K8s
Au lieu de se connecter à un serveur spécifique, de télécharger la source, de construire une image, etc., nous allons plutôt déployer notre conteneur dans le nuage. Le nuage se chargera de faire fonctionner le conteneur pour nous !
Nous allons utiliser un cluster Kubernetes que je vous ai fourni pour déployer votre conteneur.
Je fournirai à chacun d'entre vous un fichier de configuration qui vous donnera un accès exclusif à mon cluster kubernetes.
apiVersion: v1
clusters:
- name: "hetic-devops"
cluster:
certificate-authority-data: LS0tLS1CRUdJTiB...
server: https://96ff...
contexts:
- name: kevin-nguni-fr
context:
cluster: "hetic-devops"
user: s-...
namespace: s-...
current-context: s-...
kind: Config
preferences: {}
users:
- name: s-...
user:
token: eyJhbGciOiJS....
Retournez à votre DevContainer. J'ai déjà installé l'application kubectl
dans votre DevContainer qui nous permet de communiquer avec un cluster Kubernetes.
Copiez le fichier kubeconfig-....yaml
dans votre devcontainer, sous le dossier k8s
(créez ce dossier s'il n'existe pas encore).
Dans le terminal de votre DevContainer, naviguer dans le dossier k8s
:
cd k8s
Commencez par créer une variable d'environnement qui pointe vers votre fichier kubeconfig :
export KUBECONFIG=./kubeconfig.yaml
Nous pouvons maintenant interagir avec le cluster Kubernetes, en listant tous les pods (ou conteneurs) qui sont en cours d'exécution :
kubectl get pods
Deployment
Nous allons maintenant indiquer à k8s que nous voulons déployer notre API sur le cluster. Nous allons écrire un fichier de configuration de type "deployment".
# k8s/deployment.k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: devopsapi
labels:
app: devopsapi
spec:
replicas: 2
selector:
matchLabels:
app: devopsapi
template:
metadata:
labels:
app: devopsapi
spec:
containers:
- name: devopsapi
image: drkevinglass/devopsapi:1.0.0
command: ["npm", "run", "start-api"]
Remplacez drkevinglass/devopsapi:1.0.0
par le nom de votre image envoyé à Docker Hub.
Lancez votre image dans le cluster avec :
kubectl apply -f deployment.k8s.yaml
Si tout se passe bien, l'image sera récupéré de Docker Hub, et lancé automatiquement sur mon cluster !
Vérifions :
kubectl get pods
# Vous devez voir 2 pods
kubectl get deployments
# Vous devez vois 1 deployment
kubectl logs [ID DU POD]
# Vous devez voir les logs de votre API
A chaque fois qu'on veut modifier notre deploiement, par exemple, le nombre de copies, ou mettre à jour la version de notre API, on modifie le fichier deployment.k8s.yaml
, et on éxecute kubectl apply ...
Service
Pour l'instant, notre déploiement est en cours, mais il n'est pas disponible à l'extérieur. Nous devons établir ce lien. Il fonctionne comme suit :
Load-Balancer → Ingress → Service → Deployment → Pods
Nous avons déjà configuré le "Deployment" qui a généré automatiquement plusieurs Pods.
Le LoadBalancer est une ressource payante de mon fournisseur de services que j'ai déjà configurée pour vous. Je vous donnerai l'adresse IP précise en classe.
Il ne reste plus qu'à connecter le Ingress et le Service.
Créez un nouveau fichier pour le service :
# k8s/service.k8s.yaml
apiVersion: v1
kind: Service
metadata:
name: devopsapi-svc
labels:
app: devopsapi
spec:
ports:
- port: 5055
targetPort: 5055
protocol: TCP
selector:
app: devopsapi
Ensuite, déployez le service vers le cluster :
kubectl apply -f service.k8s.yaml
Ingress
Nous voulons maintenant indiquer au cluster comment rediriger les requêtes entrantes. Pour ce faire, nous utilisons un contrôleur Ingress.
Comme nous partageons tous le même cluster (et donc la même adresse IP), nous allons distinguer nos déploiements par un sous-chemin.
Par exemple, une requête à
http://cluster.mt.glassworks.tech/kevin-nguni-fr
devrait être dirigée vers mon API.
Par contre, une requête vers
http://cluster.mt.glassworks.tech/t_joubert-hetic-eu
devrait être redirigée vers l'API de cet étudiant.
Crée un nouveau fichier :
# k8s/ingress.k8s.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /MON_CHEMIN_UNIQUE(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: devopsapi-svc
port:
number: 5055
Remplacez MON_CHEMIN_UNIQUE
par un chemin qui vous identifie, par exemple, votre adresse e-mail (ayant remplacé le @
et les .
par des tirés -
)
Déployez cette configuration avec :
kubectl apply -f ingress.k8s.yaml
Tester
Vous devriez pouvoir envoyer une requête au serveur maintenant !
# Remplacez l'adress IP et par l'adresse fourni du cluster
# Remplacez MON_CHEMIN_UNIQUE par le chemin indique dans le ingress
curl http://cluster.mt.glassworks.tech/MON_CHEMIN_UNIQUE/info
# Resultat :
#{"title":"DevOps Code Samples API","host":"devopsapi-7774dbf9fb-sb5js","platform":"linux","type":"Linux"}%
Félicitations ! Vous avez réussi à mettre en place votre environnement de production !
Variables d'environnement (chapitre facultatif)
Comment préciser les variables d'environnement pour nos deploiements ? Crée un config-map :
# k8s/api-cfg.k8s.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: devopsapi-cfg
data:
PORT: "5001"
Ensuite, l'appliquer :
kubectl apply -f ./api-cfg.k8s.yaml
Il faut ensuite préciser au déploiement d'utiliser le config-map et appliquer les variables d'environnement :
# k8s/deployment.k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: devopsapi
labels:
app: devopsapi
spec:
replicas: 2
selector:
matchLabels:
app: devopsapi
template:
metadata:
labels:
app: devopsapi
spec:
containers:
- name: devopsapi
image: drkevinglass/devopsapi:1.0.0
command: ["npm", "run", "start-api"]
envFrom:
- configMapRef:
name: devopsapi-cfg
Appliquer la modification :
kubectl apply -f deployment.k8s.yaml
Attention, on ne stocke jamais les secrets dans un config-map, car les valeurs sont stockées en texte claire !
Secrets (chapitre facultatif)
Comment les secrets sont-ils stockés dans Kubernetes, si ce n'est via les ConfigMaps ?
Nous devons ponctuellement créer des secrets à l'aide d'une commande unique qui n'est pas stockée dans un fichier ou dans GIT. Nous essayons également de ne jamais mettre un secret directement sur la ligne de commande, car n'importe qui pourrait récupérer notre historique.
Tout d'abord, nous créons un fichier .env
qui stocke nos secrets localement, et qui est ignoré par GIT (il doit se trouver dans le fichier .gitignore
)
export DB_DATABASE=
export DB_PASSWORD=
...
Nous chargeons ensuite ces variables dans le shell actuel:
source .env
Testez que vos variables sont chargées :
echo $DB_DATABASE
Vous devriez voir votre valeur affichée dans le shell.
Ensuite, on va créer les secrets sur le cluster :
kubectl delete secret devopsapi-secrets
kubectl create secret generic devopsapi-secrets \
--from-literal=DB_DATABASE="$DB_DATABASE" \
--from-literal=DB_PASSWORD="$DB_PASSWORD"
Il faut ensuite préciser au déploiement d'utiliser les secrets :
# k8s/deployment.k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: devopsapi
labels:
app: devopsapi
spec:
replicas: 2
selector:
matchLabels:
app: devopsapi
template:
metadata:
labels:
app: devopsapi
spec:
containers:
- name: devopsapi
image: drkevinglass/devopsapi:1.0.0
command: ["npm", "run", "start-api"]
envFrom:
- configMapRef:
name: devopsapi-cfg
- secretRef:
name: devopsapi-secrets
Appliquer la modification :
kubectl apply -f deployment.k8s.yaml
Relancer vos services
Après avoir modifié les variables d'environnement et/ou secrets, pour les appliquer aux deploiements existants, il suffit de juste forcer le redemarrage des pods, en scalant à 0 et puis en les recréant :
kubectl scale --replicas=0 deployment/devopsapi
kubectl scale --replicas=2 deployment/devopsapi
Dernière mise à jour