Kubernetes — Documentation complète¶
Un conteneur, c'est simple. Cent conteneurs répartis sur plusieurs machines, qui doivent se parler, se relancer tout seuls quand ils tombent, monter en charge le vendredi soir et redescendre le lundi matin : là, il faut un chef d'orchestre. Kubernetes est ce chef d'orchestre — le standard de fait pour faire tourner des applications conteneurisées à l'échelle, sans supplier chaque nuit qu'aucune machine ne tombe.
Cette page rassemble l'essentiel en une documentation continue : des concepts de base jusqu'à l'administration avancée, chaque notion étant suivie d'une mise en pratique concrète. À parcourir de haut en bas pour apprendre, ou à picorer via le sommaire pour retrouver un exemple.
Présentation¶
Table des Matières¶
Introduction à Kubernetes¶
Pourquoi Kubernetes ?¶
Kubernetes est une plateforme open-source qui automatise : - Le déploiement d'applications conteneurisées - La mise à l'échelle (scaling) - La gestion des applications distribuées
Avantages principaux : - Haute disponibilité - Scalabilité automatique - Gestion simplifiée des applications complexes
Objectifs de cette documentation¶
- Comprendre les concepts fondamentaux
- Installer un cluster Kubernetes
- Déployer et gérer des applications
- Pratiquer avec des exercices concrets
Concepts Clés¶
Architecture du Cluster¶
- Nœud Maître (Master) : Orchestre le cluster (API Server, Scheduler, Controller Manager)
- Nœuds Travailleurs (Workers) : Exécutent les applications (kubelet, kube-proxy)
Composants Principaux¶
| Composant | Description |
|---|---|
| Pod | Plus petite unité exécutable (1+ conteneurs) |
| Deployment | Gère le cycle de vie des applications |
| Service | Point d'accès réseau stable aux Pods |
| ConfigMap/Secret | Gestion de configuration et données sensibles |
| Ingress | Routeur HTTP pour accès externe |
| PersistentVolume | Stockage persistant pour les données |
Prérequis¶
Configuration Matérielle¶
| Rôle | CPU | RAM | Stockage |
|---|---|---|---|
| Master | 2 cœurs | 2GB | 20GB |
| Worker | 1 cœur/Pod | 1GB/Pod | Variable |
Configuration Logicielle¶
- Runtime conteneur (Docker, containerd)
- Kubernetes v1.25+
- Swap désactivé (
sudo swapoff -a)
Configuration Réseau¶
- Ports ouverts : 6443 (API), 10250 (kubelet)
- Connectivité entre tous les nœuds
Installation¶
Étapes d'Installation avec kubeadm¶
-
Préparation du système :
sudo apt update && sudo apt upgrade -y -
Installation des dépendances :
sudo apt install -y apt-transport-https curl gnupg -
Ajout du dépôt Kubernetes :
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list -
Installation des composants :
sudo apt update sudo apt install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl -
Initialisation du cluster :
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 -
Configuration du réseau :
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml -
Ajout des workers :
kubeadm join <MASTER_IP>:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>
Usage Basique¶
Commandes Essentielles¶
| Commande | Description |
|---|---|
kubectl apply -f fichier.yaml |
Déploie une ressource |
kubectl get pods |
Liste les Pods |
kubectl describe pod <nom> |
Affiche les détails d'un Pod |
kubectl logs <pod> |
Affiche les logs |
kubectl exec -it <pod> -- bash |
Ouvre un shell dans un Pod |
Exemple de Déploiement¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Bonnes Pratiques¶
- Un conteneur par Pod en général
- Utiliser des labels cohérents
- Configurer des probes (liveness/readiness)
- Gérer les secrets avec l'objet Secret
Mise en pratique — Pods et sondes¶
Créer un Pod avec une sonde de vie (livenessProbe)¶
Créer un Pod qui simule une application simple avec un fichier de "santé" (/tmp/healthy), surveillé par une sonde de vie (livenessProbe).
Cette sonde vérifiera si le fichier existe ; s’il est supprimé, Kubernetes redémarrera automatiquement le conteneur.
Contexte
- Utiliser l’image busybox
- Lancer le Pod dans un cluster Kubernetes déjà opérationnel (Minikube ou cluster distant)
- Utiliser kubectl apply -f pod-liveness.yaml pour le déploiement
Ce que met en place le manifeste
1. Créer un fichier YAML nommé pod-liveness.yaml
2. Définir un Pod avec :
- Un conteneur basé sur busybox
- Une commande shell qui crée un fichier /tmp/healthy, le supprime après 30s, puis dort
- Une livenessProbe qui vérifie ce fichier toutes les 5 secondes
3. Déployer le Pod avec kubectl apply -f pod-liveness.yaml
4. Observer le redémarrage automatique du Pod avec :
kubectl describe pod <nom>
kubectl get pod <nom> -w
Observer le comportement * Pour voir les événements et vérifier la sonde :
kubectl describe pod pod-liveness
- Pour surveiller l’état du Pod en temps réel :
kubectl get pod pod-liveness -w
Manifeste :
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness
labels:
app: pod-liveness
spec:
restartPolicy: OnFailure
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- |
touch /tmp/healthy
sleep 30
rm -rf /tmp/healthy
sleep 600
resources:
requests:
memory: "32Mi"
cpu: "128m"
limits:
memory: "64Mi"
cpu: "256m"
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Init Container +¶
Volume partagé
Comprendre le fonctionnement des initContainers et le partage de volume entre initContainer et conteneur principal.
Contexte
* Init container : prépare les données (copie de fichiers) dans un volume partagé emptyDir
* Conteneur principal : utilise ces fichiers pour démarrer l’application
Ce que met en place le manifeste 1. Créer un Pod avec :
- Un initContainer qui crée un fichier dans
/mnt - Un volume
emptyDirpartagé avec le conteneur principal - Déployer et vérifie que le conteneur principal peut lire ce fichier
Observer le comportement * Pour voir les logs de l’init container :
kubectl logs <nom-pod> -c <nom-init-container>
- Pour décrire le pod et vérifier les volumes montés :
kubectl describe pod <nom-pod>
Manifeste :
apiVersion: v1
kind: Pod
metadata:
name: pod-init-demo
spec:
volumes:
- name: shared-data
emptyDir: {}
initContainers:
- name: init-container
image: busybox
command:
- /bin/sh
- -c
- echo "Hello from init container" > /mnt/message.txt
volumeMounts:
- name: shared-data
mountPath: /mnt
containers:
- name: main-container
image: busybox
command:
- /bin/sh
- -c
- cat /mnt/message.txt && sleep 3600
volumeMounts:
- name: shared-data
mountPath: /mnt
Déploiements et Scaling¶
Table des Matières¶
- Déploiements (Deployments)
- Définition et Structure
- Cas d'Usage
- Scaling des Applications
- ReplicaSets
- Horizontal Pod Autoscaling (HPA)
- Stratégies de Déploiement
- Rolling Update
- Canary
- Blue-Green
- Commandes Utiles
Déploiements¶
Définition et Structure¶
Un Deployment Kubernetes permet de gérer des Pods et ReplicaSets en déclarant un état désiré. Kubernetes maintient automatiquement cet état.
Exemple de Deployment :
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.23.3
Points clés :
- Les labels (metadata, selector, template) doivent être cohérents
- replicas définit le nombre de pods souhaités
- template décrit les pods à créer
Cas d'Usage¶
- Mise à l'échelle : Augmenter/diminuer le nombre de pods
- Historique : Gestion des versions et rollback
- Mises à jour : Déploiement sans interruption
- Auto-réparation : Redémarrage automatique des pods défaillants
Scaling¶
ReplicaSets¶
Un ReplicaSet maintient un nombre stable de pods identiques.
Exemple :
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
Préférer les Deployments qui offrent plus de fonctionnalités
Horizontal Pod Autoscaling¶
L'HPA ajuste automatiquement le nombre de pods basé sur l'utilisation des ressources.
Exemple HPA :
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: frontend-scaler
spec:
scaleTargetRef:
kind: ReplicaSet
name: frontend
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Prérequis : - Serveur de métriques installé (Metrics Server) - Demandes de ressources définies dans les pods
Stratégies de Déploiement¶
Rolling Update (par défaut)¶
Mise à jour progressive pod par pod pour éviter les interruptions.
Commande :
kubectl set image deployment/nginx-deployment nginx=nginx:1.23.3
Canary¶
Déploie la nouvelle version sur un sous-ensemble de pods (ex: 20%) pour tester avant déploiement complet.
Blue-Green¶
- Deux environnements complets (blue = actuel, green = nouveau)
- Basculement instantané du trafic une fois la nouvelle version validée
Commandes Utiles¶
| Commande | Description |
|---|---|
kubectl apply -f deployment.yml |
Créer/mettre à jour un déploiement |
kubectl set image deployment/<name> <container>=<image> |
Mettre à jour l'image d'un conteneur |
kubectl scale deployment/<name> --replicas=<n> |
Modifier le nombre de réplicas |
kubectl rollout status deployment/<name> |
Suivre l'état du déploiement |
kubectl rollout history deployment/<name> |
Voir l'historique des versions |
kubectl rollout undo deployment/<name> --to-revision=<n> |
Revenir à une version antérieure |
kubectl rollout restart deployment/<name> |
Redémarrer tous les pods |
Bonnes Pratiques : - Toujours utiliser des Deployments plutôt que des ReplicaSets directement - Définir des probes (liveness/readiness) pour une meilleure gestion des pods - Utiliser des stratégies de déploiement adaptées à votre application
Mise en pratique — Déploiements et scaling¶
Créer un Deployment (replicas, labels, image)¶
Un Deployment avec :
- 2 replicas
- label
app: nginx-deploy - image
nginx:1.26.1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- name: nginx
image: nginx:1.26.1
Mettre à jour l’image nginx en version 1.27.0 :
Manifeste :
kubectl set image deployment/nginx-deploy nginx=nginx:1.27.0
Augmenter le nombre de replicas à 3 :
Manifeste :
kubectl scale deployment/nginx-deploy --replicas=3
Suivre le déploiement :
Manifeste :
kubectl rollout status deployment/nginx-deploy
Voir l’historique des déploiements et revenir à la première version (replicas 2) :
Manifeste :
kubectl rollout history deployment/nginx-deploy
kubectl rollout undo deployment/nginx-deploy --to-revision=1
Services et connectivité¶
Table des Matières¶
- Introduction aux Services
- Résolution DNS dans Kubernetes
- Types de Services
- ClusterIP
- NodePort
- LoadBalancer
- ExternalName
- Services Avancés
- Services sans Selector
- Ingress
- Outils de Débogage
- Architecture Globale
Introduction aux Services¶
Les Services dans Kubernetes fournissent une abstraction pour exposer une application exécutée sur un ensemble de Pods en tant que service réseau. Ils offrent :
- Stabilité : Une IP et un nom DNS persistants même lorsque les Pods changent
- Découverte de service : Mécanisme intégré pour localiser les services
- Équilibrage de charge : Répartition du trafic entre les Pods sains
Résolution DNS dans Kubernetes¶
Kubernetes déploie automatiquement un service DNS (CoreDNS) qui permet la résolution des noms de services :
- Même namespace :
<service-name> - Autre namespace :
<service-name>.<namespace-name> - FQDN complet :
<service-name>.<namespace-name>.svc.cluster.local
Exemple pour un service db dans le namespace production :
- Dans le même namespace : db
- Depuis un autre namespace : db.production
Types de Services¶
ClusterIP¶
Type par défaut - accessible uniquement depuis l'intérieur du cluster.
apiVersion: v1
kind: Service
metadata:
name: internal-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
NodePort¶
Expose le service sur un port statique de chaque nœud (plage 30000-32767 par défaut).
apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 31000
LoadBalancer¶
Crée un équilibreur de charge externe (cloud providers).
apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
ExternalName¶
Mappe un service à un nom DNS externe.
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: my.database.example.com
Services Avancés¶
Services sans Selector¶
Pour pointer vers des endpoints externes au cluster :
Service :
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
Endpoints :
apiVersion: v1
kind: Endpoints
metadata:
name: external-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376
Ingress¶
Gère l'accès HTTP/HTTPS aux services :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Outils de Débogage¶
Port Forwarding (accès direct à un Pod) :
kubectl port-forward pod/mon-pod 8080:8080
Vérification des Endpoints :
kubectl get endpoints <service-name>
Test DNS :
kubectl run -it --rm --image=busybox:1.28 dns-test -- nslookup <service-name>
Architecture Globale¶
+---------------------+
| Cluster DNS |
+----------+----------+
|
+----------v----------+
| Service IP |
+----------+----------+
|
+-----------+----------+--------------+
| ClusterIP | NodePort | LoadBalancer |
+-----------+----------+--------------+
|
+----------v----------+
| Endpoints |
+----------+----------+
|
+----------v----------+
| Pods |
+---------------------+
Mise en pratique — Services¶
Exposer un Pod avec un Service (ClusterIP)¶
Un Pod qui utilise l'image nginx:latest avec le port 80 en écoute.
Créer ensuite un service qui écouté sur le port 7354 à l'intérieur du cluster.
Lancez un pod curl pour valider le bon fonctionnement
kubectl run curlpod --image=curlimages/curl -i --tty --rm -- sh
Puis executez la commande suivante sur le pod.
curl <adresse-dns>:<port>
Manifeste :
apiVersion: v1
kind: Pod
metadata:
name: pod-nginx
labels:
app: webapp
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 7354 # Port sur lequel le Service écoute
targetPort: 80 # Port sur le Pod cible
type: ClusterIP
curl nginx-service:7354
VOIR SI L'INGRESS PEUT MARCHER
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80
Gestion des Volumes et Stockage Persistant¶
Table des Matières¶
- Les Volumes
- emptyDir
- hostPath
- Persistent Volumes et Persistent Volume Claims
- Stateful vs Stateless Applications
- StatefulSets
- StorageClass
Les Volumes¶
Quoi ?¶
Les fichiers dans un conteneur sont éphémères par défaut, ce qui pose deux problèmes principaux : - Perte de données lors du redémarrage d'un conteneur. - Partage de fichiers nécessaire entre plusieurs conteneurs dans un Pod.
Les volumes Kubernetes résolvent ces problèmes. Deux types courants sont emptyDir et hostPath.
emptyDir¶
Un volume emptyDir est initialement vide et partagé entre les conteneurs d'un Pod.
Exemple¶
apiVersion: v1
kind: Pod
metadata:
name: production
spec:
containers:
- name: container1
image: image1
volumeMounts:
- name: storage
mountPath: /vol/data
- name: container2
image: image2
volumeMounts:
- name: storage
mountPath: /store/data
volumes:
- name: storage
emptyDir: {}
- Un volume
emptyDir nommé storage est monté dans /vol/data pour container1 et /store/data pour container2.
hostPath¶
Un volume hostPath monte un fichier/dossier du système hôte dans un Pod.
Options¶
DirectoryOrCreate: Crée un dossier si inexistant (permissions :0755).FileOrCreate: Crée un fichier si inexistant (permissions :0644).- Autres options :
Directory,File,Socket,CharDevice,BlockDevice.
Exemple¶
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: nginx
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
- Monte un dossier (
/var/local/aaa) et un fichier (1.txt) depuis l'hôte.
Persistent Volumes et Persistent Volume Claims¶
Quoi ?¶
Les PersistentVolumes (PV) et PersistentVolumeClaims (PVC) permettent d'utiliser un stockage externe au cluster.
- PV : Ressource de stockage physique/logique (ex : NFS, EBS).
- PVC : Demande de stockage par un utilisateur (taille, mode d'accès).
Modes d'accès¶
ReadWriteOnce (RWO): Montage en lecture/écriture par un seul nœud.ReadOnlyMany (ROX): Montage en lecture seule par plusieurs nœuds.ReadWriteMany (RWX): Montage en lecture/écriture par plusieurs nœuds.
Exemple¶
# PersistentVolume
kind: PersistentVolume
apiVersion: v1
metadata:
name: access-log-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /var/log/syslog
type: DirectoryOrCreate
# PersistentVolumeClaim
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: access-log-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
# Pod utilisant le PVC
kind: Pod
apiVersion: v1
metadata:
name: test
spec:
volumes:
- name: access-log-pvc-vol
persistentVolumeClaim:
claimName: access-log-pvc
containers:
- name: proxy
image: nginx
volumeMounts:
- mountPath: "/nginx/"
name: access-log-pvc-vol
- Un PV de 1 Go est créé, puis un PVC de 500 Mo. Le Pod monte le PVC dans
/nginx/.
Stateful vs stateless applications¶
Stateless¶
- Pas de persistance : Chaque requête est indépendante.
- Exemples : Services REST, proxies.
Stateful¶
- Persistance des données : Bases de données, caches.
- Géré via
StatefulSets.
StatefulSets¶
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
- Créer 3 pods avec un PVC par pod (
volumeClaimTemplates).
- Résolution DNS : web-0.nginx, web-1.nginx, etc.
StorageClass¶
Quoi ?¶
Une StorageClass définit des classes de stockage pour un provisionnement dynamique.
Exemple (vSphere)¶
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: vsphere-ssd
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: thin
datastore: "MyDatastore1"
type: ssd
Exemple (AWS EBS)¶
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: aws-ebs
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
zone: eu-west-3
- Définit une classe de stockage SSD sur AWS (
gp2) dans la zone eu-west-3.
Résumé¶
- Volumes :
emptyDir(éphémère),hostPath(hôte). - PV/PVC : Stockage persistant externe.
- StatefulSets : Pour applications avec état.
- StorageClass : Provisionnement dynamique de stockage.
Mise en pratique — Stockage¶
Partager un volume entre conteneurs (emptyDir)¶
Un manifeste contenant deux pods avec une image busybox.
Ajoutez la commande command: ["sh", "-c", "while true; do echo container2; sleep 3600; done"]
Créez un volume vide nommé storage, sur le container1 il est monté dans /vol/data et sur le container2 il est monté dans /store/data
Manifeste :
apiVersion: v1
kind: Pod
metadata:
name: pod-shared-volume
spec:
containers:
- name: container1
image: busybox
command: ["sh", "-c", "while true; do echo container1; sleep 3600; done"]
volumeMounts:
- name: storage
mountPath: /vol/data
- name: container2
image: busybox
command: ["sh", "-c", "while true; do echo container2; sleep 3600; done"]
volumeMounts:
- name: storage
mountPath: /store/data
volumes:
- name: storage
emptyDir: {}
Utiliser plusieurs volumes dans un Pod¶
Un pod qui utilise deux volumes :
- un pour créer un fichier (nommé myfile)
- un pour créer un dossier (nommé mydir).
Le dossier sera créer dans /var/local/folder et le fichier dans /var/local/folder/1.txt.
Vérifiez la présence du fichier et du dossier.
Manifeste :
apiVersion: v1
kind: Pod
metadata:
name: pod-two-volumes
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "while true; do echo container2; sleep 3600; done"]
volumeMounts:
- mountPath: /var/local/folder
name: mydir
- mountPath: /var/local/folder/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
path: /var/local/folder
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/folder/1.txt
type: FileOrCreate
kubectl exec -it pod-two-volumes -c app -- sh
exercice bonus¶
Créez un PV de 1Go qui a pour path /mnt/data, il doit être monté en lecture et écriture par un seul noeud à la fois.
Créer un PVC qui utilise un 1Go du PV, il doit être monté en lecture et écriture par un seul noeud à la fois.
Créer un statefulset avec son service.
Le port exposé dans le service sera le port: 27017
Le conteneur doit utiliser l'image mongo:4.4, il aura 2 replicas. Le PVC sur le chemin /data/db et il doit utiliser tout le stockage défini au dessus.
Manifeste :
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongo-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html
volumes:
- name: storage
persistentVolumeClaim:
claimName: mongo-pvc
RBAC et Service Accounts¶
Table des Matières¶
- RBAC (Role-Based Access Control)
- Rôles et ClusterRoles
- RoleBindings et ClusterRoleBindings
- Service Accounts
- Création et Utilisation
- Comportement par Défaut
RBAC (Role-Based Access Control)¶
Quoi ?¶
Le RBAC (Contrôle d'Accès Basé sur les Rôles) permet de gérer finement les permissions des utilisateurs et des Service Accounts sur un cluster Kubernetes. Il permet par exemple d'autoriser la lecture des logs d'un Pod tout en interdisant sa modification.
Rôles et ClusterRoles¶
Role (Namespace-scopé)¶
Définit des permissions limitées à un namespace.
Commande :
kubectl create role pod-lecture --verb=get,list,watch --resource=pods,pods/logs
Manifeste YAML :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-lecture
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "watch", "list"]
ClusterRole (Cluster-scopé)¶
Définit des permissions sur tout le cluster.
Commande :
kubectl create clusterrole pod-lecture --verb=watch,list,get --resource=pods,pods/log
Manifeste YAML :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-lecture
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "watch", "list"]
RoleBindings et ClusterRoleBindings¶
RoleBinding¶
Lie un Role à un utilisateur/Service Account dans un namespace.
Commande :
kubectl create rolebinding pod-lecture --user=dev --role=pod-lecture
Manifeste YAML :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: pod-lecture
subjects:
- kind: User
name: dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-lecture
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding¶
Lie un ClusterRole à un utilisateur/Service Account pour tout le cluster.
Commande :
kubectl create clusterrolebinding pod-lecture --user=dev --clusterrole=pod-lecture
Manifeste YAML :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pod-lecture
subjects:
- kind: User
name: dev
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-lecture
apiGroup: rbac.authorization.k8s.io
Service Accounts¶
Quoi ?¶
Un Service Account est un compte utilisé par les conteneurs pour interagir avec l'API Kubernetes. Il est associé à des permissions via RBAC (RoleBinding/ClusterRoleBinding).
Création et Utilisation¶
Commande :
kubectl create serviceaccount mon-serviceaccount
Manifeste YAML :
apiVersion: v1
kind: ServiceAccount
metadata:
name: mon-serviceaccount
Exemple de RoleBinding pour un Service Account :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: pod-lecture
subjects:
- kind: ServiceAccount
name: mon-serviceaccount
namespace: default
roleRef:
kind: Role
name: pod-lecture
apiGroup: rbac.authorization.k8s.io
Comportement par Défaut¶
- Par défaut, un Pod utilise le Service Account
default. - Un token d'accès est automatiquement monté dans :
/var/run/secrets/kubernetes.io/serviceaccount/token - Désactiver cette fonctionnalité :
Ou directement sur un Pod :
apiVersion: v1 kind: ServiceAccount metadata: name: build-robot automountServiceAccountToken: false # Désactive le montage automatiqueapiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: build-robot automountServiceAccountToken: false # Désactive pour ce Pod
Récapitulatif¶
| Objet RBAC | Portée | Lien avec |
|---|---|---|
| Role | Namespace | Utilisateurs/Service Accounts (via RoleBinding) |
| ClusterRole | Cluster | Utilisateurs/Service Accounts (via ClusterRoleBinding) |
| ServiceAccount | Pods | Permissions via RBAC |
Mise en pratique — RBAC¶
Créer un ServiceAccount et un Role (lecture des pods)¶
Un ServiceAccount associé à un Role qui lui permet de faire les 3 actions de lectures des pods, unqiuement de son namespace.
Mappez ce Service account sur un pod basique.
Manifeste :
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: pod-reader-sa
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
name: pod-sa-demo
spec:
serviceAccountName: pod-reader-sa
containers:
- name: app
image: busybox
command: ["sh", "-c", "sleep 3600"]
Helm et métriques¶
Table des Matières¶
- Helm - Gestionnaire de paquets Kubernetes
- Concepts Clés
- Architecture Helm
- Utilisation Basique
- Métriques dans Kubernetes
- Metrics Server
- Prometheus et ServiceMonitor
Helm - Gestionnaire de paquets Kubernetes¶
Concepts Clés¶
Helm est le gestionnaire de paquets standard pour Kubernetes qui simplifie : - Le déploiement d'applications - La gestion des versions - La configuration des applications
Terminologie Helm¶
| Terme | Description |
|---|---|
| Chart | Package Helm contenant les ressources Kubernetes |
| Release | Instance déployée d'un Chart |
| Repository | Dépôt de Charts Helm |
| Values | Paramètres de configuration personnalisables |

