Découvrir Kubernetes
Objectifs
- Découvrir Kubernetes et l’orchestration de conteneurs
Note pour la mise en place
Pour que minikube fonctionne correctement pour ce TD, il faut être une seule personne par compte utilisateur sur les Xeon à l’INSA-CVL.
Si vous partagez un Xeon avec d’autres élévèes, alors vous devez créer des comptes utilisateurs distincts pour chacun d’entre vous, les ajouter dans le groupe libvirt et vous y connecter avant de commencer ce TD :
root@xeon $ useradd --create-home --user-group --groups wheel,libvirt userX
root@xeon $ passwd userX
user@localhost $ ssh userX@172.x.y.z
Obtenir un cluster Kubernetes avec minikube
Nous allons utiliser minikube pour obtenir un cluster en local pour réaliser ce TD.
Récupérer le binaire minikube
:
# "Ces commandes ne sont nécessaires qu'une seule fois par machine physique / Xeon"
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install -o root -g root -m 0755 minikube-linux-amd64 /usr/local/bin/minikube
Configurer l’utilisation du driver kvm2
avec libvirt
et l’usage de cri-o
:
$ minikube config set driver kvm2
$ minikube config set container-runtime cri-o
Récupérer l’image minikube mise à disposition en TD :
$ cp /mnt/nfs/DATASTORE/A_COURS/RAVIER/minikube-v1.34.0-amd64.iso* ./
$ sha256sum --check minikube-v1.34.0-amd64.iso.sha256sum
Démarer la machine virtuelle avec l’image mise à jour, en précisant votre nom-prénom comme nom de profil :
$ minikube start --profile nomprenom --iso-url=file://$(pwd)/minikube-v1.34.0-amd64.iso
Commandes à utiliser uniquement si vous rencontrez une erreur parce que le réseau "default" n'existe pas.
Utilisez les commandes suivantes pour re-créer le réseau “default” :
# "Ces commandes ne sont nécessaires qu'une seule fois par machine physique / Xeon"
$ curl -o default.xml https://raw.githubusercontent.com/libvirt/libvirt/master/src/network/default.xml
$ sed -i 's/virbr0/virbr99/' default.xml
$ virsh net-define default.xml
$ virsh net-start default
$ virsh net-autostart default
Définir ensuite votre profil comme celui par défaut pour éviter d’avoir à le préciser pour chaque commande :
$ minikube profile nomprenom
Installer kubectl
:
# "Ces commandes ne sont nécessaires qu'une seule fois par machine physique / Xeon"
$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
$ echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
$ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Activer la completion (avec <TAB>) des commandes kubectl
:
$ echo 'source <(kubectl completion bash)' >>~/.bashrc
$ source ~/.bashrc
Vérifier que le noeud minikube est bien fonctionel :
$ kubectl get nodes
Intéragir avec le cluster
Pour intéragir avec l’API exposée par le cluster Kubernetes, nous allons utiliser kubectl
.
Le commandes kubectl
suivent le format suivant :
$ kubectl <action> <ressource>/(<nom-de-la-ressource)
# ou
$ kubectl <action> <ressource> (<nom-de-la-ressource)
Par exemple pour obtenir la liste des noeuds disponibles dans notre cluster Kubernetes :
$ kubectl get nodes
Pour obtenir plus d’informations, vous pouvez rajouter l’option -o wide
:
$ kubectl get nodes -o wide
Pour vérifier la version de kubectl et du cluster :
$ kubectl version --output=yaml
Vous pouvez vous connecter au noeud de notre cluster (notre machine virtuelle) :
$ minikube ssh
Et constater que nous avons les services minimum nécessaires au fonctionnement de Kubernetes installés et lancés :
$ systemctl -t service | grep -E 'crio|kubelet'
Listez les conteneurs qui forment le control plane de Kubernetes :
$ sudo crictl ps
Déployer une application
Pour déployer une application sur un cluster Kubernetes, nous utilisons un déploiement (deployment).
Le déploiement indique à Kubernetes comment créer et mettre à jour des instances d’une application. Nous ne gérons pas les coteneurs directement mais c’est Kubernetes qui se charge de garantir que ce qui tourne sur le cluster correspond à ce que nous lui demandons.
Pour créer un déploiement avec l’interface de ligne de commande kubectl
, nous devons préciser un nom et l’image de conteneur qui sera utilisée :
$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
Kubernetes va faire les choses suivantes :
- Ecrire dans la base de donnée etcd les informations pour faire tourner notre deploiement
- Le Scheduler va chercher un noeud disponible pour faire tourner notre deploiement et ses pods (nous n’en avons ici qu’un seul)
- Il va alors écrire le ou les noeuds choisis dans la configuration du/des noeuds dans etcd pour programmer le lancement des pods sur ces noeuds
- Les kubelets sur les noeuds vont réaliser qu’il a des nouveaux pods à lancer qui n’existent pas sur le noeud actuellement
Pour lister les déploiements :
$ kubectl get deployments
Pods
Lorsque que nous créons un déploiement, Kubernetes crée un Pod pour regrouper les conteneurs qui forment notre application. Un pod est une abstraction Kubernetes qui représente un groupe de conteneurs qui partagent certains namespaces :
- le stockage partagé (volumes)
- le namespace réseau, avec une adresse IP unique sur tout le cluster
Pour lister les pods déployés :
$ kubectl get pods
Pour obtenir plus d’informations sur les pods et les conteneurs en cours d’exécution :
$ kubectl describe pods
Logs
Pour obtenir les logs des conteneurs qui constituent notre pod, nous pouvons utiliser :
$ kubectl logs kubernetes-bootcamp-f95c5b745-7td7b
Exécuter des commandes dans les conteneurs
Nous pouvons aussi exécuter directement des commandes à l’intérieur des conteneurs :
$ kubectl exec kubernetes-bootcamp-f95c5b745-7td7b -- env
Ou obtenir un shell :
$ kubectl exec -ti kubernetes-bootcamp-f95c5b745-7td7b -- bash
Exposer une application publiquement
Les conteneurs lancés dans un cluster Kubernetes ne sont pas accessibles par défaut depuis l’extérieur. Seules les autres applications du cluster peuvent communiquer avec eux.
De plus, les pods sont ephemères et peuvent être déplacés entre les noeuds du cluster en cas de crash, mise à jour ou redémarrage. Pour y accéder depuis l’extérieur du cluster, nous allons utiliser le concept de Service. Pour lister les Services sur le cluster :
$ kubectl get services
Nous allons ensuite exposer notre application publiquement à l’aide d’un service de type “NodePort”, qui va mettre à disposition notre application sur un port d’un noeud du cluster :
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
Nous pouvons obtenir le port sur lequel notre application a été rendu disponible :
$ kubectl get services
$ kubectl describe services/kubernetes-bootcamp
...
NodePort: <unset> 30542/TCP
...
Et ensuite contacter notre application :
# Obtenir l'IP de la machine minikube
$ minikube ip
192.168.39.80
$ curl http://192.168.39.80:30542
Passage à l’échelle
Si notre application gère beaucoup de requettes, il peut devenir nécessaire d’en déployer plusieurs copies pour répartir la charge sur les noeuds du cluster. Pour cela, nous allons utiliser les ReplicaSet. Lorsque nous avons créé notre déploiement, un ReplicaSet a aussi été automatiquement créé :
$ kubectl get replicasets
Par défaut, un seul réplicat est demandé et un seul est en cours d’exécution.
Nous allons désormais en demander 4 :
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
Constater que le changement a été effectué avec :
$ kubectl get deployments
et constater la création des nouveaux pods avec :
$ kubectl get pods -o wide
Noter que chaque pod a sa propre adresse IP.
Ce changement a aussi été enregistré dans le log des évènements :
$ kubectl describe deployments/kubernetes-bootcamp
Lorsque nous contactons notre application via notre service, nous sommes désormais redirigé vers différentes instances de notre application :
# Répétez la requête jusqu'à obtenir une reponse d'un pod différent
$ curl http://192.168.39.80:30542
Nous pouvons ensuite réduire le nombre de conteneurs déployés :
$ kubectl scale deployments/kubernetes-bootcamp --replicas=2
$ kubectl get deployments
$ kubectl get pods
Déploiment progressif d’une mise à jour
Pour pouvoir déployer une mise à jour de notre application sans créer d’interruption de service, nous allons réaliser une mise à jour progressive (rolling update).
Nous allons indiquer à Kubernetes que nous voulons désormais utiliser une nouvelle version de notre application et celui-ci va se charger de déployer de nouveaux pods avec cette nouvelles version pour progressivement remplacer les anciens pods.
Listons d’abord les pods en cours d’exécution :
$ kubectl get pods
Indiquons que nous voulons désormais utiliser la version 2 de notre application :
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
Constater le remplacement progressif des pods :
$ kubectl get pods
Constater aussi que notre application reste toujours disponible au cours de la mise à jour :
$ curl http://192.168.39.80:31436
Les réponses arrivent progressivement depuis les nouveaux pods.
Nous pouvons aussi valider la progression du déploiment avec :
$ kubectl rollout status deployments/kubernetes-bootcamp
Essayons désormais de réaliser une autre mise à jour avec la version 10 de notre application :
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10
Observer la (non) progression :
$ kubectl get pods
Pour obtenir plus d’informations sur l’erreur :
$ kubectl describe pods
Et pour annuler le déploiement de la mise à jour :
$ kubectl rollout undo deployments/kubernetes-bootcamp
Références
- Ce TD est fortement inspiré du tutoriel Learn Kubernetes Basics :
- Ensemble des tutoriels de Kubernetes :
- Tutoriels alternatifs :
- Sur GCP : Suivre le tutoriel intégré à la plateforme (Quickstart / Démarrage rapide)
- Sur Azure : Tutorial - Deploy an Azure Kubernetes Service (AKS) cluster (Azure Kubernetes Service (AKS))
- Sur AWS : Getting started with Amazon EKS
- Apprendre Kubernetes à l’aide d’exemples : Kubernetes By Example
- Site de minikube
- Install and Set Up kubectl on Linux
- Kubernetes The Hard Way, Kelsey Hightower
- Découvrez le fonctionnement d’
etcd
: http://play.etcd.io/play