Avant-propos
Qu’est-ce qu’un container?
Au Niveau du système d’exploitation, un container va regrouper un groupe de ressources mis à disposition d’un ensemble de process.
-
un système de fichiers,
-
des allocations de ressources système (CPU, mémoire , capacité d’entrée/sortie)
-
un espace d’isolation de process
-
une ou plusieurs interfaces réseau
-
etc …
Pourquoi utiliser des containers
-
Pour illustrer ce problème, imaginez les programmes ARTHUR et BERTRAND dépendant de la librairie libLili en version v1. Dans un premier temps, les choses devraient bien se passer. En revanche, dans une version du programme de BERTRAND, la version de la dépendance libLili est passée de version v1 à la version v2. Problème : ARTHUR est incompatible avec libLili en version v2.
-
Les containers proposent de répondre à ce type de problème de manière très élégante en faisant de sorte que toutes les dépendantes d’un programme soient embarquées dans l’image contenant l’image à lancer.Ainsi chaque container se retrouve isolé avec ses propres dépendances sans risquer d’interférer avec les autres containers. La réalisation du même découpage à l’aide de machines virtuelles réclamait beaucoup plus de ressources.
Problèmes introduits avec les containers
-
comment mettre à jour les containers
-
comment faire la surveillance des containers,
-
comment absorber les pics de charges,
-
comment mettre en oeuvre de la persistance des données,
-
comment réaliser des mises à jour sans interruption de service,
-
comment étendre la capacité de traitement du cluster
-
comment exposer les applications à des utilisateurs.
A quoi va servir Kubernetes ?
La gestion des containers à Docker (ou un équivalent)
-
Gestion de la montée en charge applicative (avec les pods)
-
Gestion de la montée en charge système ( avec les noeuds ou nodes)
-
Surveillance de l’état des containers.
-
Gestion de cycles de vie des containers.
Les deux notions évoquées (pods et nodes) sont très importantes dans Kubernetes :
-
Les pods vont représenter la plus petite unité de travail dans Kubernetes.
-
Les noeuds (ou nodes) vont représenter les machines faisant partie du cluster Kubernetes.
Un pod est généralement constitué d’un ou plusieurs containers ( généralement un seul) :
-
La surveillance de la bonne santé du/des containers.
-
La configuration et/ou les variables d’environnement.
-
L’emplacement des volumes persistants.
En cas de défaillance détectée sur un container, Kubernetes se charge automatiquement d’en démarrer un nouveau et d’arrêter l’ancien.
Même chose lorsqu’une charge importante est détectée : Kubernetes procédera à la création de nouveaux pods.
Chapitre 1
Introduction
Cibles et Objectifs de l’ouvrage : Connaissance aussi bien en administration systèmes qu’en développement.
-
Notions sur l’administration système Linux (Installation de paquets, téléchargement de binaires, utilisation de sudo)
-
Connaissance minimale d’un fournisseur d’informatique dans les clouds (Azure, Google , AWS, OVH ou IONOS)
-
Principe de fonctionnement des couches réseaux/HTTP (DNS,répartiteur de charge, proxy inverse)
-
Notion de l’utilisation de Git (Cloner un dépôt de code source)
Ressources documentaires
-
Déploiement d’application WEB.
-
Déploiement de base de données.
-
Mise en place de surveillance avec Prometheus.
Code source de ces exemples : https://github.com/EditionsENI/kubernetes
Ressources documentaires du projet des dernières évolutions : https://kubernetes.io/fr/docs/home
Racine de dépôts GitHub du projet : https://github.com/kubernetes
Récupération des fichiers d’exemples
-
Dépôts GitHup du livre : https://githup.com/EditionsENI/kubernetes
-
Récupération une copie des fichiers d’exemples en local : https://github.com/EditionsENI/kubernetes.git
Présentation générale
-
Exemples élaborés sur une machine Linux Ubuntu 20.04 LTS
Utilisation de Kubernetes
-
Tableau de bord et ligne de commande : la notion de pod , de déploiement, de service ainsi qu le cycle de vie d’un pod.
-
Persistance de données : MySQL/MariaDB.
-
Gestion des briques internes de Kubernetes, Helm – Gestionnaire de packages et Contextes et outils tiers Kubernetes permettent de découvrir les briques internes de Kubernetes, le gestionnaire de paquets Helm et enfin quelques outils d’administration.
Extention du Cluster Kubernetes et notions avancées
-
Polices réseau et Maillage de services avec Istio , sécurisation des accès internes du cluster ainsi qu’au chiffrement des communications entre services.
-
Montées en charge automatique, montée en charge d’application , surveillance à l’aide de Prometheus et Centralisation des journaux d’activité d’application et d’activités.
-
Restriction et délégation d’accès avec le mécanisme d’authentification et d’autorisation des administrateurs Kubernetes ainsi que la mise en place de restrictions sur la consommation de ressources.
Déploiement et intégration continue
Application avec Helm :
-
Comment créer une image de container.
-
Comment mettre à jour une image automatiquement.
-
Comment déployer une application à l’aide de Helm
Chapitre 2
Installation de l’environnement
Kubernetes
Mise en place de la commande kuberctl
Prérequis d’Installation Docker
### INSTALL DOCKER (/shareProd/1and1/local/appli/Kubernetes/scripts/1-PrerequisDocker.ksh)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update ; clear
sudo apt-get install -y docker-ce
sudo wget https://raw.githubusercontent.com/lerndevops/labs/master/kubernetes/0-install/daemon.json -P /etc/docker
sudo systemctl restart docker.service
sudo service docker status
######################################################################
Pour installer Docker sur Ubuntu 20.04, vous pouvez suivre les étapes ci-dessous :
### Étape 1 : Mettre à jour les paquets existants
Ouvrez un terminal et exécutez la commande suivante pour mettre à jour l’index des paquets :
bash
sudo apt update
sudo apt upgrade
### Étape 2 : Installer les dépendances
Installez les paquets nécessaires pour permettre à apt de gérer les paquets via HTTPS :
bash
sudo apt install apt-transport-https ca-certificates curl software-properties-common
### Étape 3 : Ajouter la clé GPG officielle de Docker
Ajoutez la clé GPG officielle de Docker à votre liste de clés :
bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
### Étape 4 : Ajouter le dépôt de Docker
Ajoutez le dépôt Docker à votre liste de dépôts APT :
bash
sudo add-apt-repository « deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable »
### Étape 5 : Mettre à jour à nouveau les paquets
Après avoir ajouté le dépôt, mettez à jour l’index des paquets :
bash
sudo apt update
### Étape 6 : Installer Docker
Installez Docker avec la commande suivante :
bash
sudo apt install docker-ce
### Étape 7 : Vérifier l’installation de Docker
Vérifiez si Docker est bien installé et fonctionne :
bash
sudo systemctl status docker
### Étape 8 : Exécuter Docker sans sudo (optionnel)
Si vous souhaitez exécuter Docker sans préfixe sudo, ajoutez votre utilisateur au groupe Docker :
bash
sudo usermod -aG docker $USER
Déconnectez-vous et reconnectez-vous pour appliquer les modifications.
### Étape 9 : Tester l’installation
Vous pouvez tester votre installation de Docker en exécutant le conteneur hello-world :
bash
docker run hello-world
Cela devrait afficher un message confirmant que Docker fonctionne correctement.
Voilà, Docker est maintenant installé et prêt à être utilisé sur votre système Ubuntu 20.04 !
####################################################################
-
L’emplacement de récupération des instructions d’installation : https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl
Installation sous Debian/Ubuntu
( /shareProd/1and1/local/appli/Kubernetes/scripts/2-Installation_du_package_kubectl.ksh)
-
Ajout des Clés
$ wget -O – https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –
-
Déclaration des sources kubernetes
$ echo « deb https://pat.kubernetes.io/ kubernetes-xenial main » | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
-
Mise à jour des sources de package
-
Installation du package kubectl
-
-
I cleared kubectl from
/usr/local/binand also from
/home/$USER/.local/binAnd run the commands below:
# curl -LO "https://dl.k8s.io/release/v1.24.7/bin/linux/amd64/kubectl"# curl -LO "https://dl.k8s.io/v1.24.7/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
# sudo install -o root -g root -m 0755 kubectl /home/$USER/.local/bin/kubectl
-
Vérification de l’installation
$ kubctl version –client
-
Autocomplétion sur kubectl
– Ajouter cette instruction suivante dans le fichier profile : source <(kubectl completion bash)
-
Mise en place d’un alias ( ~/.bashrc)
$ alias k=kubectl
$ complete -F __start_kubectl k
Pourquoi faire appel à Minikube ?
Minikube est un projet qui a pour but de fournir un environnement bac à sable à un utlisateur pour expérimenter le fonctionnement de kubernetes.
Téléchargement et installation de Minikube
(/shareProd/1and1/local/appli/Kubernetes/scripts/3-telechargement-installation-Minikube.ksh)
-
Téléchargement de Minikube
$ wget https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
-
Déplacement du fichier Minikube dans /usr/local/bin
$ sudo mv minikube-linux-amd64 /usr/local/bin/minikube
$sudo chmod +x /usr/local/bin/minikube
-
Vérification de l’installation de Minikube
$ minikube version
-
Mise en place de l’autocomplétion
– Ajouter cette instruction suivante dans le fichier profile : source <(minikube completion $(basename $SHELL))
Installation du cluster Kubernetes avec Minikube
Options de lancement
-
L’installation du cluster Kubernetes par MInikube se fait soit à l’aide d’un container Docker ou d’une machine virtuelle (pilotée par un hyperviseur)
Installation de Docker :
Fichier : /shareProd/1and1/local/appli/Kubernetres/scripts/./4-Installation-Docker.ksh
-
Installation de Docker Community Edition sur Ubuntu
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
$ sudo add-apt-repository « deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable »
$ sudo apt update
$ sudo apt-get install docker.ce docker-ce-cli containerd.io
-
Configuration des accès à Docker
$ sudo usermod -aG docker <USER>
-
Vérification de l’installation de Docker
$ docker run hello -world
-
Extrait du résultat :
u70779858@Kubernetes-SRV:
$ docker run hello-world
u70779858@Kubernetes-SRV:~$ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world c1ec31eb5944: Pull complete Digest: sha256:1408fec50309afee38f3535383f5b09419e6dc0925bc69891e79d84cc4cdcec6 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly.
-
$ minikube start –cpus 2 –memory 2048 –kubernetes-version v1.24.7 –vm-driver docker –container-runtime containerd
-
$ minikube start –cpus 2 –memory 2048 –kubernetes-version v1.24.7 –vm-driver docker –container-runtime containerd
X Fermeture en raison de K8S_NEW_UNSUPPORTED : La version Kubernetes 1.33.1 n'est pas prise en charge par cette version de minikube
u70779858@Kubernetes-SRV:~$ k version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.7", GitCommit:"e6f35974b08862a23e7f4aad8e5d7f7f2de26c15", GitTreeSta te:"clean", BuildDate:"2022-10-12T10:57:14Z", GoVersion:"go1.18.7", Compiler:"gc", Platform:"linux/amd64"}
Kustomize Version: v4.5.4
The connection to the server localhost:8080 was refused - did you specify the right host or port?
u70779858@Kubernetes-SRV:~$ minikube start --cpus 2 --memory 2048 --kubernetes-version v1.33.1 --vm-driver docker --container-runtime con tainerd
* minikube v1.33.1 sur Ubuntu 20.04
! La version de Kubernetes spécifiée 1.33.1 est plus récente que la dernière version prise en charge : v1.30.0. Utilisez `minikube config defaults kubernetes-version` pour plus de détails.
! La version Kubernetes spécifiée 1.33.1 est introuvable dans la liste des versions de Kubernetes
* Recherche sur Internet de la version de Kubernetes...
! Version Kubernetes introuvable dans la liste des versions de GitHub. Vous pouvez forcer une version de Kubernetes via l'indicateur --force
X Fermeture en raison de K8S_NEW_UNSUPPORTED : La version Kubernetes 1.33.1 n'est pas prise en charge par cette version de minikube
u70779858@Kubernetes-SRV:~$ minikube start --cpus 2 --memory 2048 --kubernetes-version v1.24.7 --vm-driver docker --container-runtime containerd
* minikube v1.33.1 sur Ubuntu 20.04
* Utilisation du pilote docker basé sur la configuration de l'utilisateur
* Utilisation du pilote Docker avec le privilège root
* Démarrage du nœud "minikube" primary control-plane dans le cluster "minikube"
* Extraction de l'image de base v0.0.44...
* Téléchargement du préchargement de Kubernetes v1.24.7...
> gcr.io/k8s-minikube/kicbase...: 481.58 MiB / 481.58 MiB 100.00% 13.04 M
> preloaded-images-k8s-v18-v1...: 437.52 MiB / 437.52 MiB 100.00% 7.05 Mi
* Création de docker container (CPU=2, Memory=2048Mo) ...
* Préparation de Kubernetes v1.24.7 sur containerd 1.6.31...
X Impossible de charger les images mises en cache : loading cached images: stat /home/u70779858/.minikube/cache/images/amd64/registry.k8s.io/kube-controller-manager_v1.24.7: no such file or directory
- Génération des certificats et des clés
- Démarrage du plan de contrôle ...
- Configuration des règles RBAC ...
* Configuration de CNI (Container Networking Interface)...
* Vérification des composants Kubernetes...
- Utilisation de l'image gcr.io/k8s-minikube/storage-provisioner:v5
* Modules activés: storage-provisioner, default-storageclass
* Terminé ! kubectl est maintenant configuré pour utiliser "minikube" cluster et espace de noms "default" par défaut.
Installation dans l’environnement Kubernetes
$ kubectl get namespace
$ kubectl get namespace NAME STATUS AGE default Active 24h kube-node-lease Active 24h kube-public Active 24h kube-system Active 24h
Arrêt/démarrage de la machine Minikube
$ minikube stop
u70779858@Kubernetes-SRV:~$ minikube stop * Nœud d'arrêt "minikube" ... * Mise hors tension du profil "minikube" via SSH… * 1 nœud arrêté.
$ minikube start
u70779858@Kubernetes-SRV:~$ minikube start * minikube v1.33.1 sur Ubuntu 20.04 * Kubernetes 1.30.0 est désormais disponible. Si vous souhaitez effectuer une mise à niveau, spécifiez : --kubernetes -version=v1.30.0 * Utilisation du pilote docker basé sur le profil existant * Démarrage du nœud "minikube" primary control-plane dans le cluster "minikube" * Extraction de l'image de base v0.0.44... * Redémarrage du docker container existant pour "minikube" ... * Préparation de Kubernetes v1.24.7 sur containerd 1.6.31... X Impossible de charger les images mises en cache : loading cached images: stat /home/u70779858/.minikube/cache/images/amd64/registry.k8s.io/etcd_3.5.3-0: no such file or directory * Vérification des composants Kubernetes... - Utilisation de l'image gcr.io/k8s-minikube/storage-provisioner:v5 * Modules activés: default-storageclass, storage-provisioner * Terminé ! kubectl est maintenant configuré pour utiliser "minikube" cluster et espace de noms "default" par défaut.
Suppression de la machine Minikube
$ minikube delete
Quelques notions sur le format YAML
-
La commande kubectl permet d’interagir avec Kubernete afin de créer certains objets (dévelopement, adresse de services, proxy inverse, etc
Un proxy inverse Kubectl vous permet de créer un tunnel sécurisé vers un service Kubernetes en cours d'exécution, puis de vous connecter à ce service à partir de votre machine locale. Cela peut être utile pour déboguer ou tester des applications déployées dans un cluster Kubernetes
-
Yam permet permet d’écrire des structures de données sous forme de listes ou de dictionnaires ( lisibilité ou compacité)
Chapitre 3
Tableau de bord et
Ligne de commande
-
Le tableau de bord (dashboard) Kubernettes
-
La commande kubectl
-
Le moteur Docker et Minikube
-
La consultation de quelques objets de base (pods et nodes)
-
Un cluster Kubernettes fonctionnel
-
Un contexte kubectl cohérent
Pourquoi utiliser Kubernetes
-
Possibilité de réaliser des opérations auparavant compliquées de façon plus rapide et simple /
– Démarrer des éléments de tests à la demande
– s’affranchir des problèmes de dépendances de librairies
– uniformiser les livrables de tous les environnements
-
Nouveaux problèmes rencontrés pour ce nouvel outil :
– Persistance des données.
– Surveillance des applications dans les containers.
– Mise à jour automatique des applications
– Scalabilité du moteur Docker
– Scalabilité de la charge applicative
– Publication des environnements sur l’extérieur
Le tableau de bord de Kubernetes (Dashboard)
-
Déploiement du dashboard sur Minikube
$ minikube addons enables dashboard
$ minikube addons enables metrics-server
$minikube dashboard
-
Création d’un déploiement
App name :mailhog (Nom du déploiement)
Container image : mailhog/mailhog (Nom de l’image)
Consultation du gestionnaire de réplicats
Nom du réplicat
L’espace des noms, les labels et annotaions
La date de création
L’image utilisée
La liste des pods
La liste des pods associés
Les services associés
Le service de mise à l’échelle
Les événements associés au RéplicaSetConsultation
Consultation de l’état d’un pod
Journal d’activité du container : View logs
Scalabilié : Option Scale (à l’échelle)
Mise à jour de l’application
Edition de la définition au format YAML de l’application MailHog
Pour résumer
- Création d’un ReplicaSet
- Création d’un Pod associé au ReplicaSet
- Démarrage du container
Une mise à jour du déploiement se traduira par la création d’un nouveau ReplicaSet qui disparaîtra une fois la mise à jour terminée.
$ minikube start
u70779858@Ubuntu20Kubernetes:~$ minikube start * minikube v1.32.0 sur Ubuntu 20.04 * minikube 1.33.1 est disponible ! Téléchargez-le ici : https://github.com/kubernetes/minikube/releases/tag/v1.33.1 * Pour désactiver cette notification, exécutez : 'minikube config set WantUpdateNotification false' * Choix automatique du pilote docker * Utilisation du pilote Docker avec le privilège root * Démarrage du noeud de plan de contrôle minikube dans le cluster minikube * Extraction de l'image de base... * Téléchargement du préchargement de Kubernetes v1.28.3... > preloaded-images-k8s-v18-v1...: 403.35 MiB / 403.35 MiB 100.00% 40.28 M > gcr.io/k8s-minikube/kicbase...: 453.90 MiB / 453.90 MiB 100.00% 19.42 M * Création de docker container (CPU=2, Memory=2200Mo) ... X Docker est presque à court d'espace disque, ce qui peut entraîner l'échec des déploiements ! (86 % de la capacité). Vous pouvez passer '--force' pour ignorer cette vérification. * Suggestion : Essayez une ou plusieurs des solutions suivantes pour libérer de l'espace sur l'appareil : 1. Exécutez "docker system prune" pour supprimer les données Docker inutilisées (éventuellement avec "-a") 2. Augmentez le stockage alloué à Docker for Desktop en cliquant sur : Icône Docker > Settings > Ressources > Disk Image Size 3. Exécutez "minikube ssh -- docker system prune" si vous utilisez l'environnement d'exécution du conteneur Docker * Problème connexe: https://github.com/kubernetes/minikube/issues/9024 * Préparation de Kubernetes v1.28.3 sur Docker 24.0.7... - Génération des certificats et des clés - Démarrage du plan de contrôle ... - Configuration des règles RBAC ... * Configuration de bridge CNI (Container Networking Interface)... - Utilisation de l'image gcr.io/k8s-minikube/storage-provisioner:v5 * Vérification des composants Kubernetes... * Modules activés: default-storageclass, storage-provisioner * Terminé ! kubectl est maintenant configuré pour utiliser "minikube" cluster et espace de noms "default" par défaut.
$ minikube addons enable dashboard
u70779858@Ubuntu20Kubernetes:~$ minikube addons enable dashboard * dashboard est un addon maintenu par Kubernetes. Pour toute question, contactez minikube sur GitHub. Vous pouvez consulter la liste des mainteneurs de minikube sur : https://github.com/kubernetes/minikube/blob/master/OWNERS - Utilisation de l'image docker.io/kubernetesui/dashboard:v2.7.0 - Utilisation de l'image docker.io/kubernetesui/metrics-scraper:v1.0.8 * Certaines fonctionnalités du tableau de bord nécessitent le module metrics-server. Pour activer toutes les fonctionnalités, veuillez exécuter : minikube addons enable metrics-server * Le module 'dashboard' est activé
Présentaion de l’outil kubectl
$ kubectl get namespace
$ kubectl get pod
$ kubectl get node
$ kubectl get node -o wide
$ minikube ssh
$ sudo ctr namespace ls
docker@minikube:~$ sudo ctr namespace ls NAME LABELS k8s.io
$ sudo ctr -n k8s.io container ls
docker@minikube:~$ sudo ctr -n k8s.io container ls CONTAINER IMAGE RUNTIME 130812f821ffb7ddba52ea8e451731b36d6a2f82baccf5e6aa470478e306baa3 k8s.gcr.io/pause:3.7 io.containerd.runc.v2 17703389b0c9bed338c5cb7bd4af68b871477d854b6ccbba212209beb5379a3b k8s.gcr.io/pause:3.7 io.containerd.runc.v2 2a6b86fe292dbc5c29f83b9deb7035b4dd942fe0515b43ab922ed832e75a4e52 k8s.gcr.io/pause:3.7 io.containerd.runc.v2
$ sudo crictl ps –label=io.kubernetes.container.name=etcd
docker@minikube:~$ sudo crictl ps --label=io.kubernetes.container.name=etcd CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD a46f41882376f aebe758cef4cd 43 hours ago Running etcd 1 17703389b0c9b etcd-minikube
$ sudo crictl inspect a46f41882376f
Chapitre 4
Automatisation et publication
d’une application
Suppression d’un déploiement
$ kubectl get deployment
$ kubectl delete deployment mailhog
Création d’un dépoiement
$ kubectl -create deployement mailhog —image=mailhog/mailhog
$ kubectl get deployement
$ kubectl describe deployement mailhog
Mécanisme des réplicats
-
Consultation des réplicats
-
Parmi les informations remontées par la commande kubectl describe se trouve le ReplicaSet actuel ainsi que – en cas de mise à jour – la liste des anciens ReplicaSet.
-
Cet objet va prendre en charge la création d’un nombre données de Replicats pour une application donnée. C’est lui qui va indiquer au Cluster Kubernetes qu’il faut démarrer un pod en cas de suppression d’un pod.
-
Il vas également être associé à l’ensemble des caractéristiques d’une applicationnà un instant donné.comme par exemple :
– les caractéristiques d’une image : numéro de version, emplacement, nom
– la réservation d’une quantité de mémoire et CPU
– certaines caractéristiques du déploiement : variables d’environnement
$ kubectl get replicaset
NAME DESIRED CURRENT READY AGE mailhog-b44849b6f 1 1 1 3m21s
$ kubectl describe rs mailhog-b44849b6f
u70779858@Kubernetes-SRV:~$ k get replicaset
NAME DESIRED CURRENT READY AGE
mailhog-b44849b6f 1 1 1 3m21s
u70779858@Kubernetes-SRV:~$ k describe rs mailhog-b44849b6f
Name: mailhog-b44849b6f
Namespace: default
Selector: app=mailhog,pod-template-hash=b44849b6f
Labels: app=mailhog
pod-template-hash=b44849b6f
Annotations: deployment.kubernetes.io/desired-replicas: 1
deployment.kubernetes.io/max-replicas: 2
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/mailhog
Replicas: 1 current / 1 desired
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=mailhog
pod-template-hash=b44849b6f
Containers:
mailhog:
Image: mailhog/mailhog
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 5m4s replicaset-controller Created pod: mailhog-b44849b6f-444bt
$ watch kubectl get pods
$ kubectl logs mailhog-b44849b6f-444bt -c mailhog
u70779858@Kubernetes-SRV:~$ k logs mailhog-b44849b6f-444bt -c mailhog 2024/08/24 05:57:42 Using in-memory storage 2024/08/24 05:57:42 [SMTP] Binding to address: 0.0.0.0:1025 2024/08/24 05:57:42 Serving under http://0.0.0.0:8025/ [HTTP] Binding to address: 0.0.0.0:8025 Creating API v1 with WebPath: Creating API v2 with WebPath: [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events [APIv1] KEEPALIVE /api/v1/events
Accéder à l’application Mailhog
Le container Mailhog utilise 2 ports d’écoute :
– Le port 1025 pour le protocole SMTP
– Le port 8025 pour l’interface web de MailHog
– Le nom du pod`
– Une piste à faire suivre
Pour accéder au port 8025, dans le cas de MailHog, :
$ kubectl port-forward mailhog-b44849b6f-444bt 8025
Forwarding from 127.0.0.1:8025 -> 8025 Forwarding from [::1]:8025 -> 8025
$ kubectl port-forward deployement/mailhog 8025
Forwarding from 127.0.0.1:8025 -> 8025 Forwarding from [::1]:8025 -> 8025
Pourquoi utiliser un service
– Création d’une entrée stable dans Kubernetes
– Mise à jour de l’entrée DNS du service en cas de changement
Exposition d’un déploiement via un service
$ kubectl expose deployment/mailhog —port 1025,8025
RÉSULTAT : Service/mailhog exposed
Vérification du service mailhog
$ kubectl exec -it mailhog-b44849b6f-444bt sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. ~ $
$ kubectl exec -it deployment/mailhog — sh
Il est possible de réaliser une résolution de nom sur l’entrée DNS du service
– la commande dig
– La commande nslookup
– L’instruction gèrent hosts
Sh du pod : dig nslookup et getent hosts
Malheureusement pour l’administrateur Unix classique, une pratique courante dans la mise au point d’image de container est de réduire au maximum des outils présents (notamment pour réduire au maximum la couverture d’attaque).
$ getent hosts mailhog
RÉSULTAT : 192.168.1.99 mailhog.default.svc.cluster.local Mailhog.default.svc.cluster.local mailhog
Que faire en cas d’absence de Shell
Contexte
– connexion au pod du service
– Container ne contient aucun Shell UNIX
Dans le cas de minikube le pod storage-provisioner de l’espace
$ kubectl -n kube-system exec -it storage-provisioner sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
error: unable to upgrade connection: container not found ("storage-provisioner")
Utilisation d’un pod éphémère
– instruction de DEBUG : permet de débogguer le comportement d’un pod
$ kubectl debug -it mailhog-b44849b6f-444bt —image=alpine
u70779858@Kubernetes-SRV:~$ k debug mailhog-b44849b6f-444bt -it --image=alpine Defaulting debug container name to debugger-ctv4z. If you don't see a command prompt, try pressing enter. / #
$ kubectl exec -it deployment/mailhog — sh
u70779858@Kubernetes-SRV:~$ kubectl exec -it deployment/mailhog -- sh Defaulted container "mailhog" out of: mailhog, debugger-ctv4z (ephem), debugger-r54dl (ephem), debugger-d9699 (ephem) ~ $ getent hosts mailhog 10.111.25.214 mailhog.default.svc.cluster.local mailhog.default.svc.cluster.local mailhog ~ $
Lancement d’un pod de test
$ kubectl run -it —rm test-mailhog —image=alpine sh
$ nslookup mailhog
u70779858@Kubernetes-SRV:~$ k run -it --rm test-mailhog --image=alpine sh If you don't see a command prompt, try pressing enter. / # nslookup mailhog Server: 10.96.0.10 Address: 10.96.0.10:53 ** server can't find mailhog.cluster.local: NXDOMAIN ** server can't find mailhog.svc.cluster.local: NXDOMAIN ** server can't find mailhog.cluster.local: NXDOMAIN ** server can't find mailhog.svc.cluster.local: NXDOMAIN Name: mailhog.default.svc.cluster.local Address: 10.111.25.214 / #
A la sortie du shell associé au container, le pod est supprimé automatiquement.
/ # exit Session ended, resume using 'kubectl attach test-mailhog -c test-mailhog -i -t' command when the pod is running pod "test-mailhog" deleted u70779858@Kubernetes-SRV:~$
Résilience et scalabilité
La résilience d’un pod, dans le contexte de l’informatique et plus particulièrement de Kubernetes, fait référence à la capacité du pod à continuer de fonctionner de manière stable malgré des défaillances ou des perturbations dans l’environnement où il s’exécute.
Voici ce que cela peut impliquer :
1. *Tolérance aux pannes* : Le pod peut résister à la défaillance de certaines de ses dépendances (comme un nœud de cluster qui tombe en panne) sans interruption majeure.
2. *Redondance* : La résilience peut être améliorée par la création de plusieurs instances d’un pod (réplication), de sorte que si une instance tombe en panne, une autre instance prend le relais sans affecter la disponibilité de l’application.
3. *Auto-réparation* : Kubernetes permet de redémarrer automatiquement un pod en cas de défaillance ou de mauvais fonctionnement, ce qui améliore la résilience.
4. *Scalabilité* : La capacité du système à ajuster dynamiquement le nombre de pods en réponse à la charge de travail peut également être vue comme une forme de résilience, car elle aide à prévenir la saturation des ressources.
En somme, la résilience d’un pod est sa capacité à maintenir ses services fonctionnels même en cas de problème, grâce à des mécanismes tels que la réplication, le redémarrage automatique et l’ajustement dynamique des ressources.
Scalabilité manuelle
$ kubectl scale deployment mailhog –replicas=2
deployment.apps/mailhog scaled
Nombre de pods associés à un déploiement
$ kubectl get deployment mailhog
NAME READY UP-TO-DATE AVAILABLE AGE mailhog 2/2 2 2 75m
$ kubectl get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE mailhog-b44849b6f-444bt 1/1 Running 0 76m mailhog-b44849b6f-l485j 1/1 Running 0 94s
Arrêter temporairement une application
$ kubectl scale deployment mailhog –replicas=0
deployment.apps/mailhog scaled
$ kubectl get pods -l app=mailhog
No resources found in default namespace.
$ kubectl scale deployment mailhog –replicas=1
deployment.apps/mailhog scaled
Automatisation de déploiement par fichier YAML
Mécanisme de mise à jour
– le Dashboard de Kubernetes
– La commande kubectl avec l’option creat
Structure YAML d’un déploiement
Récupération d’une structure au format YALM
$ kubectl get deployment mailhog -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2024-08-24T05:57:38Z"
generation: 4
labels:
app: mailhog
name: mailhog
namespace: default
resourceVersion: "1209263"
uid: 3364b92d-a5ff-49f3-a256-2f53ac62ccda
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mailhog
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: mailhog
spec:
containers:
- image: mailhog/mailhog
imagePullPolicy: Always
name: mailhog
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2024-08-24T05:57:38Z"
lastUpdateTime: "2024-08-24T05:57:42Z"
message: ReplicaSet "mailhog-b44849b6f" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2024-08-24T07:23:08Z"
lastUpdateTime: "2024-08-24T07:23:08Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 4
readyReplicas: 1
replicas: 1
updatedReplicas: 1
Édition d’un déploiement
$ kubectl edit deployment mailhog
Export EDITOR=vi
Squelette d’un déploiement
Un meilleur moyen pour obtenir un squelette d’objet afin d’automatiser sa création
$ kubectl create deployment mailhog –image mailhog/mailhog –dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: mailhog
name: mailhog
spec:
replicas: 1
selector:
matchLabels:
app: mailhog
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: mailhog
spec:
containers:
- image: mailhog/mailhog
name: mailhog
resources: {}
status: {}
$ kubectl create deployment mailhog –image mailhog/mailhog –dry-run=client -o yaml > mailhog-deployment.yaml
Fichier : /home/u70779858/mailhog-deployment.yaml
Création d’un déploiement à l’aide d’un fichier
2 manières à créer un objet avec kubectl
– Avec l’option create : l’objet sera créé mais ne pourra plus être mis à jour
– Avec l’option apply : l’objet sera créé mais en revanche s’il existe déjà , kubectl se chargera tout seul à mettre à jour.
$ kubectl apply -f mailhog-deployment.yaml
Warning: resource deployments/mailhog is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. deployment.apps/mailhog configured
Suppression des éléments d’un fichier
$ kubectl delete -f mailhog-deployment.yaml
Gestion de l’dempotence et de la réentrance
Idempotence : le résultat d’une opération sera le même qu’il soit appliqué une fois ou plusieurs fois.
La réentrance : désigne le même mécanisme et sera à prendre comme un synonyme .
$ kubectl apply mailhog-deployment.yaml
|| deployment.apps/mailhog configured
Malheureusement les lancements suivant continuent de renvoyer le même message alors que la commande devrait renvoyer le message unchanged
Afin d’éviter ce comportement :
Suppression de la ligne sous champ creationTimestamp : null du champ metadata :
Et le sous champ strategy : () et ressources : () du champ spec :
Et testez les modifications réalisées :
Modifier le fichier mailhog-deployment.yaml :
apiVersion: apps/v1 kind: Deployment metadata: labels: app: mailhog name: mailhog spec: replicas: 1 selector: matchLabels: app: mailhog template: metadata: labels: app: mailhog spec: containers: - image: mailhog/mailhog name: mailhog
$ kubectl apply -f mailhog-deployment.yaml
Résultat du 1er lancement : || deployment.apps/mailhog configured Et résultat du second lancement : || deployment.apps/mailhog unchanged
Création du service
Tout comme le déploiement , il est possible d’exporter la définition de l’objet service au format YAML
$ kubectl expose deployment/mailhog —dry-run=client —port 1025, 8025 -o yaml > mailhog-service.yaml
apiVersin: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: mailhog
name: mailhog
spec:
ports:
- name: port-1
port: 1025
protocol: TCP
targetPort: 1025
- name: port-2
port: 8025
protocol: TCP
targetPort: 8025
selector:
app: mailhog
status:
loadBalancer: {}
Le contenu sera stocké dans le fichier mailhog-service.yaml
Application de la définition du service
$ kubectl apply -f mailhog-service.yaml
service/mailhog configured
Gestion de la réentrance
Tout comme pour le déploiement CreationTimestamp et Status à supprimer
Fichier mailhog-service.yaml :
apiVersion: v1
kind: Service
metadata:
labels:
app: mailhog
name: mailhog
spec:
ports:
- name: port-1
port: 1025
protocol: TCP
targetPort: 1025
- name: port-2
port: 8025
protocol: TCP
targetPort: 8025
selector:
app: mailhog
loadBalancer: {}
Mécanisme de sélecteur et labels
metadata:
labels:
cle1: valeur1
cle2: valeur2
$ kubectl get pods -l app=mailhog
Regroupement de la création des éléments
– Création d’un répertoire mailhog
– Déplacement du fichier mailhog-deployment.yaml dans ce répertoire sous le nom deployment.yaml
– Déplacement du fichier mailhog-service.yaml dans le répertoire sous le nom service.yaml
$ kubectl apply -f ./mailhog
u70779858@Kubernetes-SRV:~$ k apply -f ./mailhog deployment.apps/mailhog unchanged service/mailhog unchanged
Consultation de l’état d’un groupe d’objets
$ kubectl get -f ./mailhog
u70779858@Kubernetes-SRV:~$ k get -f ./mailhog NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/mailhog 1/1 1 1 25h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mailhog ClusterIP 10.111.25.214 <none> 1025/TCP,8025/TCP 24h u70779858@Kubernetes-SRV:~$
Structure des objets
Interrogation de Kubernetes avec kubectl
Kubectl offre la possibilité d’interroger le moteur de Kubernetes la structure d’un objet (explain)
$ kubectl explain service
KIND: Service VERSION: v1 DESCRIPTION: Service is a named abstraction of software service (for example, mysql) consisting of local port (for example 3306) that the proxy listens on, and the selector that determines which pods will answer requests sent through the proxy. FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata spec <Object> Spec defines the behavior of a service. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status status <Object> Most recently observed status of the service. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
$ kubectl explain service.status
u70779858@Kubernetes-SRV:~$ k explain service.status KIND: Service VERSION: v1 RESOURCE: status <Object> DESCRIPTION: Most recently observed status of the service. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status ServiceStatus represents the current status of a service. FIELDS: conditions <[]Object> Current service state loadBalancer <Object> LoadBalancer contains the current status of the load-balancer, if one is present.
Ingress et reverse proxy
Origine du Besoin
Inaccessible depuis l’extérieur sauf à passer la commande kubectl port-forward
Les objets Ingress conçu pour ce type d’opération. Ces derniers comme le déploiement et les services se manipulent à l’aide de la commande kubectl get describe et create ou apply.
Rôle d’un proxy inverse
Un proxy inverse désigne un composant qui va se placer en amont d’un autre afin d’étendre ses capacités.
Utilisée pour répondre aux problématiques suivantes.
– Accéder à un programme inaccessible directement depuis Internet
– Répartir la charge sur plusieurs serveurs
– Prendre en charge les opérations de chiffrements et de compression
– Prendre en charge la gestion de sécurité.
– Mutualiser les accès et réduire l-utilisation d’adresse IP publiques.
Minikube dispose d’un contrôleur Nginx prêt à l’emploie par simple activation.
Activation du contrôleur Ingress dans MInikube
$ minikube addons enable ingress
u70779858@Kubernetes-SRV:~$ k explain service.status KIND: Service VERSION: v1 RESOURCE: status <Object> DESCRIPTION: Most recently observed status of the service. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status ServiceStatus represents the current status of a service. FIELDS: conditions <[]Object> Current service state loadBalancer <Object> LoadBalancer contains the current status of the load-balancer, if one is present. u70779858@Kubernetes-SRV:~$ minikube addons enable ingress * ingress est un addon maintenu par Kubernetes. Pour toute question, contactez minikube sur GitHub. Vous pouvez consulter la liste des mainteneurs de minikube sur : https://github.com/kubernetes/minikube/blob/master/OWNERS - Utilisation de l'image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1 - Utilisation de l'image registry.k8s.io/ingress-nginx/controller:v1.10.1 - Utilisation de l'image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1 * Vérification du module ingress... * Le module 'ingress' est activé u70779858@Kubernetes-SRV:~$
$ kubectl get namespace
NAME STATUS AGE default Active 25d ingress-nginx Active 5m17s kube-node-lease Active 25d kube-public Active 25d kube-system Active 25d kubernetes-dashboard Active 24d
Les pods associés à ce mécanisme portent le label app.kuberneters.io
$ kubectl -n ingress-nginx get pods -l app.kubernetes.io/name
u70779858@Kubernetes-SRV:~$ kubectl -n ingress-nginx get pods -l app.kubernetes.io/name NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-l7l9p 0/1 Completed 0 9m21s ingress-nginx-admission-patch-t5cdb 0/1 Completed 0 9m21s ingress-nginx-controller-6cbb9754ff-z746c 1/1 Running 0 9m21s u70779858@Kubernetes-SRV:~$
Déclaration d’une règle Ingress
Déclaration d’un objet Ingress est assez similaire à celle d’un service :
Fichier ./mailhog/ingress.yaml créé :
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: name: mailhog spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: mailhog port: number: 8025
$ kubectl apply -f mailhog/ingress.yalm
ingress.networking.k8s.io/mailhog created
Consultation des règles Ingress
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE mailhog nginx * 192.168.49.2 80 3m8s
NAME CLASS HOSTS ADDRESS PORTS AGES
|| mailhog nginx * localhost 80 4m54s
$ minikube ip
192.168.49.2
Ouvrir une session du serveur KUB-SERVER avec MobaXterm :
Interface Mailhog est maintenant accessible depuis un navigateur :
Hôte virtuel et nip.io
Hôte par défaut
Présentation du mécanisme de nip.io
IP 192.168.1.67.nip.io
Mailhog.192.168.1.67.nip.io
Configuration du serveur DNS
Adresse DNS 192.168.0.1 $ dig +short 192.168.0.1.nip.io $ nmcli connection show $ nmcli con mod « connexion filaire 1 » ipv4.dns « 8.8.8.8 8.8.8.4 $ nmcli con mod « connexion filaire 1 » ipv4.ignore-auto-dns yes $ nmcli con down « Connexion filaire 1 » $ nmcli con IP « Connexion filaire 1 « $ dig +short 192.168.0.1.nip.io
Création d’un hôte virtuel pour Mailhog
Modifier le fichier ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: name: mailhog spec: rules: - host: "mailhog.192.168.49.2.nip.io" http: paths: - path: / pathType: Prefix backend: service: name: mailhog port: number: 8025
$ kubectl appli -f mailhog/
$ curl 192.168.49.2
<html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html>
Le mécanisme de publication sur hôte virtuel est bien en place. Il va permettre de facilement exposer des applications HTTP vers l’extérieur.
Chapitre 5
Cycle de vie d’un container
Dans Kubernetes
L’application pourrait installer de plusieurs manières :
– manuellement à l’aide de Dashboard de Kubernetes
– Via la création de l’objet à l’aide. De kubectl
– Enfin, à l’aide de fichiers de définition des éléments à créer
Cycle de vie d’un container au travers de 2 aspects
– la correspondance entre un pod et son container au niveau du moteur Docker
– Le mécanisme de surveillance des containers
Gestion des crash d’application
Consultation de l’état des pods
$ kubectl get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE mailhog-b44849b6f-khwt9 1/1 Running 0 2d6h
Connexion à un pod
$ kubctl exec -it deployment/mailhog — sh
u70779858@Kubernetes-SRV:~$ k exec -it deployment/mailhog -- sh ~ $ ps -ef PID USER TIME COMMAND 1 mailhog 0:13 MailHog 14 mailhog 0:00 sh 20 mailhog 0:00 ps -ef ~ $
$ mkdir /tmp/test
$ ls -ld /tmp/test
PID USER TIME COMMAND 1 mailhog 0:13 MailHog 14 mailhog 0:00 sh 20 mailhog 0:00 ps -ef ~ $ mkdir /tmp/test ~ $ ls -ld /tmp/test drwxr-xr-x 2 mailhog mailhog 4096 Aug 26 14:21 /tmp/test
Container associé à MailHog
$ kubectl get pods -l app=mailhog -o jsonpath= »{.items[*].status.containerStatuses[*].containerID} »
u70779858@Kubernetes-SRV:~$ kubectl get pods -l app=mailhog -o jsonpath="{.items[*].status.containerStatuses[*].containerID}"
containerd://6a520ea5128e7f8914626c13b7c0c3bde7c942b8e225230d7251e31be0a0f37cu70779858@Kubernetes-SRV:~$
Comportement en cas de Crash
Killer le process de MailHog
Constat : Le process a démarré automatiquement
$ kubectl get pods -l app=mailhog
u70779858@Kubernetes-SRV:~$ kubectl get pods -l app=mailhog NAME READY STATUS RESTARTS AGE mailhog-b44849b6f-khwt9 1/1 Running 4 (5m45s ago) 5d
– Un préfixe (containerd://)
– Un Identifiant unique : //6a520ea5128e7f8914626c13b7c0c3bde7c942b8e225230d7251e31be0a0f37cu70779858@Kubernetes-SRV.
Cet identifiant est celui correspondant au moteur de container (ici Containerd)
u70779858@Kubernetes-SRV:~$ ps -ef |grep -i mailhog u707798+ 835215 721591 1 09:27 ? 00:00:00 MailHog u707798+ 835254 834140 0 09:27 pts/1 00:00:00 grep --color=auto -i mailhog u70779858@Kubernetes-SRV:~$ kill 835215 u707798+ 835387 721591 1 09:31 ? 00:00:00 MailHog u707798+ 835426 834140 0 09:31 pts/1 00:00:00 grep --color=auto -i mailhog
u70779858@Kubernetes-SRV:~$ kubectl get pods -l app=mailhog -o jsonpath="{.items[*].status.containerStatuses[*].containerID}"
containerd://72c035a1530b03c3f8664e8c9fb490f842511feac76e8ad3636e3b3d52b1521eu70779858@Kubernetes-SRV:~$
ce n’est plus le même ID du container : //72c035a1530b03c3f8664e8c9fb490f842511feac76e8ad3636e3b3d52b1521eu7077985
Etat du container après redémarrage du pod
$ kubectl exec -it deployment/mailhog — sh
u70779858@Kubernetes-SRV:~$ kubectl exec -it deployment/mailhog -- sh ~ $ ls -ld /tmp/test ls: /tmp/test: No such file or directory ~ $
Container vu depuis Containerd (Minikube)
$ ps -ef |grep -i mailhog
u707798+ 835387 721591 0 09:31 ? 00:00:00 MailHog u707798+ 836070 834140 0 09:51 pts/1 00:00:00 grep --color=auto -i mailhog
u70779858@Kubernetes-SRV:~$ kill -9 835387
u70779858@Kubernetes-SRV:~$ ps -ef |grep -i mailhog
u707798+ 836140 721591 0 09:52 ? 00:00:00 MailHog u707798+ 836180 834140 0 09:52 pts/1 00:00:00 grep --color=auto -i mailhog
u70779858@Kubernetes-SRV:~$ kubectl get pods -l app=mailhog -o jsonpath= »{.items[*].status.containerStatuses[*].containerID} »
containerd://ecc0c44c605e133a396cac35cb5244b20e4cd86d079979efe77c2c083b6cbbd7u70779858@Kubernetes-SRV:~$
u70779858@Kubernetes-SRV:~$ minikube ssh
docker@minikube:~$ sudo crictl inspect 126010f1d0ab0
docker@minikube:~$ sudo crictl inspect ecc0c44c605e133a396cac35cb5244b20e4cd86d079979efe77c2c083b6cbbd7
docker@minikube:~$ sudo crictl inspect ecc0c44c605e133a396cac35cb5244b20e4cd86d079979efe77c2c083b6cbbd7
{
"status": {
"id": "ecc0c44c605e133a396cac35cb5244b20e4cd86d079979efe77c2c083b6cbbd7",
"metadata": {
"attempt": 5,
"name": "mailhog"
},
"state": "CONTAINER_RUNNING",
"createdAt": "2024-08-29T07:52:16.99],
"maskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
]
}
],
"annotations": {
"io.kubernetes.cri.container-name": "mailhog",
"io.kubernetes.cri.container-type": "container",
"io.kubernetes.cri.image-name": "docker.io/mailhog/mailhog:latest",
"io.kubernetes.cri.sandbox-id": "9d0ff9f9095f688525269520c584a0b3492997e3fcd6febd8fbf321eeb2d02b1",
"io.kubernetes.cri.sandbox-name": "mailhog-b44849b6f-khwt9",
"io.kubernetes.cri.sandbox-namespace": "default",
"io.kubernetes.cri.sandbox-uid": "6e0f6f06-c040-4f88-ba2d-a5a86c5300e1"
},
"linux": {
"readonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
}
}
}
}
docker@minikube:~$ sudo crictl ps –all –label io.kubernetes.container.name=mailhog
docker@minikube:~$ sudo crictl ps --all --label io.kubernetes.container.name=mailhog CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD ecc0c44c605e1 4de68494cd0db 20 minutes ago Running mailhog 5 9d0ff9f9095f6 mailhog-b44849b6f-khwt9 72c035a1530b0 4de68494cd0db 41 minutes ago Exited mailhog 4 9d0ff9f9095f6 mailhog-b44849b6f-khwt9
Attention au nettoyage
Dans le cas de kubernetes , le crash d’un container va donc avoir 2 conséquences .
– la création d’un nouveau container
– la présence d’un container arrêté
Etat d’un container
Pourquoi scruter l’état d’un container ?
Un process peut être :
-
soit dans un état figé
-
soit dans un boucle infini
-
soit dans un état saturé
Vérification de la présence d’un process :
-
Surveiller la présence d’un port d’écoute
-
Surveiller la présence d’un fichier
-
Réaliser une connexion HTTP
-
Se connecter à une base de données
-
Faire appel à une page de diagnostic
Readines vs Liveness
Kubernetes permet de définir 2 types de surveillance sur un container
-
tests Readines : container est-il prêt
-
tests liveness : container est-il toujours utilisable
-
TEST SUPPLEMENTAIRE : startupProbe lors de démarage du container ( faire appel à ce champ pour les containers ayant une phase de démarrage un peu longue
Vérification de la présence d’un port
Fichier mailhog-tcp-port.yaml
apiVersion: apps/v1 kind: Deployment metadata: labels: app: mailhog name: mailhog spec: replicas: 1 selector: matchLabels: app: mailhog template: metadata: labels: app: mailhog spec: containers: - image: mailhog/mailhog name: mailhog readinessProbe: tcpSocket: port: 1025 livenessProbe: tcpSocket: port: 8025
$ kubectl apply -f mailhog/mailhog-tcp-port.yaml
u70779858@Kubernetes-SRV:~$ kubectl apply -f mailhog/mailhog-tcp-port.yaml deployment.apps/mailhog configured
Etat d’indisponibilité sur un pod non prêt
Nouvelle de définition du champ readinessProbe :
-
readinessProbe:
-
tcpSocket:
-
port: 2025
AVANT MODIF mailhog-tcp-port.yaml :
$ k get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE
mailhog-6d798f5dd-mj54x 1/1 Running 0 3m54s
APRES MODIF mailhog/mailhog-tcp-port.yaml :
u70779858@Kubernetes-SRV:~$ vim mailhog/mailhog-tcp-port.yaml
u70779858@Kubernetes-SRV:~$ kubectl apply -f mailhog/mailhog-tcp-port.yaml
deployment.apps/mailhog configured
u70779858@Kubernetes-SRV:~$ k get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE
mailhog-6d798f5dd-mj54x 1/1 Running 0 4m58s
mailhog-86f6dc75dc-jjgmp 0/1 Running 0 6s
Le point intéressant est ici le champ READY du nouveau pod mailhog-86f6dc75dc-jjgmp qui reste indéfiniment à la valeur 0/1 . Cette indication indique que le pod n’est pas prêt pour recevoir le trafic.
Test d’indisponibilité sur un pod en mauvaise santé : PAGE 168-188
Allocation de ressources à l’application à l’application MailHog
- Modifier le fichier deployment.yaml
u70779858@Kubernetes-SRV:~$ kubectl apply -f mailhog/deployment.yaml
deployment.apps/mailhog configured
u70779858@Kubernetes-SRV:~$ k get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE mailhog-7d9896576-v6tt9 1/1 Running 0 25s
Comportement en cas de saturation des ressources
Demande trop importanate de CPU
-
Modification du fichier : deployment.yaml
u70779858@Kubernetes-SRV:~$ kubectl apply -f mailhog/deployment.yaml
deployment.apps/mailhog configured
u70779858@Kubernetes-SRV:~$ k get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE mailhog-7c694f6b56-xdvfs 0/1 ContainerCreating 0 6s mailhog-7d9896576-v6tt9 1/1 Running 0 5m40s
Creer le fichier : mailhog-deployment.yaml

u70779858@Kubernetes-SRV:~$ kubectl apply -f ./mailhog
deployment.apps/mailhog configured ingress.networking.k8s.io/mailhog configured deployment.apps/mailhog configured deployment.apps/mailhog configured service/mailhog unchanged
u70779858@Kubernetes-SRV:~$ k get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE mailhog-7bc6c6fdb8-8525t 1/1 Running 0 4m48s
Consultation des priorités des pods
-
La définition de la classe de priorité sur un pod se fait à l’aide du champ priorityClassName.
$ kubectl describe pods -1 app-mailhog
Dans le cas où le pod n’aurait pas de classe de priorité, le champ Priority- ClassName prendra la valeur <none>.
La récupération de l’ensemble des classes de priorité des pods du cluster peut se faire à l’aide de la commande kubectl suivie des options suivantes :
– Une option de sélection de l’espace de noms système (-n kube-system).
L’option -o suivie de l’option custom-columns suivie des colonnes
Les instructions get pods.
suivantes :
– NAME : récupération du nom du pod (.metadata.name).
– PRIORITY : récupération de la classe (.spec.priorityClassName).
Remarque
Pour récupérer l’ensemble des pods, utilisez l’option –all-namespaces. La commande à lancer prenant en compte ces indications:
$ kubectl get pods -n kube-system -o custom-columns=NAME: .metadata.name, \ PRIORITY:.spec.priorityClassName
u70779858@Kubernetes-SRV:~$ kubectl get pods -n kube-system -o custom-columns=NAME:.metadata.name,PRIORITY:.spec.priorityClassName NAME PRIORITY coredns-6d4b75cb6d-cp7st system-cluster-critical etcd-minikube system-node-critical kindnet-gfc94 <none> kube-apiserver-minikube system-node-critical kube-controller-manager-minikube system-node-critical kube-proxy-248nb system-node-critical kube-scheduler-minikube system-node-critical metrics-server-8cf8b7f65-9b5v2 system-cluster-critical storage-provisioner <none>
Les pods critiques pour le système sont bien affectés à une classe de priorité :
– La classe system-node-critical pour les pods Calico gérant le réseau.
– La classe system-cluster-critical pour le pod CalicoTypha.
Les pods de gestion du réseau ont la priorité la plus grande tandis que le pod Calico Typha (affecté au stockage de données pour Calico) est légèrement En cas de conflit entre ces deux types de pods, le pod Typha sera réaffecté sur un autre noeud tandis que le pod de gestion du réseau Calico restera en
moins prioritaire.
Création d’une classe de priorité
Création d’une classe : Déclaration contenant les indications suivantes.
– La version d’API (apiVersion).
– Un champ metadata avec le nom de la classe (champ name).
– Un champ description.
– Un champ value avec un entier donnant le priorité relative
Pour une classe custom-priority de priorité 100 000 :
-
Création le fichier sous le nom custom-priority-class.yaml
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: custom-priority description: Custom priority class. value: 100000
$ kubectl apply -f custom-priority-class.yaml
$ kubectl get priorityclasses
u70779858@Kubernetes-SRV:~$ kubectl get priorityclasses NAME VAL
Affectation d’une classe de priorité personnalisée
-
Comme indiqué plus haut, l’affectation de la classe de priorité se fait dans le champ priorityClassName associé à un pod.
Reprenez le fichier associé au déploiement de MailHog afin d’y ajouter ce champ à la valeur custom-priority.
Ci-dessous la déclaration suite à cet ajout :
Sauvegardez le fichier sous le nom mailhog.yaml et appliquez-le :
$ kubectl apply -f mailhog.yaml
Dorénavant, en cas de conflit avec un autre déploiement, MailHog sera prioritaire
Remarque sur les classes de priorité par défault
-
Les classes de priorié du cluster ont des niveaux très importants. Afin d’éviter qu’une charge applicative puisse prendre le pas sur une charge système, ces Les classes de priorité du cluster ont des niveaux très importants. Afin d’éviter classes ne peuvent pas être affectées à un pod en dehors de l’espace de noms kube-system.
-
Dans le cas où vous tenteriez d’effectuer cette affectation, le cluster Kuber- netes refuserait de le faire. Dans le cas d’un déploiement, l’erreur se trouverait au niveau de l’objet intermédiaire ReplicaSet.
-
Cette consultation peut se faire à l’aide de la commande suivante (pour l’application MailHog) :
$ kubectl describe rs -l app=mailhog
$ kubectl get pods -l app=mailhog
u70779858@Kubernetes-SRV:~$ k get pods -l app=mailhog -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2024-09-02T13:22:48Z"
generateName: mailhog-b558bd46-
labels:
app: mailhog
pod-template-hash: b558bd46
name: mailhog-b558bd46-xddmj
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: mailhog-b558bd46
uid: dd626857-233b-4226-8075-126ee8677905
resourceVersion: "1844580"
uid: 60bb8232-8f74-4ae6-89ef-15f0fa2aa020
spec:
containers:
- image: mailhog/mailhog
imagePullPolicy: Always
name: mailhog
resources:
limits:
cpu: 400m
memory: 128Mi
requests:
cpu: 150m
memory: 64Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-4vzsl
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: minikube
preemptionPolicy: PreemptLowerPriority
priority: 100000
priorityClassName: custom-priority
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-4vzsl
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2024-09-02T13:22:48Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2024-09-02T13:22:52Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2024-09-02T13:22:52Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2024-09-02T13:22:48Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://f4392f5ac202ae000f8363b323d4738bfab1b5e36210d44067894ef3bd77fb12
image: docker.io/mailhog/mailhog:latest
imageID: docker.io/mailhog/mailhog@sha256:8d76a3d4ffa32a3661311944007a415332c4bb855657f4f6c57996405c009bea
lastState: {}
name: mailhog
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2024-09-02T13:22:51Z"
hostIP: 192.168.49.2
phase: Running
podIP: 10.244.0.48
podIPs:
- ip: 10.244.0.48
qosClass: Burstable
startTime: "2024-09-02T13:22:48Z"
kind: List
metadata:
resourceVersion: ""
Ci-dessous un exemple de message d’erreur indiquant l’origine du problème:
Warning FailedCreate 2s (x14 over 43s). replicaset-controller creating: pods "mailhog-5b6ddd9f6-" is forbidden: pods with system-cluster- critical priorityClass is not permitted in default namespace
Chapitre 6
Persistance des données
Objectifs du chapitre et prérequis
-
Ce chapitre présente la persistance des données dans Kubernetes. En effet, le contenu d’un container n’a pas vocation à perdurer. Ce mécanisme est là pour permettre de conserver une information lorsque c’est nécessaire (bases de données, serveurs de fichiers, etc.).
-
Le chapitre abordera deux points de vue :
– L’utilisateur faisant appel aux volumes persistants.
– L’administrateur mettant en place ce mécanisme.
Chapitre 6
Persistance des données
Page 189
2.1Origine du besoin
-
Dans ce qui a précédé, vous avez pu aborder le cycle de vie du container dans Kubernetes. Un point important à retenir est qu’un container a une durée de vie relativement courte et, qu’en l’état, il n’est pas possible de conserver de la donnée.
-
Pour répondre à ce besoin, Kubernetes peut mettre à disposition des espaces de stockage externes au cluster. Ce mécanisme s’appuie sur la notion de volume de données persistant (Persistent Volume).
2.2 Utilisation d’un volume persistant externe
-
L’utilisation d’un volume persistant se fait au sein de la déclaration d’un pod. Une première solution pourrait être de passer par un service externe comme avec un point de montage NFS.
-
Cette déclaration de persistance de données se définira en deux parties :
– Un référencement au niveau du pod dans le champ volumes.
– une indication de l’emplacement du montage au sein du container.
-
Le référencement d’un volume NFS au niveau d’un pod se présentera sous la forme suivante :
spec: volumes: - name: nfs nfs: # URL for the NFS server server: 192.168.0.1 path: /
-
Le montage au niveau du container se présentera ainsi :
spec: containers: name: mailhog image: mailhog/mailhog # Mount the NFS volume in the container volumeMounts: name: nfs mountPath: /maildir
2.3 Volumes persistants
2.3.1 Structure du volume persistant
-
En plus de faire appel à des services externes, il est possible de référencer des objets de type volume persistant (Persistent Volume). Ces derniers ont la structure suivante :
– Une version et un type (apiVersion et kind).
– Des métadonnées (champ metadata).
– Une spécification contenant :
– le type d’accès,
– la capacité de stockage,
– la classe du volume persistant (positionner à manual pour l’exemple), – les caractéristiques du stockage.
-
Ci-dessous un exemple de stockage portant le nom de pv-mailhog s’appuyant sur un répertoire de la machine hôte. Ce volume a une capacité déclarée de 10 Go:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-mailhog
spec:
accessModes:
- ReadWriteOnce
storageClassName: manual
capacity:
storage: 10Mi hostPath:
path: /maildir
-
Sauvegardez cette déclaration dans le fichier pv-mailhog.yaml.
2.3.2 Création du volume persistant
- La déclaration réalisée, l’application de cette déclaration se fera à l’aide de la commande kubectl suivie des indications suivantes :
– Le mot-clé apply.
– L’option -f suivie du nom de fichier.
- Ci-dessous la commande correspondante:
$ kubectl apply -f pv-mailhog.yaml
persistentvolume/pv-mailhog created
2.4 Persistance de données avec MailHog
2.4.1 Opérations à réaliser
Par défaut, lorsque MailHog reçoit un message, ce dernier le stocke en local dans un répertoire de travail. Malheureusement, lorsque le pod est relancé ou redémarré, la donnée se perd.
Afin de faire face à ce problème, ajoutez un point de montage dans le contai- ner de MailHog.
Pour cela, deux modifications seront réalisées dans l’objet déploiement :
Utilisation d’un volume persistant.
– Modification des options de lancement de MailHog.
En plus de ces modifications dans le déploiement, vous devrez également dé- clarer un objet permettant de référencer le volume persistant.
Cet objet fera le lien entre le volume persistant et la déclaration d’utilisation.
2.4.2 Déclaration de l’objet PersistentVolumeClaim
La demande de volume persistant (PersistentVolumeClaim ou son raccourci pvc) réclame un certain nombre d’informations:
Les champs apiVersion et kind.
– Les métadonnées (metadata).
– Les spécifications de l’objet :
– le mode d’accès,
– la classe précisée précédemment (manual),
– la quantité de ressources demandées,
– le nom du volume persistant.
Dans le cas d’un objet PersistentVolumeClaim portant le nom de mailhog pour un volume de 10 Go, la déclaration sera la suivante :
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-mailhog spec: accessModes: - ReadWriteOnce storageClassName: manual resources: requests: storage: 10Gi volumeName: pv-mailhog
$ kubectl apply -f pvc-mailhog.yaml
persistentvolumeclaim/pvc-mailhog created
2.4.3 État des objets de volume persistant
La consultation de ces objets se fait traditionnellement avec les méthodes get ou describe.
Ci-dessous la commande pour consulter la liste des volumes persistants
(Persistent Volume ou pv):
$ kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-mailhog 10Gi RWO Retain Bound default/pvc-mailhog manual 4h8m
L’ensemble de ces champs va donner les informations suivantes :
– NAME: nom du volume persistant.
– CAPACITY: taille du volume persistant.
– ACCESS MODES: types d’accès autorisés.
– RECLAIM POLICY: permet de spécifier le comportement à adopter en cas de suppression de l’objet PersistentVolumeClaim (garder le volume ou suppression automatique).
– STATUS: si le volume est associé (Bound) ou détaché (Released) vis-à-vis d’un objet PersistentVolumeClaim.
– CLAIM: nom de l’objet PersistentVolumeClaim associé.
– STORAGECLASS: classe utilisée par le volume.
Le volume persistant pv-mailhog est bien lié à l’objet Persistent Volume-
2.4.4 État de la demande de volume persistant
Comme pour les objets Persistent Volume, il est possible de consulter Tétat des demandes de volumes persistants (PersistentVolumeClaim ou pvc):
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-mailhog Bound pv-mailhog 10Gi RWO manual 4h10m
Ci-dessous une description des champs renvoyés :
NAME : nom du PersistentVolumeClaim.
– STATUS : état vis-à-vis du Persistent Volume.
– CAPACITY: taille du PVC.
– ACCESS MODES: accès demandé (un seul pod à la fois, plusieurs, lecture seule).
– STORAGECLASS: nom de la classe de stockage.
– AGE: âge du PVC.
La valeur Bound au niveau du champ STATUS indique que le PVC est lié au PV.
2.4.5 Déclaration du point de montage
Par la suite, la déclaration de déploiement de l’application MailHog sera re- prise dans le fichier deployment.yaml.
Au niveau des modifications à réaliser, vous devrez ajouter un sous-champ vo- lumes au niveau du champ spec du pod (champ spec –> template –> spec volumes).
Ce sous-champ va prendre les valeurs suivantes :
– Un champ name pour être référencé depuis la liste des containers.
– Un champ persistent Volume Claim avec le champ claimName poin- tant sur le nom de l’objet PVC précédemment créé (pvc-mailhog).
Le nom du volume prendra la valeur mailhog-maildir.
Ci-dessous la déclaration correspondant à ces indications:
volumes:
- name: mailhog-maildir
persistentVolumeClaim: { claimName: pvc-mailhog }
2.4.6 Ajout d’un point de montage sur le container
Au niveau du container associé à MailHog, l’ajout du champ volumeMounts va permettre de donner une liste de montages à réaliser. Chaque point de
montage prend le contenu suivant :
– Le champ mount Path suivi de l’emplacement du point de
montage.
– Le champ name permettant de pointer sur le volume défini plus haut.
Ci-dessous le champ containers suite à la prise en compte de ces modifications:
containers:
- image: mailhog/mailhog
name: mailhog
image Pull Policy: IfNotPresent
volumeMounts:
- mountPath: /maildir
name: mailhog-maildir
2.4.7 Options de lancement de MailHog
Le point de montage est prêt. Il est malgré tout nécessaire d’indiquer à MailHog que les données devront être écrites à cet emplacement.
Pour ce faire, l’application MailHog supporte les options suivantes :
-storage-maildir: indique de passer par un répertoire au format Maildir.
-maildir-path=/maildir: indique que l’écriture devra se faire dans le répertoire/maildir.
Ce répertoire correspondant à l’emplacement du point de montage, MailHog n’écrira plus dans le container mais dans ce volume de données externe.
Ce passage de paramètres se fait au niveau de la déclaration du container avec le champ command. Ce champ prend en paramètre un tableau de chaîne de caractères.
Ci-dessous le champ containers suite à l’ajout de ce champ:
containers:
- image: mailhog/mailhog
name: mailhog
image PullPolicy: IfNot Present
volumeMounts:
- mountPath: /maildir
name: mailhog-maildir
command:
- "MailHog"
- "-storage-maildir"
- "-maildir-path=/maildir"
2.4.8 Déclaration entière suite aux modifications
L’ensemble des modifications devrait vous amener au contenu suivant : Fichier mailhog/mailhog-deployement.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mailhog
name: mailhog
spec:
replicas: 1
selector:
matchLabels:
app: mailhog
template:
metadata:
labels:
app: mailhog
spec:
containers:
- image: mailhog/mailhog
name: mailhog
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /maildir
name: mailhog-maildir
command:
- "MailHog"
- "-storage=maildir"
- "-maildir-path=/maildir"
volumes:
- name: mailhog-maildir
persistentVolumeClaim: { claimName: pvc-mailhog }
Pour des raisons de clarté, les tests de type readiness ou liveness de MailHog n’ont pas été reportés dans l’exemple. Rien n’empêche de les conserver. Sauvegardez cette déclaration dans le fichier mailhog-deployment.yaml et appliquez la modification :
$ kubectl apply -f mailhog-deployment.yaml
deployment.apps/mailhog configured
Consultez l’état des pods :
$ kubectl get pods -l app=mailhog
NAME READY STATUS RESTARTS AGE
mailhog-69fb77b74b-mg9ns 1/1 Running 0 4h20m
Le lancement de la description du contenu du pod indiquera l’état des points
$ kubectl describe pods mailhog-69fb77b74b-mg9ns
Name: mailhog-69fb77b74b-mg9ns Namespace: default Priority: 0 Node: minikube/192.168.49.2 Start Time: Tue, 10 Sep 2024 10:36:37 +0200 Labels: app=mailhog pod-template-hash=69fb77b74b Annotations: <none> Status: Running IP: 10.244.0.29 IPs: IP: 10.244.0.29 Controlled By: ReplicaSet/mailhog-69fb77b74b Containers: mailhog: Container ID: containerd://24e034fa23ce3d3e479f59b186e5255f022ca0b3cd72b4c743b7e6182a225889 Image: mailhog/mailhog Image ID: docker.io/mailhog/mailhog@sha256:8d76a3d4ffa32a3661311944007a415332c4bb855657f4f6c57996405 c009bea Port: <none> Host Port: <none> Command: MailHog -storage=maildir -maildir-path=/maildir State: Running Started: Tue, 10 Sep 2024 10:36:38 +0200 Ready: True Restart Count: 0 Environment: <none> Mounts: /maildir from mailhog-maildir (rw) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-h9tjt (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: mailhog-maildir: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: pvc-mailhog ReadOnly: false kube-api-access-h9tjt: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: <none>
Ci-dessous un extrait renvoyé par cette commande indiquant l’état des points
2.5 Test de la persistance
2.5.1 Installation de mhsendmail
Afin de tester la persistance, vous allez envoyer un mail à l’application Mail- Hog à l’aide du programme mhsendmail.
Récupérez ce programme à l’adresse ci-dessous : https://github.com/mailhog/mhsendmail
Son installation peut se réaliser via les étapes suivantes :
– Téléchargement et extraction de l’archive d’installation en version v0.2.0.
– Ajout des droits d’exécution à l’aide de la commande chmod.
– Dépôt du fichier dans le répertoire /usr/local/bin à l’aide de sudo cp. Ci-dessous les commandes à lancer pour réaliser ces actions:
– Téléchargement de mhsendmail:
$ export MHURL= »https://github.com/mailhog/mhsendmail/releases »
$ wget $MHURL/download/v0.2.0/mhsendmail_linux_amd64 -O mhsendmail
u70779858@Kubernetes-SRV:~/mailhog$ wget $MHURL/download/v0.2.0/mhsendmail_linux_amd64 -O mhsendmail --2024-09-03 15:19:33-- https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 Résolution de github.com (github.com)… 140.82.121.3 Connexion à github.com (github.com)|140.82.121.3|:443… connecté. requête HTTP transmise, en attente de la réponse… 302 Found Emplacement : https://objects.githubusercontent.com/github-production-release-asset-2e65be/35970282/e7a6b69c-e952-11e5-9c5c-78ecf5f26102?X-Amz-Algorithm=AWS 4-HMAC-SHA256&X-Amz-Credential=releaseassetproduction%2F20240903%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240903T131933Z&X-Amz-Expires=300&X-Amz-Signatu re=bbb55a0f5d27f6fce877a1efd14ce01cafda4d9994715528ef0c64ee3b3df3ae&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=35970282&response-content-dispositi on=attachment%3B%20filename%3Dmhsendmail_linux_amd64&response-content-type=application%2Foctet-stream [suivant] --2024-09-03 15:19:33-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/35970282/e7a6b69c-e952-11e5-9c5c-78ecf5f26102?X-Amz-Al gorithm=AWS4-HMAC-SHA256&X-Amz-Credential=releaseassetproduction%2F20240903%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240903T131933Z&X-Amz-Expires=300&X- Amz-Signature=bbb55a0f5d27f6fce877a1efd14ce01cafda4d9994715528ef0c64ee3b3df3ae&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=35970282&response-conten t-disposition=attachment%3B%20filename%3Dmhsendmail_linux_amd64&response-content-type=application%2Foctet-stream Résolution de objects.githubusercontent.com (objects.githubusercontent.com)… 185.199.110.133, 185.199.111.133, 185.199.108.133, ... Connexion à objects.githubusercontent.com (objects.githubusercontent.com)|185.199.110.133|:443… connecté. requête HTTP transmise, en attente de la réponse… 200 OK Taille : 5878296 (5,6M) [application/octet-stream] Enregistre : «mhsendmail» mhsendmail 100%[============================================================================>] 5,61M --.-KB/s ds 0,07s 2024-09-03 15:19:34 (78,0 MB/s) - «mhsendmail» enregistré [5878296/5878296]
$ chmod +x mhsendmail
$ sudo cp mhsendmail /usr/local/bin/.
2.5.2 Ouverture de la communication avec le port SMTP
Afin de pouvoir communiquer avec le serveur SMTP de MailHog, il est néces- saire d’ouvrir le port avec la commande kubectl avec les options suivantes :
– Le mot-clé port-forward.
– Le nom du service sur lequel se connecter précédé par service/.
Le port à ouvrir pour accéder au service SMTP de MailHog (1025).
Ci-dessous la commande correspondante :
–
$ kubectl port-forward service/mailhog 1025
La commande devrait renvoyer le message suivant en gardant la main :
u70779858@Kubernetes-SRV:~/mailhog$ k port-forward service/mailhog 1025 Forwarding from 127.0.0.1:1025 -> 1025 Forwarding from [::1]:1025 -> 1025
2.5.3 Envoi d’un mail
Le port est ouvert et mhsendmail est installé. Il est maintenant temps d’envoyer un mail sur MailHog.
Préparez tout d’abord le contenu du mail. Ce dernier doit contenir certains champs. Ci-dessous quelques champs intéressants à renseigner:
– Un champ From avec l’expéditeur.
– Un champ To avec le destinataire.
– Un champ Subject avec le sujet de l’e-mail.
– Enfin, une ligne vide suivie du contenu du message.
Chaque champ sera référencé par son nom suivi de deux points (:) ainsi que sa valeur.
Afin d’envoyer un mail à bat@man.org de la part de super@man.org po organiser le pot de départ de Wonder Woman, le message pourrait ressembler au contenu suivant : email.txt
From: Clark Kent<manheng.luong@gmail.com> To: Bruce Wayne<manheng2.luong@gmail.com> Subject: Pot de départ Wonder Woman Salut Bruce, J'ai ouvert une cagnotte au bureau pour le départ de Diana. N'hésite pas à passer au bureau. Hengo
Pour la suite, le contenu de ce message sera stocké dans le fichier email.txt. Pour spécifier l’adresse du serveur SMTP, la commande mhsendmail supporte l’option –smtp-addr. Le passage du message se fait quant à lui à l’aide d’un pipe Unix. La lecture du contenu du fichier se fera à l’aide de la commande cat.
En reprenant toutes ces indications, l’envoi du mail se fera avec la commande suivante :
$ cat email.txt | mhsendmail –smtp-addr=127.0.0.1:1025
Ci-dessous le message renvoyé par cette commande :
error sending mail
2019/04/08 18:14:02 452 Unable to store message
Il semblerait que le serveur SMTP n’ait pas pu recevoir le message en raison d’un problème de stockage.
2.5.4 Droits du répertoire de persistance des données
Le message d’erreur reçu vient du fait que le répertoire monté dans le contai- ner ne dispose pas des droits nécessaires.
La correction du problème peut se faire en attribuant des droits plus larges sur le répertoire /tmp/pv-mailhog. Pour cela, dans le cas de Minikube, vous devrez suivre la procédure suivante :
– Connexion au serveur de Minikube avec la commande minikube ssh.
– Attribution des droits 777 au répertoire avec la commande chmod précédée par la commande sudo.
Ci-dessous la suite de commandes à lancer:
$ minikube ssh
$ sudo chmod -R 777 /maildir
- Remarque
L’attribution de droits de ce type est bien sûr fortement déconseillée. Vous aborderez plus loin des notions permettant de vous passer de ce type de contournement.
La relance de la commande d’envoi de mail devrait maintenant se passer sans problème.
$ cat email.txt | mhsendmail –smtp-addr=127.0.0.1:1025
2.5.5 Consultation de l’interface MailHog
Pour se connecter à l’application, la règle Ingress et le service associé à MailHog doivent être toujours là.
L’adresse de l’objet Ingress peut être consultée à l’aide de kubectl avec la commande suivante :
$ kubectl get ingress mailhog
Cette commande doit alors renvoyer le contenu suivant :
NAME CLASS HOSTS ADDRESS PORTS AGE
mailhog nginx mailhog.192.168.49.2.nip.io 192.168.49.2 80 15d
□ Rentrez l’adresse contenue dans le champ HOSTS dans un navigateur afin de consulter l’interface web de MailHog.
- Ouvrir une session via MobaXterm : lancer le navigateur firefox
- Lancer le navigateur firefox :
$ firefox
Sur la gauche, le lien Inbox permet de consulter la liste des messages reçus.
Interface MailHog: affichage du contenu d’un e-mail envoyé de la part de Superman
Interface MailHog: affichage du contenu d’un e-mail envoyé de la part de Superman
2.5.6 Suppression des pods
Afin de s’assurer que le mécanisme fonctionne bien, vous allez supprimer le pod avec la commande kubectl en utilisant les options suivantes :
$ kubectl delete pods -l app=mailhog
La commande doit alors renvoyer le message suivant :
pod "mailhog-69fb77b74b-mg9ns" deleted
2.5.7 Vérification du fonctionnement de la persistance
☑Une fois le pod supprimé, consultez la liste des pods de MailHog:
$ kubectl get pods -1 app-mailhog
- Remarque
Vous pouvez également ajouter l’option –wait (ou son raccourci -w) pour attendre que le pod soit démarré.
Ci-dessous le résultat attendu :
NAME READY STATUS RESTARTS AGE mailhog-69fb77b74b-76kcs 1/1 Running 0 97s
Sur l’interface web de MailHog, rafraîchissez le contenu de la page avec la touche [F5].
Le message de Clark Kent doit alors être présent indiquant que la persistance a bien fonctionné.
2.5.7.1 Vérification suite à la suppression du POD
- Relancer l’envoie de email.txt sur la 1ere Session
$ cat email.txt |mhsendmail –smtp-addr=127.0.0.1:1025
error sending mail 2024/09/10 15:59:36 EOF
- Erreur de la 1ere session pour le port-forward du service/mailhog
Solution :
- 1ère session : Relancer la commande port-forward
$ kubectl port-forward service/mailhog 1025
- 2ème session : Relancer l’envoie de email.txt
$ cat email.txt |mhsendmail –smtp-addr=127.0.0.1:1025
2.5.7.2 Vérification du contenu de Persistent Volume
- Se connecter sur le pod
$ minikube ssh
$ cd /maildir
-rw-r----- 1 docker 1000 342 Sep 10 08:37 '2BjKqJTM3KOGkoHKa0cgd_YlJO0HEsYFPIz8BvXcnG0=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 08:20 'DaIYisMGR-NisnA-MHPk8pRL8fBOSazw2AJcWQnH16A=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 08:37 'G9gPpmofBXzbbrXkXblzn1I9bFJbPPOAEKm-2ziaLAQ=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 08:35 'UZYmKWlbiCv72wYIeh8Ofn4uRfBbZb4b1w-oDmubXvY=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 14:14 'Uh_jSBPewXs6eE5-qOD5vENrYcOJsR-QwyRqWAUfMsU=@mailhog.example' -rwxrwxrwx 1 root root 0 Sep 10 08:16 aaa* -rw-r----- 1 docker 1000 342 Sep 10 08:35 'hlje0v1XGyci0t5262Lh9hxnWkOSnqsMZfD7jSD5j7A=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 08:20 'nNIL7FXuiIkItjeKMqPHxPTSBhH8973imEJEN-TEFhg=@mailhog.example' -rw-r--r-- 1 docker docker 0 Sep 10 08:20 qqq -rw-r----- 1 docker 1000 342 Sep 10 08:37 'xl2Cp9RDGV5J_kTmp8PgUUmjI-2cuNMppHNOQ3E99jo=@mailhog.example' -rw-r----- 1 docker 1000 342 Sep 10 08:20 'y7NhbHA0hBDRiozlfi0HboKpRyDxguoWZZyvON1-jMI=@mailhog.example'
3. Classes de stockage
3.1 Origine du besoin
La section précédente a permis d’aborder le travail nécessaire à la mise en place d’un volume persistant:
– Une déclaration pour indiquer que de l’espace disque est disponible. – Une déclaration pour pouvoir s’accaparer un espace disque.
– Une action manuelle pour positionner les droits sur les répertoires. Heureusement pour l’administrateur, ce travail de déclaration n’est saire. Il est possible de passer par un gestionnaire automatique de volume persistant : les objets StorageClass (ou son raccourci sc).
Ces objets vont se charger d’intercepter les demandes de volumes persistants (PersistentVolumeClaim) et de réaliser automatiquement les actions suivantes.
– Création de l’objet PersistentVolume.
– Attribution des droits ad-hoc.
Autre point, un cluster Kubernetes peut faire appel à plusieurs classes de stockage offrant plusieurs niveaux de services, comme par exemple :
– une classe ssd pour des disques rapides de type SSD,
– une classe hdd pour des disques durs classiques de type HDD,
– une classe nfs pour pouvoir partager un espace disque entre plusieurs pods.
Charge à vous ensuite de créer le type de disque nécessaire en fonction des besoins des utilisateurs.
Ainsi, une application réclamant des disques rapides pourra demander des disques SSD, tandis qu’une autre prendra des disques traditionnels afin de ré- duire les coûts de stockage.
3.2 Liste des classes de stockage
Sur Minikube, une classe de stockage est présente à l’installation.
Pour récupérer cette déclaration, lancez la commande kubectl avec les options suivantes :
Le verbe get.
– Le type à récupérer (storageclass ou son raccourci sc).
Ci-dessous la commande à lancer:
$ kubectl get storageclass (sc)
Et le résultat attendu :
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) k8s.io/minikube-hostpath Delete Immediate false 43d
Une classe de stockage porte le nom standard et cette dernière est définie par défaut. Autre point, le mécanisme d’approvisionnement porte le nom de k8s.io/minikube-hostpath
3.3 Détail d’une classe de stockage
Comme tout autre objet présent dans Kubernetes, il est possible de décrire un objet à l’aide de la commande kubectl suivie des options suivantes :
– Le verbe describe.
– Le type d’objet à consulter (storageclass ou sc).
· Le nom de l’objet à consulter (standard).
Ci-dessous la commande à lancer (faisant appel au raccourci sc pour StorageClass):
$ kubectl describe sc standard
Et le résultat renvoyé :
Name: standard
IsDefaultClass: Yes
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","m etadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"},"labels":{"addonmanager.kubernetes.io/mode":" EnsureExists"},"name":"standard"},"provisioner":"k8s.io/minikube-hostpath"}
,storageclass.kubernetes.io/is-default-class=true
Provisioner: k8s.io/minikube-hostpath
Parameters: <none>
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: Immediate
Events: <none>
3.4 Classe de stockage par défaut
Comme tout autre objet dans Kubernetes, les classes de stockage peuvent por- ter des annotations ou des labels.
Ici, la classe standard porte l’annotation storageclass.beta.kuber- netes.io/is-default-class-true en faisant ainsi la classe par défaut. Si un objet PersistentVolumeClaim ne précise rien, cette dernière sera utilisée.
- Remarque
Il ne peut y avoir à un instant T qu’une seule classe portant cette annotation.
3.5 Les différentes classes de stockage
3.5.1 Les différentes familles
Actuellement, il existe trois types de gestionnaires de volume:
– Les gestionnaires intégrés au code de Kubernetes.
– Les gestionnaires s’appuyant sur FlexVolume.
– Les gestionnaires s’appuyant sur l’interface CSI.
Actuellement, le type CSI (Container Storage Interface) est en version stable (depuis la version 1.13 et en bêta depuis la version 1.10). C’est la méthode recommandée pour écrire de nouveaux pilotes.
Ce type CSI est un standard permettant d’écrire des pilotes de gestion de volume pour des systèmes d’orchestration de containers (COS pour Container Orchestration Systems).
- Remarque
L’autre standard (FlexVolume) existe depuis la version 1.2 de Kubernetes, mais n’évoluera plus. Il s’appuie sur un mécanisme d’exécution de commandes. Ces commandes doivent être installées sur les machines constituant le cluster Kubernetes.
3.5.2 Origine de ces familles
Au début du projet, les pilotes de volume faisaient partie intégrante du code source de Kubernetes. Malheureusement, ce type d’organisation entraîne certaines contraintes :
– Mise à jour impossible d’un plugin sans changer la version de Kubernetes.
– Les mainteneurs de Kubernetes étaient responsables d’un code difficile à tester
– Un bug sur un gestionnaire de disque pouvait faire crasher Kubernetes.
– Les gestionnaires d’espaces disque avaient les mêmes droits que les compo- sants principaux de Kubernetes (pouvant entraîner des problèmes de sécurité).
– Le développement d’un pilote devait forcément être intégré comme une brique open source.
Partant de ce constat, la communauté autour de Kubernetes a fait le choix de sortir les gestionnaires de volume de la branche principale du code source. Ces gestionnaires sont maintenant en dehors du code de Kubernetes.
En anglais, ces deux types de gestionnaires sont référencés par le terme in-tree lorsqu’ils sont présents avec le code de Kubernetes, et ceux en dehors par le terme out-of-tree.
Pour en savoir plus, consultez le lien suivant (anglais) : https://github.com/ kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md
3.6 Caractéristiques des classes de stockage
3.6.1 Modes d’accès
Un volume persistant peut être accédé à l’aide de plusieurs modes:
– ReadWriteOnce : montage de l’espace disque sur un pod à la fois.
– ReadOnlyMany: lecture seule sur plusieurs pods à la fois.
– ReadWriteMany: montage en lecture-écriture dans plusieurs pods à la fois.
Au niveau des sorties de la commande kubectl, ces modes sont abrégés de la manière suivante :
– ReadWriteOnce : RWO
– ReadOnlyMany: RXO
– ReadWriteMany: RWX
3.6.2 Caractéristiques de certains pilotes
Kubernetes offre de nombreux pilotes par défaut. Ci-dessous un extrait des ca- pacités de quelques pilotes courants :
Pilote AWSElasticBlockStore AzureFile AzureDisk CephFS Cinder Fiber Channel FlexVolume Flocker GCEPersistentDisk Glusterfs HostPath iSCSI Photon Persistent Disk Quobyte NFS RBD Vsphere Volume PortworxVolume ScaleIO Mode d'accès RWO RWO, RXO et RWX RWO RWO, RXO et RWX RWO RWO et RXO RWO et RXO RWO RWO et RXO RWO, RXO et RWX RWO RWO et RXO RWO RWO, RXO et RWX RWO, RXO et RWX RWO et RXO RWO RWO et RWX RWO et RXO Nom du pilote kubernetes.io/aws-ebs kubernetes.io/azure-file kubernetes.io/azure-disk ceph.com/cephfs kubernetes.io/cinder kubernetes.io/fc external/flex-simple kubernetes.io/flocker kubernetes.io/gce-pd gluster.org/glusterfs-simple kubernetes.io/host-path iscsi-targetd kubernetes.io/photon-pd kubernetes.io/quobyte example.com/nfs kubernetes.io/rbd volume kubernetes.io/scaleio 209 kubernetes.io/vsphere-volume kubernetes.io/portworx-
La deuxième colonne donne les capacités du pilote et la troisième la valeur que devra prendre le champ provisioner lors de sa déclaration.
- Remarque
Les pilotes historiques de type in-tree font actuellement l’objet d’un portage sur le standard CSI. Il s’agit encore de travaux préliminaires qui sont toujours en version beta. À l’avenir, il ne restera que les pilotes out-of-tree.
Ainsi, un volume créé avec le pilote Vsphere Volume aura les caractéristiques
– Il ne pourra pas être partagé entre plusieurs pods.
– Le champ provisioner aura la valeur kubernetes.io/vsphere-
Pour plus de détails, consultez les adresses suivantes (anglais):
Classes de stockage de Kubernetes:
https://kubernetes.io/docs/concepts/storage/storage-classes
https://github.com/kubernetes-incubator/external-storage
3.6.3 Liste des pilotes chargés
Pour obtenir la liste des pilotes chargés dans un nœud Kubernetes, consultez la sortie du démon Kubelet.
Sur une machine faisant appel à systemd, vous pourrez obtenir cette informa- tion à l’aide de la commande journalctl suivie des options suivantes :
– L’option -u.
– Le nom du service à consulter (exemple : kubelet).
Le démon Kubelet est verbeux. Afin de réduire la quantité d’informations remontée, faites appel à la commande grep. Dans le cas des pilotes chargés automatiquement, les lignes intéressantes contiendront la chaîne de carac- tères plugins.go.
En combinant ces deux instructions, récupérez la liste des pilotes de stockage à l’aide de la commande suivante :
$ journalctl -u kubelet | grep « plugins.go »
Ci-dessous un extrait de la sortie dans le cas d’un noeud de cluster Kubernetes hébergé dans le cloud :
plugins.go:159] Loaded network plugin « kubenet »
plugins.go: 508] Loaded volume plugin « kubernetes.io/aws-ebs » plugins.go:508] Loaded volume plugin « kubernetes.io/empty-dir » plugins.go:508] Loaded volume plugin « kubernetes.io/gce-pd »
plugins.go: 508] Loaded volume plugin « kubernetes.io/storageos » plugins.go: 508] Loaded volume plugin « kubernetes.io/csi »
Dans le cas de Minikube, Kubernetes ne charge aucun pilote. Ci-dessous la sortie que vous devriez obtenir :
… plugins.go:103] No cloud provider specified.
3.7 Déclaration d’une classe de stockage
3.7.1 Structure de la déclaration
Tout comme pour un déploiement, la déclaration d’une classe de stockage se fait à l’aide d’un fichier au format YAML. Le fichier devra contenir les champs suivants :
– apiVersion: doit prendre la valeur storage.k8s.io/v1.
– kind : doit prendre la valeur StorageClass.
– metadata: doit contenir un champ name (hdd, sdd, nfs, etc.).
– parameters: paramètres optionnels (type, encrypted).
– provisioner: nom du pilote de gestion de volume.
– reclaimPolicy: politique à appliquer par défaut sur les objets PersistentVolume en cas de suppression de l’objet PersistentVo-
lumeClaim associé.
– volumeBindingMode: politique pour la création des volumes (par défaut
immédiat).
3.7.2 Exemple de déclaration
Dans l’exemple qui va suivre, vous allez créer une classe de stockage respectant les indications suivantes :
– Le stockage se fera à l’aide du service de stockage de Minikube (k8s.io/ minikube-hostpath).
– La classe portera le nom hdd.
– La suppression de l’objet PVC entraînera celle du PV.
– La politique de création sera immédiate.
–
- Remarque
Si vous faites tourner cet exemple en dehors de Minikube, il sera nécessaire de changer la valeur du champ provisioner (par exemple: kubernetes.io/ host-path).
La déclaration ci-dessous correspond à ces indications:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hdd provisioner: k8s.io/minikube-hostpath reclaimPolicy: Delete volumeBindingMode: Immediate
Sauvegardez cette déclaration dans le fichier storage-class.yaml.
- Appliquez cette définition à l’aide de la commande suivante :
$ kubectl apply -f storage-class.yaml
Ci-dessous le résultat renvoyé au premier lancement: storageclass.storage.k8s.io/hdd created
3.8 Test de création automatique d’un volume persistant
Toutes ces déclarations peuvent sembler de prime abord complexes. Néanmoins, sans ce mécanisme, l’utilisateur doit réaliser les opérations
suivantes :
– Création du volume disque (dans une baie, création de répertoire, etc.) – Attribution des droits (chmod)
– Création d’un objet PV faisant la référence au volume ou à l’emplacement du répertoire
– Création d’un objet PVC référençant le PV
Suite à l’ajout de la classe de stockage, l’utilisateur n’aura plus qu’à créer un objet PVC.
Il sera vu également par la suite que dans certains cas (objet StatefulSet), cette déclaration ne se fait plus directement mais au travers d’un template afin d’allouer automatiquement de la volumétrie.
Pour ce test, l’exemple avec l’application MailHog sera repris. Le fichier de dé- ploiement n’aura pas besoin d’être changé.
Au niveau de la déclaration du volume persistant, modifiez l’élément storageClassName pour le faire pointer sur le nom de la classe de stockage qui vient d’être créée (hdd).
Ci-dessous le contenu du fichier pvc-mailhog.yaml et pv-mailhog.yaml suite à cette modification :
Ci-dessous le fichier pc-mailhog.yaml :
ci-dessous le fichier pvc-mailhog.yaml :
- Appliquez la modification:
$ kubectl apply -f pvc-maihog.yaml
$ kubectl apply -f pv-maihog.yam
Ci-dessous le résultat qui devrait être renvoyé :
The PersistentVolumeClaim "pvc-mailhog" is invalid: spec: Forbid- den: spec is immutable after creation except resources.requests for bound claims
core. PersistentVolumeClaimSpec{
mations.
suivante :
AccessModes: Selector:
Resources:
Volume Name:
Volume Name:
VolumeMode:
DataSource:
DataSourceRef:
- Le verbe delete.
{"ReadWriteOnce"},
nil, {...},
11 11
'
Ce message s’explique assez facilement : Kubernetes vous interdit de changer certains champs.
- Remarque
Un volume persistant n’a pas vocation à être changé en cours de vie. En effet, un changement de classe de stockage pourrait entraîner une perte d’infor-
Pour contourner le problème, vous allez supprimer le déploiement et la demande de volume persistant de MailHog. La suppression se fait à l’aide de la commande kubectl suivie des options suivantes :
– Le verbe delete
– L’option -f suivie des fichiers de définition d’objets à supprimer. Dans le cas où le déploiement serait défini dans le fichier deployment.yaml et la demande de volume dans le fichier pvc.yaml, la commande à lancer sera la suivante :
$ kubectl delete -f pv-mailhog.yaml -f pvc-mailhog.yaml -f mailhog-deployment.yaml
La commande renverra alors le résultat suivant:
persistentvolumeclaim « pvc-mailhog » deleted deployment.extensions « mailhog » deleted
☑Pour la création du volume persistant, faites appel à cette commande:
$ kubectl apply -f pv-mailhog.yaml -f pvc-mailhog.yaml -f mailhog-deployment.yaml
Ci-dessous le résultat renvoyé :
persistentvolumeclaim/pvc-mailhog created. deployment.extensions/mailhog created
Certains objets sont immutables : une fois créés, ils ne peuvent pas être modifiés. La seule façon de les modifier est donc de procéder à leur suppression avant de relancer leur création. Autre point d’attention, un objet PVC ne peut être supprimé tant qu’il est utilisé par un pod. Afin de pouvoir le supprimer, il est donc indispensable de supprimer l’objet déploiement de MailHog.
Chapitre 7
Hébergement d’application
en Cluster
1. Objectifs du chapitre et prérequis en cluster
Ce chapitre va aborder un besoin spécifique au fonctionnement de Kubernetes: l’hébergement d’un groupe de pods fonctionnant en cluster. Ce ype d’hébergement se retrouve souvent lors de la mise en place de base de données ou d’un ensemble de machines fonctionnant en cluster pour offrir de La haute disponibilité.
La gestion de la persistance de données sera abordée puisqu’elle diffère légère- ment du mécanisme précédemment abordé.
La synchronisation des données entre pods sera quant à elle abordée dans le
chapitre suivant.
2. Prérequis d’installation MariaDB sur le serveur
2. Déploiement d’une base de données MariaDB
2.1 Origine du besoin
Le lancement d’une base de données dans Kubernetes ne constitue pas en soi une difficulté: il existe des images pour la plupart des bases de données open Source du marché.
La principale difficulté va venir de deux aspects:
La persistance de la donnée.
– La mise en place de la résilience.
Par la suite, l’exercice va consister à déployer une base de données de type MariaDB et mettre en place une réplication.
2.2 Déploiement
2.2.1 Choix de l’image Docker
Sur le site Docker Hub (https://hub.docker.com), la base de données est disponible dans l’image officielle mariadb (https://hub.docker.com/_/mariadb). Une première installation va être réalisée afin de se familiariser avec cette dernière.
2.2.1.1 Comment charger image mariadb latest por docker
2.2.1.1.1 Procédure par ChatGPT IA
A: Pour charger l’image de MariaDB la plus récente dans Docker, vous pouvez suivre les étapes ci-dessous :
1. *Installer Docker* : Assurez-vous que Docker est installé sur votre machine. Vous pouvez vérifier cela en exécutant la commande suivante dans votre terminal :
bash
docker –version
2. *Tirer l’image MariaDB* : Utilisez la commande suivante pour télécharger la dernière version de l’image MariaDB depuis Docker Hub :
bash
docker pull mariadb:latest
Cela téléchargera l’image la plus récente de MariaDB.
3. *Créer un conteneur depuis l’image* : Une fois l’image téléchargée, vous pouvez créer un conteneur MariaDB en exécutant la commande suivante :
bash
docker run –name nom_du_conteneur -e MYSQL_ROOT_PASSWORD=mon_mot_de_passe -d mariadb:latest
Remplacez nom_du_conteneur par le nom que vous souhaitez donner à votre conteneur et mon_mot_de_passe par le mot de passe que vous souhaitez utiliser pour l’utilisateur root de MariaDB.
4. *Vérifier que le conteneur fonctionne* : Pour vérifier que votre conteneur est en cours d’exécution, utilisez la commande :
bash
docker ps
5. *Se connecter à MariaDB* : Vous pouvez vous connecter à MariaDB en utilisant la commande suivante :
bash
docker exec -it nom_du_conteneur mysql -u root -p
Entrez le mot de passe que vous avez configuré à l’étape 3.
Avec ces étapes, vous devriez être en mesure de charger et de démarrer l’image MariaDB la plus récente sur Docker. Si vous rencontrez des problèmes ou avez besoin d’informations supplémentaires, n’hésitez pas à demander.
https://apps.apple.com/app/apple-store/id6447419372?pt=121708643&ct=question-share&mt=8
2.2.1.1.2 Ianstallation image last téléchargée
u70779858@Kubernetes-SRV:~/mariadb$ docker pull mariadb:latest
latest: Pulling from library/mariadb dafa2b0c44d2: Pull complete 2d5e0d69d765: Pull complete 5145df719521: Pull complete ffe11d25f6ee: Pull complete f0eb027ac47e: Pull complete 586260156254: Pull complete 62c80f8d2eea: Pull complete 36be09cfdba3: Pull complete Digest: sha256:4066f2d4805fef72a83cf4a62689a0aadb6e83a8c8a82b64431edd4b94f684f8 Status: Downloaded newer image for mariadb:latest docker.io/library/mariadb:latest
u70779858@Kubernetes-SRV:~/mariadb$
3- Créer un container depuis l’image
$ docker run –name MyMariaDB -e MYSQL_ROOT_PASSWORD=mon_mot_de_passe -d mariadb:latest
4- Vérifier que le conteneur fonctionne
u70779858@Kubernetes-SRV:~/mariadb$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 52e3a99847cc mariadb:latest "docker-entrypoint.s…" 2 minutes ago Up About a minute 3306/tcp MyMariaDB 9f0e62fa257f mariadb:latest "docker-entrypoint.s…" 5 minutes ago Up 4 minutes 3306/tcp nom_du_conteneur 0f23edd5f7b4 gcr.io/k8s-minikube/kicbase:v0.0.44 "/usr/local/bin/entr…" 7 weeks ago Up 7 hours 127.0.0.1:32768->22/tcp, 127.0.0.1:32769->237.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp minikube
u70779858@Kubernetes-SRV:~/mariadb$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52e3a99847cc mariadb:latest « docker-entrypoint.s… » 2 minutes ago Up About a minute 3306/tcp MyMariaDB
9f0e62fa257f mariadb:latest « docker-entrypoint.s… » 5 minutes ago Up 4 minutes 3306/tcp nom_du_conteneur
0f23edd5f7b4 gcr.io/k8s-minikube/kicbase:v0.0.44 « /usr/local/bin/entr… » 7 weeks ago Up 7 hours 127.0.0.1:32768->22/tcp, 127.0.0.1:32769->2376/tcp, 127.0.0.1:32770->5000/tcp, 127.0.0.1:32771->8443/tcp, 127.0.0.1:32772->32443/tcp minikube
2.2.2 Version initiale du fichier de déploiement
Comme vu précédemment, kubectl permet de créer une ébauche de fichier de déploiement.
Pour cela, passez-lui les options suivantes :
– Le verbe create suivi du type (deployment).
– Un nom pour le déploiement (mariadb).
– L’option image suivie du nom d’image à utiliser (mariadb).
– L’option –dry-run pour ne pas créer directement le déploiement. – L’option –output yaml pour obtenir le résultat au format YAMLL Redirigez également le résultat de la commande dans le fichier mariadb- deployment.yaml.
Ci-dessous la commande correspondante :
$ kubectl create deployment mariadb\n–image-mariadb –dry-run=server –output yaml > Mariadb-deployment.yaml
Fichier : Mariadb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
generation: 1
labels:
app: mariadb
name: mariadb
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mariadb
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: mariadb
spec:
containers:
- image: mariadb:latest
imagePullPolicy: Always
name: mariadb
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
2.2.3 Gestion de la réentrance
Afin de gérer la réentrance, les champs inutiles (vides, nuls ou à une valeur par défaut) vont être supprimés.
Ci-dessous la liste des champs à supprimer:
– metadata –> creationTimestamp
– spec –> replicas
– spec –> strategy
– spec –> template –> metadata –> creationTimestamp
– spec –> template –> spec –> containers –> resources
– status
Ci-dessous le contenu du fichier Mariadb-deployment.yaml après ces modifications et renommé en Mariadb-deployment2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
generation: 1
labels:
app: mariadb
name: mariadb
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mariadb
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: mariadb
spec:
containers:
- image: mariadb:latest
imagePullPolicy: Always
name: mariadb
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
env:
- name: MYSQL_ROOT_PASSWORD
value: my-secret-pw
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
2.3 Volume persistant
2.3.1 Demande de volume persistant
Afin de conserver les données de la base,un objet PersistentVolume et un objet PersistentVolume- Claim vont être créés. Ce dernier répondra aux critères suivants : PV et PVC
– Le champ metadata –> name aura la valeur mariadb-data.
– Sa taille sera fixée à 10Go.
Ci-dessous la déclaration correspondante :
apiVersion: v1 kind: PersistentVolume metadata: name: mariadb-pv spec: accessModes: - ReadWriteOnce capacity: storage: 10Gi hostPath: path: /data/mariadb
PersistentVolume Claim :
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mariadb-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
Sauvegardez le contenu de cette déclaration dans le fichier Mariadb-pv.yaml et Mariadb-pvc.yaml let lancez la création de cet objet :
$ kubectl apply -f Mariadb-pv.yaml
$ kubectl apply -f Mariadb-pvc.yaml
La commande doit alors renvoyer le message suivant :
persistentvolume/mariadb-data created
2.3.2 État de la demande de volume persistant Consultez ensuite l’état de l’objet pvc :
$ kubectl get pv mariadb-data
$ kubectl get pvc mariadb-data
Ci-dessous un exemple de résultat indiquant que le volume est prêt :
NAME STATUS VOLUME mariadb-data Bound CAPACITY ACCESS MODES pvc-x-xxx-XX-X 10 Gi RWO
2.3.3 Ajout d’une persistance sur le container de MariaDB
Le volume persistant est prêt. Reste à indiquer au container de MariaDB d’uti- liser cet objet.
☑Dans le fichier de déploiement de MariaDB, ajoutez les champs suivants :
– volumes au niveau du champ spec –> template- –> spec.
– volume Mounts au niveau du champ spec –> template. –> containers.
Le champ volumes contiendra l’enregistrement suivant :
– Un champ name suivi de la valeur mariadb-data.
– Un enregistrement persistentVolumeClaim contenant le champ claimName à la valeur maria-data
volumes:
- name: mariadb-data
persistentVolumeClaim: { claimName: mariadb-data }
Le champ volumeMounts aura le contenu suivant :
– Un champ mount Path à la valeur /var/lib/mysql.
– Un champ name à la valeur mariadb-data.
Remarque :
Le chemin /var/lib/mysql correspond au chemin standard où sont stockés les fichiers de la base de données dans le cas de MariaDB ou MySQL.
Ci-dessous la déclaration correspondante :
volumeMounts:
- mountPath: /var/lib/mysql
nom: mariadb-data
En reprenant toutes ce indications, le contenu du fichier de déploiement de MariaDB devrait être le suivant : Mariadb-deployment3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
generation: 1
labels:
app: mariadb
name: mariadb
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: mariadb
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: mariadb
spec:
containers:
- image: mariadb:latest
imagePullPolicy: Always
name: mariadb
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
env:
- name: MYSQL_ROOT_PASSWORD
value: my-secret-pw
ports:
- containerPort: 3306
volumeMounts:
- name: mariadb-data
mountPath: /var/lib/mysql
volumes:
- name: mariadb-data
persistentVolumeClaim:
claimName: mariadb-pvc
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
Appliquez maintenant la définition de ce fichier à l’aide de la commande
$ kubectl apply -f Mariadb-deployment3.yaml
La commande doit alors renvoyer la sortie suivante :
deployment.apps/mariadb created
2.3.4 Consultation de l’état du déploiement
Consultez l’état du déploiement à l’aide de la commande suivante :
$ kubectl get -f app-mariadb
Afin de comprendre pourquoi le pod redémarre tout le temps, consultez le journal d’activité à l’aide de la commande suivante :
■ $ kubectl logs -l app=mariadb
4 Configuration de la base de données
Le message d’erreur indique que MariaDB (lors du premier démarrage) a besoin de connaître le mot de passe de l’administrateur.
Traditionnellement, dans le monde des containers, ces informations se transmettent à l’aide de variables d’environnement.
Afin de spécifier le mot de passe, la définition du container mariadb va être étendue avec le champ env. Ce champ env devra contenir un enregistrement disposant des informations suivantes :
– Le champ name suivi de la valeur MYSQL ROOT PASSWORD. – Le champ value suivi de la valeur mot-de-passe-root. Ci-dessous la déclaration correspondante de ce champ:
env:
name: MYSQL ROOT PASSWORD
value: mot-de-passe-root
Ci-dessous la déclaration complète intégrant cette modification:
►Sauvegardez la modification dans le fichier mariadb-deployment.yaml et appliquez la modification :
$ kubectl apply -f mariadb-deployment.yaml
La commande doit alors renvoyer le message suivant :
deployment.apps/mariadb configured
2.5 Consultation de l’état du pod
2.5.1 Liste des pods
■ Consultez l’état du pod de MariaDB à l’aide de la commande suivante :
$ kubectl get pods -l app=mariadb
La commande doit alors renvoyer la sortie suivante:
mariadb-d9d64786c-cgt8b READY 1/1 STATUS Running RESTARTS
Ici, le container associé à MariaDB fonctionne correctement.
25.2 Connexion au container
Afin de tester le fonctionnement de la base de données, vous allez devoir lan- cer un shell dans le container de base de données :
S kubectl exec -it deployment/mariadb — bash
Afin de vous assurer que tout fonctionne, lancez la commande mysqlad- min suivie des options suivantes :
– Le mot-clé status.
– L’option -p suivie de la variable d’environnement contenant le mot de passe (-p$MYSQL_ROOT_PASSWORD).
Ci-dessous la commande correspondante :
|| ŝ mysqladmin status -p$MYSQL_ROOT_PASSWORD
Ci-dessous un exemple de ce qui pourrait être renvoyé :
■ Uptime: 630 Threads: 7 … Queries per second avg: 0.001 Cette commande sera utilisée pour mettre en place la surveillance de l’état du pod (liveness et readiness).
2.5.3 Création de l’entrée de service
Pour la suite de l’exercice, il est nécessaire de disposer d’une entrée de service. Ci-dessous un exemple de déclaration permettant de gérer la connexion vers la base de données :
apiVersion: v1 kind: Service metadata: name: mariadb spec: ports: - port: 3306 targetPort: 3306 selector: app: mariadb
Sauvegardez la définition dans le fichier Mariadb-service.yaml puis appliquez-la auprès de l’API de Kubernetes:
$ kubectl apply -f service.yaml
Le service est maintenant disponible pour la suite de l’exercice.
2.6 Surveillance de la base de données
2.6.1 Définition des commandes de surveillance
Comme vu précédemment, il est possible de définir une surveillance sur un container en définissant les champs startup Probe, liveness Probe et
readiness Probe.
Ces champs seront identiques et contiendront tous la structure exec compo- sée d’un sous-champ command.
Le champ command sera un tableau contenant la commande à exécuter.
Remarque
La commande mysqladmin ne sera pas directement transposée dans le tableau. En effet, sous cette forme, l’appel à la variable d’environnement $MYSQL_ROOT_PASSWORD n’est pas interprété.
Afin d’interpréter le contenu de la variable, il est nécessaire de passer par un shell sh. Pour interpréter cette commande, ajoutez l’option -c suivie de la commande mysqladmin et de ses options.
☑En reprenant ces indications, ajoutez les champs suivants au container:
startupProbe: &probe
exec:
command:
"sh"
- "-c"
"mysqladmin status -p $MYSQL_ROOT_PASSWORD"
livenessProbe: *probe
readiness Probe: *probe
ENI - All rights reserved
MysqlAdmin n’est pas inclus dans image
Ci-dessous le contenu de l’ensemble du fichier suite à cette modification:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mariadb
name: mariadb
spec:
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
volumes:
-
name: mariadb-data
persistentVolumeClaim: { claimName: mariadb-data }
containers:
image: mariadb
name: mariadb
volumeMounts:
env:
mountPath: /var/lib/mysql
name:
exec:
command:
"sh"
- "-c"
mariadb-data
name: MYSQL_ROOT_PASSWORD value: mot-de-passe-root startup Probe: &probe
"mysqladmin status -p$MYSQL_ROOT_PASSWORD"
liveness Probe: *probe
readiness Probe: *probe
Sauvegardez cette définition dans le fichier mariadb-deployment.yaml
2.6.2 Application de la modification
■Appliquez la modification à l’aide de la commande suivante :
$ kubectl apply -f mariadb-deployment.yaml
La commande doit alors renvoyer la sortie suivante :
| deployment.apps/mariadb configured
2.6.3 Vérification du déploiement
►Afin de s’assurer que la modification est bien prise en compte, consultez les pods portant le label app-mariadb:
$ kubectl get pods -1 app=mariadb
La commande devrait renvoyer le résultat suivant :
NAME
mariadb-57667fb6f8-vrf6p
mariadb-754c8b696d-pnmq9
$ kubectl logs mariadb-754c8b696d-pnmq9
Le nouveau pod a démarré, mais n’est pas prêt. Ce dernier a même été suppri- mé et redémarré par le moteur Kubernetes.
Consultez les événements remontés par le moteur Kubernetes:
$ kubectl describe pods mariadb-754c8b696d-pnmq9
La section Events contient certains messages d’alerte (niveau Warning). Ci- dessous un exemple de contenu indiquant une erreur de lancement: Readiness probe failed; mysqladmin: connect to server at
1 (5s ago) 38s
error: ‘Can’t connect to local MySQL server through socket
‘/var/run/mysqld/mysqld.sock’ (2)’
Check that mysqld is running and that the socket: ‘/var/run/mysqld/mysqld.sock’ exists!
Afin de consulter le journal d’activité du pod, lancez la commande
Ci-dessous un exemple d’erreur remonté par MariaDB :
. [ERROR] InnoDB: Unable to lock ./ibdatal error: 11 [Note] InnoDB: Check that you do not already have another mysqld process using the same InnoDB data or log files. . [ERROR] InnoDB: Unable to lock ./ibdatal error: 11 . [Note] InnoDB: Check that you do not already have another mysqld process using the same InnoDB data or log files.
Le container n’arrive pas à démarrer en raison de la présence d’un lock dans les fichiers de base de données.
Ce lock s’explique parfaitement en raison du fait qu’un pod est déjà démarré et que ce dernier utilise déjà les fichiers présents.
2.7 Mécanisme de déploiement
Par défaut, si rien n’est spécifié, Kubernetes utilise un déploiement par roule- ment. Le principe de ce mécanisme est le suivant :
– Un nouveau pod est démarré en parallèle de l’ancien.
– Lorsque le nouveau pod est prêt, l’ancien pod est supprimé.
Dans le cas où plusieurs pods seraient démarrés, Kubernetes réalisera l’opéra- tion pod par pod jusqu’à remplacer complètement les anciens pods.
La plupart du temps, ce type de comportement est le bon puisque les temps d’indisponibilité sont ainsi réduits. Dans le cas présent, cette stratégie consti- tue un problème.
Le problème vient du fait qu’une base de données ne peut pas partager ses
Le changement de la cinématique de déploiement se fait en modifiant le champ deployment –> spec –> strategy –> type.
Ci-dessous le valeurs possibles:
-RollingUpdate : remplacement par vageur de pods existants (mécanisme par défault)
- Recreate : suppression des anciens pods avant recréation.
Ci-dessous un extrait de la déclaration du dépliement après ce changement de stratégies.
apiVersion: apps/v1 kind: Deployment metadata: generation: 1 labels: app: mariadb name: mariadb spec: strategy: type: Recreate selector: matchLabels: app: mariadb template: metadata: labels: app: mariadb
$ kubectl apply -f Mariadb…yaml
$ kubectl get pods -l app=mariadb –watch
Le nouveau container de la base de données a bien démarré.
3. Mise en place d’un StatefulSet
3.1 Augmentation du nombre de pods associés au déploiement
En informatique l’augmentation du nombre de lancements d’une même application permet de régler 2 types de problèmes:
-Augmentation de la résilience d’un système.
– Augmentation de la capacité de traitement d’un système
Kubernetes offrre un mécanisme permettant de la montée en charge automatique au niveau des déploiements.
Pour changer le nombre de pods associés à un déploiement, vous pouvez vous appuyersur la commande kubectl suivie des options suivantes:
– Le verbe scale.
– Le type d’objet à modifier (deployment)
– Le nom de l’objet à modifier (mariadb)
– Le nombre de replicas souhaité (–replicas=2)
Pour passer de 1 à 2 pods, l’opération pourra se faire avec la commande suivante:
$ kubectl scale deployment mariadb –replicas=2
Consultez l’état des pods de mariadb:
$ kubectl get pods -1 app=mariadb –watch
Ci-dessous les premières lignes renvoyées par cette commande :
NAME mariadb-6c758c6984-4pnjw mariadb-6c758c6984-czsbw mariadb-6c758c6984-4pnjw mariadb-6c758c6984-4pnjw mariadb-6c758c6984-4pnjw pas READY 0/1 1/1 0/1 STATUS Running RESTARTS AGE ContainerCreating 0 0 Au bout de quelques secondes, la ligne suivante doit apparaître : 0/1 0/1 Running Running Running Le nouveau pod n'arrive à démarrer. 0 1 2 1s 3m 4s Au bout d'environ 1 minute, les lignes suivantes doivent apparaître (une nou- velle toutes les minutes) : 65s 2m4s
Afin de comprendre ce qu’il se passe, consultez l’état du pod:
$ kubectl describe pods mariadb-6c758c6984-4pnjw
La section Events devrait contenir le message rencontré précédemment :
Readiness probe failed: mysqladmin: connect to server at ‘localhost’ failed
error: ‘Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)’
Afin d’affiner le diagnostic, consultez le journal du pod:
$ kubectl logs mariadb-6c758c6984-4pnjw
Ci-dessous un extrait des erreurs renvoyées :
[ERROR] InnoDB: Unable to lock ./ibdatal error: 11
. [Note] InnoDB: Check that you do not already have another mysqld
process using the same InnoDB data or log files.
3.2 Présentation du type StatefulSet
3.2.1 Caractéristiques
Le diagnostic est posé : le mécanisme de déploiement n’est pas adapté pour gérer un ensemble de pods de base de données. Pour cela, Kubernetes offre un autre mécanisme : les objets de type StatefulSet.
Un objet StatefulSet (ou son raccourci sts) dispose des caractéristiques
suivantes:
– Prédictibilité du nom des pods.
– Assignation du stockage persistant pod par pod.
– Création des pods dans un ordre donné.
– Mise à jour des pods dans un ordre donné.
Remarque
Si l’application à déployer n’a pas besoin de ces caractéristiques, il est recom- mandé de passer par un mécanisme de déploiement classique.
3.2.2 Limitations
Ce type n’était pas disponible avant la version 1.5 de Kubernetes et est resté en version bêta jusqu’à la version 1.9.
Il est fortement recommandé de disposer d’un mécanisme de création auto- matique des volumes persistants. Dans le cas contraire, l’administrateur devra réaliser toutes les déclarations d’objet de type PersistentVolume manuellement.
Derniers points, les volumes persistants créés par le StatefulSet ne seront pas purgés automatiquement lors de la réduction du nombre de pods. Charge à l’administrateur de faire les purges nécessaires.
Encore une fois, le problème est tout à fait normal puisqu’une base de données s’attend à avoir un accès exclusif à ses fichiers.
3.3 Déclaration du premier objet StatefulSet
3.3.1 Purge de l’ancien déploiement
Avant d’aller plus loin, purgez l’ancien déploiement de MariaDB:
$ kubectl delete deployment mariadb
La commande doit renvoyer le message suivant :
deployment.apps « mariadb » deleted
Vérifiez qu’aucun pod portant le label app=mariadb ne reste :
$ kubectl get pods -1 app=mariadb
Relancez la commande jusqu’à obtenir le message suivant:
No resources found in default namespace.
3.3.2 Modifications à réaliser
Reprenez le fichier mariadb-deployment.yaml et sauvegardez-le sous le nom de mariadb-statefulset.yaml.
Afin de transformer la déclaration de déploiement en StatefulSet, vous devrez réaliser plusieurs opérations:
– Changement du champ kind pour la valeur StatefulSet.
– Ajout d’un nom de service associé aux pods (champ serviceName à la
valeur mariadb).
Ajout d’un champ volumeClaimTemplates.
Le champ volumeClaimTemplates sera un tableau d’éléments. Chaque élément reprendra les caractéristiques d’un volume persistant, à savoir: – un champ metadata avec un champ name (à la valeur mariadb-data),
– un champ spec reprenant les caractéristiques suivantes :
– le mode d’accès souhaité (ReadWrite Once),
– la taille du stockage.
En reprenant ces informations, la déclaration devrait correspondre au contenu
suivant:
apiVersion: apps/v1 kind: StatefulSet metadata: name: mariadb spec: serviceName: "mariadb" replicas: 1 # Ajustez selon vos besoins selector: matchLabels: app: mariadb template: metadata: labels: app: mariadb spec: containers: - name: mariadb image: mariadb:latest # Remplacez par la version souhaitée ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "my-secret-pw" # Remplacez par le mot de passe souhaité volumeMounts: - name: mariadb-storage mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: mariadb-storage spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi # Ajustez la taille selon vos besoins
3.3.3 Création du StatefulSet
Sauvegardez cette définition dans le fichier mariadb-statefulset.yaml et
appliquez-la :
$ kubectl apply -f Mariadb-statefulset.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE mariadb-0 1/1 Running 1 5d23h mariadb-1 1/1 Running 1 5d23h
3.3.4 Etat des volumes persistents
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mariadb-storage-mariadb-0 Bound pvc-96b25c57-42b9-4b86-9af3-e88532020e78 1Gi RWO standard 5d23h mariadb-storage-mariadb-1 Bound pvc-ecf0e6c1-4186-483e-a5ae-6ad942c5176a 1Gi RWO standard 5
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE mariadb-pv 10Gi RWO Retain Available 6d2h pvc-96b25c57-42b9-4b86-9af3-e88532020e78 1Gi RWO Delete Bound default/mariadb-storage-mariadb-0 standard 5d23h pvc-ecf0e6c1-4186-483e-a5ae-6ad942c5176a 1Gi RWO Delete Bound default/mariadb-storage-mariadb-1 standard 5d23h
3.3.5 Suppression des anciens objets PV/PVC
L’ancien volume persistent ne nous servira plus. Supprimez -le à l’aide de la commande suivants:
$ kubectl delete pvc/pvc-mariadb
3.4 Scalabilité de l’objet StatefulSet
Tout comme pour un déploiement, Kubernetes peut augmenter le nombre de pods associés à un objet StatefulSet.
La commande kubectl a besoin pour cela des options suivantes :
– Le type d’objet (statefulset ou le raccourci sts).
Le nom de l’objet StatefulSet (mariadb).
Le nombre de réplicats à obtenir (avec l’option -replicas).
Afin de démarrer deux pods dans le ReplicaSet de MariaDB, lancez la com-
$ kubectl scale sts mariadb –replicas=2
Ci-dessous le résultat que devrait
statefulset.apps/mariadb scaled
3.5 Pods et volumes persistants d’un objet StatefulSet
La consultation des demandes de volumes persistants se fait à l’aide de la com-
mande suivante :
$ kubectl get pvc -1 app=mariadb
Pour la consultation des pods, la commande est la suivante :
$ kubectl get pods -1 app=mariadb
Le verbe get de la commande kubectl supporte la consultation de deux types d’objets en même temps.
►Pour cela, séparez les types par des virgules et conservez la sélection à l’aide de labels.
Pour consulter les pods et les PVC portant le label app-mariadb en mêm temps, utilisez la commande suivante :
$ kubectl get pods, pvc -1 app=mariadb
NAME READY STATUS RESTARTS AGE pod/mariadb-0 1/1 Running 1 6d pod/mariadb-1 1/1 Running 1 5d23h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/mariadb-storage-mariadb-0 Bound pvc-96b25c57-42b9-4b86-9af3-e88532020e78 1Gi RWO standard 6d persistentvolumeclaim/mariadb-storage-mariadb-1 Bound pvc-ecf0e6c1-4186-483e-a5ae-6ad942c5176a 1Gi RWO standard 5d23h
Chaque objet sera précédé par son type suivi d’un slash (/). Ici, chaque pod dispose de son propre volume persistant.
3.6 Réduction de la taille du StatefulSet
La diminution du nombre de pods d’un objet StatefulSet se fait avec Toption scale de la commande kubect1. La seule chose à changer sera la va- leur de l’option –replicas.
Pour passer de deux pods à un seul sur le StatefulSet de MariaDB, lancez la commande suivante :
$ kubectl scale sts mariadb –replicas=1
statefulset.apps/mariadb scaled
Lancez la commande de consultation précédente afin de connaître l’état des pods et des demandes de volumes persistants.
Ci-dessous l’état renvoyé par la commande :
Le pod mariadb-1 a disparu. En revanche, la demande de volume persistant associée est toujours présente.
Ce comportement est intéressant puisqu’il permettra de conserver les données d’un pod faisant partie d’un ensemble StatefulSet.
Attention toutefois lors du démarrage d’un pod, il sera peut-être nécessaire de esynchroniser le contenu des bases avant de mettre à disposition le pod.
4. Base et compte de test
4.1 Variables d’environnement du container
Pour la suite de l’exercice, afin de tester la réplication, une base et un compte
de test vont être créés.
L’image Docker de MariaDB supporte ce type d’opérations. Pour les réaliser. elle s’appuie sur le contenu des variables suivantes :
– MYSQL DATABASE: nom de la base de données.
– MYSQL_USER: nom de l’utilisateur de base de données.
– MYSQL_PASSWORD : mot de passe de l’utilisateur.
Ces variables se déclarent au niveau du champ env du container mariadb. Ci-dessous l’extrait de configuration à ajouter :
env:
– name: MYSQL_ROOT_PASSWORD
value: mot-de-passe-root
name: MYSQL_DATABASE
value: test
name: MYSQL_USER
value: test
name: MYSQL_PASSWORD
value: test
4.2 ConfigMap et secret
4.2.1 Pourquoi y faire appel?
Le nombre de variables est encore petit. Toutefois, il devient intéressant de commencer à stocker ces éléments dans des emplacements plus appropriés :
les ConfigMaps et les secrets.
241
Hebergement d’application en cluster_
Chapitre 7
4.2.2 Structure d’un objet ConfigMap
Les objets ConfigMap (ou cm) sont des objets assez simples. Ci-dessous la
structure minimum :
– Le champ apiVersion et kind.
l’objet ConfigMap).
MYSQL DATABASE: test
MYSQL_USER:
$ kubectl apply -f configmap.yaml
La commande doit alors renvoyer le message suivant:
configmap/mariadb created
4.2.3 Déclaration d’un objet Secret
241
– le champ metadata constitué du champ name (contenant le nom de
– Le champ data avec les variables d’environnement à déclarer.
Pour l’exercice, l’objet ConfigMap portera le nom mariadb. Il stockera les informations suivantes :
– Le nom de la base de données (champ MYSQL_DATABASE).
– Le nom de l’utilisateur (champ MYSQL_USER).
En reprenant ces différentes indications, la déclaration devrait être la
suivante :
apiVersion: vl
kind: ConfigMap metadata:
name: mariadb
data:
test
Stockez cette déclaration dans le fichier configmap.yaml et appliquez-la :
La structure d’un objet Secret est la même qu’un objet ConfigMap. La seule différence sera sur le contenu des variables du champ data: ces valeurs devront être stockées au format base 64.
242
Kubernetes
Plateforme de déploiement de vos applications conteneurisées Pour obtenir les valeurs en base 64, vous pourrez faire appel à la commande base64 sous Linux. Le passage de la valeur à traiter se fait à l’aide d’un pipe
précédé par la commande printf ou echo
base 64.
Remarque
-n suivie du texte à passer en
Il est important de ne pas utiliser la commande echo seule. En effet, cette commande renvoie toujours un retour chariot ( ) en plus de la chaîne de co- ractères. Ce retour chariot est pris comme les autres caractères de la chaîne, ce qui peut parfois amener à certains comportements inattendus.
■ Pour transformer la chaîne de caractères « test » en base 64, lancez la com- mande suivante :
$ echo -n test | base64
Cette commande doit alors renvoyer le résultat suivant :
dGVzdA==
C’est cette valeur qui sera utilisée dans le champ MYSQL_PASSWORD. La valeur en base 64 de la chaîne « mot-de-passe-root » sera la suivante :
bW90LWRlLXBhc3N1LXJvb3Q=
Cette valeur sera stockée dans le champ MYSQL_ROOT_PASSWORD. En reprenant ces indications, vous obtiendrez le résultat suivant:
apiVersion: vl
kind: Secret
metadata:
name: mariadb
data:
MYSQL_ROOT_PASSWORD: « bW90LWRlLXBhc3N1LXJvb3Q= »
MYSQL PASSWORD:
Une technique alternative est de passer par le champ stringData. Lors qu’une valeur s’y trouve, Kubernetes se charge automatiquement
« dGVzdA== »
conversion dans le champ data.
de faire la
243
Hébergement d’application en cluster-
Chapitre 7
Ci-dessous la déclaration correspondante :
apiVersion: vl
kind: Secret metadata:
name: mariadb
stringData:
MYSQL ROOT PASSWORD: « mot-de-passe-root »
MYSQL_PASSWORD:
« test »
243
■ Stockez cette déclaration dans le fichier secret.yaml et appliquez celui-ci :
$ kubectl apply -f secret.yaml
Cette commande doit alors
secret/mariadb created
renvoyer le message suivant :
.4 Rattachement au container
Les deux objets sont prêts. Le référencement se fera depuis la structure du container à l’aide du champ envFrom. Ce champ est un tableau de structures. Ces structures sont des objets config MapRef ou secretRef. Les deux types de structures contiennent le champ name avec le nom de l’objet à réfé-
rencer.
Pour référencer l’objet ConfigMap mariadb et l’objet Secret mariadb, la déclaration du champ envFrom prendra la forme suivante :
envFrom:
config MapRef: { name: mariadb }
secretRef:
{ name: mariadb }
En reprenant l’ancienne déclaration, la structure de l’objet StatefulSet
sera la suivante :
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
labels:
app: mariadb
spec:
serviceName: mariadb
244.
Kubernetes
Plateforme de déploiement de vos applications conteneurisées
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
quez-le :
containers:
image: mariadb
name: mariadb
spec:
volumeMounts:
mount Path: /var/lib/mysql
name:
envFrom:
mariadb-data
configMapRef: { name: mariadb }
secretRef:
exec:
command:
« sh »
« -C »
resources:
requests:
storage: 100Mi
{ name: mariadb }
startup Probe: &probe
« mysqladmin status -p$MYSQL_ROOT_PASSWORD »
liveness Probe: *probe
readiness Probe: *probe
volumeClaimTemplates:
metadata:
name: mariadb-data
accessModes: [ « ReadWrite Once » ]
Sauvegardez ce contenu dans le fichier mariadb-statefulset.yaml et appli
$ kubectl apply -f mariadb-statefulset.yaml
Ci-dessous le message renvoyé :
statefulset, apps/mariadb configured
La base est maintenant configurée automatiquement à l’aide de ces éléments de configuration externes. Ce découpage simplifiera les modifications ultérieures sur les variables d’environnement.
Chapitre 9
Gestion du chapitre et prérequis
de Kubernetes
1. Objectifs du chapitre et du prérequis
Les chapitres précédents ont abordé les différents types d’objets initiales dans kubernetes de déploiement au volume persistent.
Ce chapitre sera consacré à l’étude des éléments système d’un cluster Kubernetes parmi lesquels l’espace de noms kube-system.
2. Espace des noms kube-system
2.1 Pods présents dans l’espace de noms kube-system
Le classement des éléments dans Kubernetes se fait à l’aide des espaces des noms (namespace). Dans le cas des éléments systèmes du cluster, ces derniers sont hébergés dans l’espace des noms kube-system.
> Récupération des pods de l’espace de noms kube-system:
$ kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE coredns-6d4b75cb6d-cp7st 1/1 Running 16 59d etcd-minikube 1/1 Running 333 59d kindnet-gfc94 1/1 Running 174 59d kube-apiserver-minikube 1/1 Running 329 59d kube-controller-manager-minikube 1/1 Running 328 (3m37s ago) 59d kube-proxy-248nb 1/1 Running 8 59d kube-scheduler-minikube 1/1 Running 322 59d metrics-server-8cf8b7f65-9b5v2 1/1 Running 444 58d storage-provisioner 1/1 Running 1628 (2m1s ago) 59d
Cette sortie regroupe des éléments du cluster. Ony trouve :
- Un gestionnaire des noms NOMS interne (coredns)
- un serveur etcd
- le pilote de réseau kindnet,
- le serveur d’API,
- le controler manager,
- le proxy de l’API Kubernetes,
- le gestionnaire des tâches/orchestrateur de Kubernetes.
- le gestionnaire de métriques de suivi de consomation des éléments du cluster (metrics server, optionnel),
- le gestionnaire de persistance des données (optionnel).
2.2 CoreDNS
CoreDNS est un serveur interne de Kubernetes. Il permet de gérer les résolutions de nom des services définies dans le cluster.
A noter que, par défaut, il remplace Kube-dns depuis la version 1.11. Certains clusters plus récents peuvent toujours y faire appel. Toutefois, cette différence ne devrait pas être perceptible pour la plupart des utilisateurs.
2.3 etcd
etcd est une autre brique importante. Il s’agit d’une base de données de type NoSQL. Elle permet le stokage des données au format clé/valeur. C’est elle qui va servir à la persistence des éléments dans le cluster Kubernetes.
Dans Kubernetes, cet élément peut être hébergé comme un pod ou un service externe. Cette différence se fait en fonction du mode d’installation du cluster.
Dans le cas de Minikube, le serveur tourne comme un pod.
> Remarque
A noter que les clusters créés avec k3s font apple à SQLite pour stocker les informations du cluster.
2.4 Le gestionnaire de réseau Kindnet.
Ce composant gère la communication réseau entre les pods dans Minikube. (pilote CNI pour Container Network Interface). Il s’agit d’un composant développé initialement pour le projet Kind (Kubernetes in Docker).
2.5 Le gestionnaire d’extensions de Minikube
Ce pod n’est présent que dans le cas de Minikube. Ce dernern

