Architecture Helm¶
Composants : - Client Helm : Interface en ligne de commande - Tiller (déprécié depuis Helm 3) : Composant serveur - Charts : Modèles YAML paramétrables - Releases : Versions déployées
Workflow :
1. Recherche de Charts (helm search)
2. Installation (helm install)
3. Mise à jour (helm upgrade)
4. Gestion des versions (helm rollback)
Utilisation Basique¶
Installation de Helm¶
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Commandes Essentielles¶
| Commande | Description |
|---|---|
helm repo add |
Ajouter un dépôt |
helm search repo |
Rechercher des Charts |
helm install |
Déployer une application |
helm upgrade |
Mettre à jour une release |
helm uninstall |
Supprimer une release |
helm list |
Lister les releases |
Exemple de Déploiement¶
# Ajout du dépôt stable
helm repo add stable https://charts.helm.sh/stable
# Installation de Nginx
helm install my-nginx stable/nginx-ingress
# Personnalisation avec values.yaml
helm install -f values.yaml my-app stable/mychart
Métriques dans Kubernetes¶
Metrics Server¶
Fonctionnalités :
- Collecte des métriques CPU/RAM des nodes et pods
- Nécessaire pour kubectl top et le HPA (Horizontal Pod Autoscaler)
Installation¶
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Configuration pour Kubernetes 1.25+¶
# Ajouter dans le container args
- --kubelet-insecure-tls=true
Utilisation¶
# Voir l'utilisation des ressources
kubectl top nodes
kubectl top pods
Prometheus et ServiceMonitor¶
Stack de Monitoring : - Prometheus : Collecte et stocke les métriques - Grafana : Visualisation des données - ServiceMonitor : Définit les cibles de surveillance
Exemple de ServiceMonitor¶
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: myapp-monitor
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: web
interval: 30s
path: /metrics
Fonctionnement :
1. Les applications exposent des métriques sur /metrics
2. ServiceMonitor définit quoi surveiller
3. Prometheus collecte périodiquement les données
4. Alertes et visualisation via Grafana
Déploiement avec Helm¶
# Ajout du dépôt Prometheus-Community
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# Installation de Prometheus
helm install prometheus prometheus-community/prometheus
Bonnes Pratiques¶
Pour Helm :
- Utiliser des valeurs par défaut bien documentées
- Versionner les Charts avec sémantique (SemVer)
- Tester les Charts avec helm template avant déploiement
Pour les Métriques : - Configurer des probes (liveness/readiness) - Surveiller les limites de ressources - Utiliser des dashboards Grafana pour la visualisation
Documentation Officielle Helm Documentation Prometheus Operator
Mise en pratique — Helm¶
Créer un chart Helm (serveur Nginx)¶
Un chart Helm simple pour déployer un serveur Nginx sur Kubernetes.
- Un fichier Chart.yaml pour définir le chart.
- Un fichier values.yaml pour définir les valeurs par défaut.
- Un template de déploiement (deployment.yaml).
- Un template de service (service.yaml).
Manifeste :
Créez un répertoire pour votre chart appelé my-nginx-chart. Dans ce répertoire, créez un sous-dossier templates.
Dans le répertoire my-nginx-chart, créez un fichier Chart.yaml.
apiVersion: v2
name: my-nginx-chart
description: A simple Helm chart for Nginx
version: 0.1.0
Dans le répertoire my-nginx-chart créez le fichier values.yaml.
replicaCount: 1
image:
repository: nginx
tag: "latest"
service:
type: ClusterIP
port: 80
Dans le sous-dossier templates créez les fichiers deployment.yaml et service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: 80
selector:
app: nginx
Créez ces deux fichiers de façon à ce qu'ils utilisent les values du fichier values.yaml.
Pour lancer la création du chart utilisez la commande suivante:
helm install my-nginx ./my-nginx-chart
Vérifiez que le déploiement et le service sont bien créés :
kubectl get pods
kubectl get svc
Supprimez la release une fois que vous avez terminé :
helm uninstall my-nginx
Administration Avancée¶
Table des Matières¶
- Gestion des Utilisateurs
- Installation de Cluster
- Architectures HA et Non-HA
- Procédure d'Installation
- Maintenance des Nœuds
- Mises à Jour de Cluster
- Gestion d'ETCD
- Récupération d'un Membre Corrompu
- Sauvegarde et Restauration
Gestion des Utilisateurs¶
Création d'un Utilisateur avec Certificat¶
-
Génération du CSR :
openssl req -new -newkey rsa:4096 -nodes -keyout user.key -out user.csr -subj "/CN=username/O=group" -
Création de la CSR Kubernetes :
apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: user-access spec: request: $(cat user.csr | base64 | tr -d '\n') signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 86400 usages: - client auth -
Approbation et Récupération du Certificat :
kubectl certificate approve user-access kubectl get csr user-access -o jsonpath='{.status.certificate}' | base64 -d > user.crt -
Configuration RBAC :
kubectl create role dev --verb=create,list,update,delete --resource=pods kubectl create rolebinding dev-binding --role=dev --user=username -
Création du Kubeconfig :
kubectl config set-credentials username --client-key=user.key --client-certificate=user.crt --embed-certs=true kubectl config set-context username --cluster=cluster-name --user=username
Installation de Cluster¶
Architectures HA et Non-HA¶
- Non-HA : Single control plane
- HA : Multiple control planes avec load balancer (VIP)
Procédure d'Installation¶
-
Prérequis Communs :
swapoff -a apt-get update && apt-get install -y containerd kubelet kubeadm kubectl -
Initialisation du Control Plane :
kubeadm init --control-plane-endpoint "VIP:6443" --upload-certs -
Configuration du Réseau :
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml -
Joindre les Workers :
kubeadm join VIP:6443 --token <token> --discovery-token-ca-cert-hash <hash>
Maintenance des Nœuds¶
Drain d'un Nœud¶
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
Réintégration¶
kubectl uncordon <node>
Mises à Jour de Cluster¶
Processus de Mise à Jour¶
-
Mise à Jour de kubeadm :
apt-get update && apt-get install -y kubeadm=1.26.0-00 -
Planification et Application :
kubeadm upgrade plan kubeadm upgrade apply v1.26.0 -
Mise à Jour des Composants :
apt-get install -y kubelet=1.26.0-00 kubectl=1.26.0-00 systemctl daemon-reload systemctl restart kubelet
Gestion d'ETCD¶
Récupération d'un membre corrompu¶
-
Sauvegarde :
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 snapshot save snapshot.db -
Réinitialisation :
mv /etc/kubernetes/manifests/etcd.yaml /tmp rm -rf /var/lib/etcd/member -
Réintégration :
kubeadm join phase control-plane-join etcd
Sauvegarde et Restauration¶
-
Sauvegarde Régulière :
etcdctl snapshot save /backup/etcd-snapshot-$(date +%F).db -
Restauration :
etcdctl snapshot restore /backup/etcd-snapshot.db --data-dir /var/lib/etcd-new chown -R etcd:etcd /var/lib/etcd-new
Bonnes Pratiques¶
- Sécurité : Rotation régulière des certificats
- Sauvegarde : Planification de sauvegardes ETCD quotidiennes
- Monitoring : Surveillance des ressources et des nœuds
- Documentation : Maintien d'un journal des changements
Documentation Officielle Kubernetes
Guide de Sauvegarde ETCD
Conclusion¶
1. Concepts fondamentaux¶
- Pods : unité de déploiement de base, éphémère, peut contenir plusieurs conteneurs partageant réseau et volumes.
- Deployments & ReplicaSets : permettent de garantir le nombre voulu de Pods, avec des mises à jour automatisées (rolling updates) et gestion du scaling.
- Services : abstractions réseau exposant les Pods (ClusterIP, NodePort, LoadBalancer, ExternalName) avec résolution DNS interne.
- Ingress : gestion du trafic HTTP(s) entrant vers les Services internes, via règles basées sur les hôtes/chemins.
- Volumes et Persistance :
emptyDir,hostPath, PV/PVC, StatefulSets et StorageClass pour gérer le stockage durable des données.
2. Sécurité et contrôle d'accès¶
- ConfigMaps et Secrets : injection de configuration et de données sensibles dans les conteneurs (via variables ou volumes).
- RBAC : définition de permissions granulaires via Role/ClusterRole et bindings, et utilisation des Service Accounts pour contrôler l’accès des pods à l’API.
3. Architecture du cluster¶
- Nœuds Master (Control Plane) :
kube-apiserver,etcd,kube-scheduler,kube-controller-manager,cloud-controller-manager. - Nœuds Worker :
kubelet, runtime (Docker/containerd...),kube-proxy. - Communication via API, surveillance des états désirés, orchestration automatique.
4. Opérations avancées¶
- Init Containers et probes (
liveness,readiness,startup) pour assurer la préparation, la validation et la fiabilité des conteneurs. - Requests/Limits CPU et mémoire pour distribuer la charge et prévenir les interruptions.
- Exercices pratiques (TP) : déploiement de pods, probes, configMaps, secrets, services, Ingress, scaling, mises à jour (deployments, canary, blue/green), port-forwarding.
5. Outils complémentaires¶
- Helm : packaging, versioning et déploiement avec charts et valeurs.
- Métriques :
Metrics Serverpourkubectl topet HPA ; Prometheus + ServiceMonitor pour monitoring avancé. - Administration avancée : gestion des utilisateurs et certificats, HA avec VIPs, maintenance des nœuds, mises à jour de version, sauvegarde/restauration d’ETCD.
Bonnes pratiques & points de vigilance¶
- Toujours utiliser un approche déclarative YAML + versionnée, plutôt que des commandes imperatives isolées.
- Définir de façon appropriée les
requestsetlimitspour garantir stabilité et performances. - Utiliser des probes pour maintenir la résilience des applications.
- Préférer les Deployments aux ReplicaSets pour bénéficier du rollbacks, des stratégies mises à jour, de la scalabilité.
- Pour exposer un service externe, choisir le bon type : NodePort, LoadBalancer ou Ingress selon vos besoins.
- Ne jamais stocker de données critiques dans des pods statiques : toujours les utiliser avec PV/PVC, StorageClass et StatefulSets si l’application est persistante.
- Sécuriser l’accès avec RBAC, Service Accounts, et limiter l’accès aux tokens.
- Sauvegarder régulièrement ETCD, planifier des mises à jour du cluster et les certificats.
Objectifs à garder en tête¶
- Modularité : chaque application doit être décomposée en composants conteneurisables (pods), orchestrés via deployments.
- Résilience : automatiser le redémarrage, l’exposition réseau et le scaling.
- Sécurité : configurer l’accès, la persistance, et la confidentialité via RBAC, Secrets et stockage durable.
- Observabilité & Opérations : utiliser Helm, monitoring, métriques pour gérer et faire évoluer votre infrastructure.
- Évolutivité : anticiper la montée en charge via HPA, architecture HA, et procédures de maintenance/déploiement robustes.
En résumé¶
Vous disposez désormais de :
- Une base solide pour comprendre le fonctionnement de Kubernetes (pods, services, volumes, sécurité).
- Des outils et bonnes pratiques pour déployer, faire évoluer et sécuriser vos clusters et applications.
- Des exercices concrets pour renforcer la compréhension et vérifier l’appropriation des concepts.
- Une vision complète vous permettant de passer facilement de la phase d’apprentissage à la production.