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

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 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 !

 

 

####################################################################

 

 

 

 

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/bin
    and also from /home/$USER/.local/bin
    And 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