Skip to content

TP : Maîtriser Minikube ​

Ce TP vous guide à travers les fonctionnalités avancées de Minikube : gestion multi-nœuds, addons, tunnels, profiles, et simulation de pannes. L'objectif est de vous familiariser avec un environnement proche de la production.

Prérequis ​

  • Docker installé et fonctionnel
  • Minikube installé (minikube version)
  • kubectl installé (kubectl version --client)
  • Au moins 8 GB de RAM disponible pour les exercices multi-nœuds

Partie 1 : Premiers pas avec Minikube ​

1.1 Démarrer un cluster basique ​

sh
# Démarrer avec le driver Docker (recommandé)
minikube start --driver=docker

# Vérifier l'état
minikube status
# minikube
# type: Control Plane
# host: Running
# kubelet: Running
# apiserver: Running
# kubeconfig: Configured

1.2 Explorer le cluster créé ​

sh
# Voir les informations du cluster
kubectl cluster-info
# Kubernetes control plane is running at https://192.168.49.2:8443
# CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

# Voir le nœud
kubectl get nodes
# NAME       STATUS   ROLES           AGE   VERSION
# minikube   Ready    control-plane   1m    v1.28.3

# Détails du nœud
kubectl describe node minikube | head -30

1.3 Accéder au nœud Minikube ​

Minikube crée un container Docker (ou une VM selon le driver). Vous pouvez y accéder :

sh
# Via SSH (fonctionne avec tous les drivers)
minikube ssh

# Une fois connecté, vous êtes dans le nœud
docker ps  # Voir les containers du cluster
exit

# Exécuter une commande directement
minikube ssh -- docker ps | head -10

1.4 Voir les ressources consommées ​

sh
# Ressources du nœud
minikube ssh -- free -h
minikube ssh -- df -h

# Via kubectl (après activation de metrics-server)
minikube addons enable metrics-server
kubectl top nodes
kubectl top pods -A

Partie 2 : Configuration et personnalisation ​

2.1 Configurer les ressources au démarrage ​

sh
# Supprimer le cluster actuel
minikube delete

# Créer un cluster avec plus de ressources
minikube start \
  --driver=docker \
  --cpus=4 \
  --memory=4096 \
  --disk-size=20g

# Vérifier
minikube ssh -- nproc          # 4 CPUs
minikube ssh -- free -h        # ~4 GB RAM

2.2 Choisir la version de Kubernetes ​

sh
# Lister les versions disponibles
minikube config defaults kubernetes-version

# Démarrer avec une version spécifique
minikube delete
minikube start --kubernetes-version=v1.27.0

# Vérifier
kubectl version

2.3 Configuration persistante ​

sh
# Définir des valeurs par défaut
minikube config set driver docker
minikube config set cpus 4
minikube config set memory 4096

# Voir la configuration
minikube config view

# Ces valeurs seront utilisées pour les prochains `minikube start`

Partie 3 : Cluster multi-nœuds ​

C'est ici que ça devient intéressant ! Minikube peut simuler un cluster avec plusieurs nœuds.

3.1 Créer un cluster multi-nœuds ​

sh
# Supprimer le cluster existant
minikube delete

# Créer un cluster avec 3 nœuds
minikube start --nodes=3 --driver=docker

# Vérifier les nœuds
kubectl get nodes
# NAME           STATUS   ROLES           AGE   VERSION
# minikube       Ready    control-plane   2m    v1.28.3
# minikube-m02   Ready    <none>          1m    v1.28.3
# minikube-m03   Ready    <none>          30s   v1.28.3

3.2 Architecture du cluster multi-nœuds ​

┌─────────────────────────────────────────────────────────────┐
│                     Votre machine                            │
│                                                              │
│  ┌─────────────────────────────────────────────────────────┐│
│  │                      Docker                              ││
│  │                                                          ││
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      ││
│  │  │  minikube   │  │ minikube-m02│  │ minikube-m03│      ││
│  │  │  (control)  │  │  (worker)   │  │  (worker)   │      ││
│  │  │             │  │             │  │             │      ││
│  │  │ API Server  │  │  kubelet    │  │  kubelet    │      ││
│  │  │ etcd        │  │  kube-proxy │  │  kube-proxy │      ││
│  │  │ scheduler   │  │             │  │             │      ││
│  │  │ controller  │  │             │  │             │      ││
│  │  └─────────────┘  └─────────────┘  └─────────────┘      ││
│  │        │                │                │               ││
│  │        └────────────────┴────────────────┘               ││
│  │                    Réseau Docker                         ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

3.3 Gestion des nœuds ​

sh
# Lister les nœuds Minikube
minikube node list
# minikube        192.168.49.2
# minikube-m02    192.168.49.3
# minikube-m03    192.168.49.4

# Ajouter un nœud au cluster existant
minikube node add
kubectl get nodes  # Maintenant 4 nœuds

# Supprimer un nœud
minikube node delete minikube-m04
kubectl get nodes  # Retour à 3 nœuds

3.4 Observer la répartition des pods ​

sh
# Déployer une application avec plusieurs réplicas
kubectl create deployment nginx --image=nginx --replicas=6

# Voir sur quels nœuds sont les pods
kubectl get pods -o wide
# NAME                     READY   STATUS    NODE
# nginx-xxx-abc            1/1     Running   minikube
# nginx-xxx-def            1/1     Running   minikube-m02
# nginx-xxx-ghi            1/1     Running   minikube-m03
# nginx-xxx-jkl            1/1     Running   minikube
# nginx-xxx-mno            1/1     Running   minikube-m02
# nginx-xxx-pqr            1/1     Running   minikube-m03

# Le scheduler répartit automatiquement sur tous les nœuds !

3.5 TP : Simuler la perte d'un nœud ​

sh
# Terminal 1 : Observer les pods en temps réel
kubectl get pods -o wide -w

# Terminal 2 : Arrêter un nœud worker
minikube node stop minikube-m03

# Observer dans Terminal 1 :
# - Le nœud minikube-m03 passe en NotReady
# - Après ~5 minutes, les pods sont replanifiés sur les autres nœuds

# Vérifier l'état des nœuds
kubectl get nodes
# NAME           STATUS     ROLES           AGE   VERSION
# minikube       Ready      control-plane   10m   v1.28.3
# minikube-m02   Ready      <none>          9m    v1.28.3
# minikube-m03   NotReady   <none>          8m    v1.28.3

# Redémarrer le nœud
minikube node start minikube-m03
kubectl get nodes  # Tous Ready à nouveau

3.6 TP : Pod Anti-Affinity en action ​

Forçons les pods à se répartir sur des nœuds différents :

sh
# Créer un deployment avec anti-affinity
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spread-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spread-app
  template:
    metadata:
      labels:
        app: spread-app
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: spread-app
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx
EOF

# Vérifier : chaque pod est sur un nœud différent
kubectl get pods -l app=spread-app -o wide
# NAME                          NODE
# spread-app-xxx-abc            minikube
# spread-app-xxx-def            minikube-m02
# spread-app-xxx-ghi            minikube-m03

# Que se passe-t-il si on scale à 4 avec seulement 3 nœuds ?
kubectl scale deployment spread-app --replicas=4

# Le 4ème pod reste Pending !
kubectl get pods -l app=spread-app
# spread-app-xxx-jkl   0/1     Pending   # Pas de nœud disponible

kubectl describe pod spread-app-xxx-jkl | grep -A5 Events
# Warning  FailedScheduling  didn't match pod anti-affinity rules

Partie 4 : Les Addons Minikube ​

Les addons sont des composants supplémentaires que Minikube peut installer automatiquement.

4.1 Lister les addons disponibles ​

sh
minikube addons list
# |-----------------------------|----------|--------------|
# |         ADDON NAME          | STATUS   | MAINTAINER   |
# |-----------------------------|----------|--------------|
# | dashboard                   | disabled | Kubernetes   |
# | ingress                     | disabled | Kubernetes   |
# | ingress-dns                 | disabled | Google       |
# | metrics-server              | disabled | Kubernetes   |
# | registry                    | disabled | Google       |
# | storage-provisioner         | enabled  | Kubernetes   |
# | ...                         |          |              |
# |-----------------------------|----------|--------------|

4.2 Dashboard Kubernetes ​

sh
# Activer le dashboard
minikube addons enable dashboard

# Ouvrir dans le navigateur (bloque le terminal)
minikube dashboard

# Ou juste obtenir l'URL
minikube dashboard --url
# http://127.0.0.1:xxxxx/api/v1/namespaces/kubernetes-dashboard/...

Le dashboard permet de :

  • Visualiser tous les objets du cluster
  • Voir les logs des pods
  • Exécuter des commandes dans les containers
  • Créer des ressources via l'interface

4.3 Metrics Server ​

sh
# Activer metrics-server
minikube addons enable metrics-server

# Attendre que le pod soit prêt
kubectl get pods -n kube-system -l k8s-app=metrics-server
# NAME                              READY   STATUS    RESTARTS   AGE
# metrics-server-xxx                1/1     Running   0          1m

# Maintenant kubectl top fonctionne !
kubectl top nodes
# NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
# minikube       250m         6%     1200Mi          30%
# minikube-m02   100m         2%     800Mi           20%
# minikube-m03   80m          2%     750Mi           18%

kubectl top pods -A

4.4 Ingress Controller ​

sh
# Activer l'ingress NGINX
minikube addons enable ingress

# Vérifier que le controller est déployé
kubectl get pods -n ingress-nginx
# NAME                                        READY   STATUS
# ingress-nginx-controller-xxx                1/1     Running

# Créer un Ingress pour tester
kubectl create deployment web --image=nginx
kubectl expose deployment web --port=80

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: web.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
EOF

# Obtenir l'IP de l'ingress
kubectl get ingress
# NAME          CLASS   HOSTS       ADDRESS        PORTS   AGE
# web-ingress   nginx   web.local   192.168.49.2   80      30s

# Ajouter l'entrée DNS locale
echo "$(minikube ip) web.local" | sudo tee -a /etc/hosts

# Tester
curl http://web.local
# <!DOCTYPE html>...

4.5 Registry local ​

sh
# Activer le registry Docker local
minikube addons enable registry

# Le registry est accessible à l'intérieur du cluster
# Pour y pousser des images depuis votre machine :

# Configurer Docker pour utiliser le registry insecure
# (ajouter dans /etc/docker/daemon.json)
# { "insecure-registries": ["$(minikube ip):5000"] }

# Ou utiliser le tunnel Minikube
kubectl port-forward -n kube-system svc/registry 5000:80 &

# Pousser une image
docker tag mon-image:latest localhost:5000/mon-image:latest
docker push localhost:5000/mon-image:latest

# Utiliser l'image dans un pod
kubectl run test --image=localhost:5000/mon-image:latest

4.6 Storage Provisioner ​

sh
# Déjà activé par défaut, mais vérifions
minikube addons list | grep storage

# Créer un PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
EOF

# Le PV est créé automatiquement !
kubectl get pvc
# NAME       STATUS   VOLUME                                     CAPACITY
# test-pvc   Bound    pvc-abc123-def456                          1Gi

kubectl get pv
# NAME                                       CAPACITY   STATUS   CLAIM
# pvc-abc123-def456                          1Gi        Bound    default/test-pvc

Partie 5 : Accéder aux services ​

5.1 minikube service ​

La commande minikube service crée un tunnel vers un Service :

sh
# Déployer une application
kubectl create deployment hello --image=nginxdemos/hello
kubectl expose deployment hello --type=NodePort --port=80

# Accéder au service (ouvre le navigateur)
minikube service hello

# Juste obtenir l'URL
minikube service hello --url
# http://192.168.49.2:31234

5.2 minikube tunnel ​

Pour les Services de type LoadBalancer :

sh
# Créer un service LoadBalancer
kubectl expose deployment hello --type=LoadBalancer --port=80 --name=hello-lb

# Sans tunnel, EXTERNAL-IP reste <pending>
kubectl get svc hello-lb
# NAME       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)
# hello-lb   LoadBalancer   10.96.xxx.xxx   <pending>     80:31xxx/TCP

# Démarrer le tunnel (dans un autre terminal, nécessite sudo)
minikube tunnel

# Maintenant EXTERNAL-IP est assignée
kubectl get svc hello-lb
# NAME       TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)
# hello-lb   LoadBalancer   10.96.xxx.xxx   10.96.xxx.xxx   80:31xxx/TCP

# Accéder via l'IP externe
curl http://10.96.xxx.xxx

5.3 Port-forward kubectl ​

Alternative universelle :

sh
# Forward un pod
kubectl port-forward pod/hello-xxx 8080:80

# Forward un service
kubectl port-forward svc/hello 8080:80

# Forward un deployment
kubectl port-forward deployment/hello 8080:80

# Accessible sur http://localhost:8080

Partie 6 : Profiles (clusters multiples) ​

Minikube permet de gérer plusieurs clusters simultanément via les profiles.

6.1 Créer plusieurs clusters ​

sh
# Cluster par défaut (profile "minikube")
minikube start

# Créer un second cluster avec un autre profile
minikube start -p dev-cluster --nodes=2

# Créer un troisième cluster
minikube start -p staging --kubernetes-version=v1.27.0

# Lister tous les profiles
minikube profile list
# |--------------|-----------|---------|--------------|------|---------|---------|
# |   Profile    | VM Driver | Runtime |      IP      | Port | Version | Status  |
# |--------------|-----------|---------|--------------|------|---------|---------|
# | minikube     | docker    | docker  | 192.168.49.2 | 8443 | v1.28.3 | Running |
# | dev-cluster  | docker    | docker  | 192.168.58.2 | 8443 | v1.28.3 | Running |
# | staging      | docker    | docker  | 192.168.67.2 | 8443 | v1.27.0 | Running |
# |--------------|-----------|---------|--------------|------|---------|---------|

6.2 Basculer entre les clusters ​

sh
# Voir le profile actif
minikube profile
# minikube

# Changer de profile
minikube profile dev-cluster

# kubectl pointe maintenant vers dev-cluster
kubectl get nodes
# NAME              STATUS   ROLES           AGE
# dev-cluster       Ready    control-plane   5m
# dev-cluster-m02   Ready    <none>          4m

# Basculer via kubectl directement
kubectl config get-contexts
# CURRENT   NAME          CLUSTER       AUTHINFO
# *         dev-cluster   dev-cluster   dev-cluster
#           minikube      minikube      minikube
#           staging       staging       staging

kubectl config use-context minikube

6.3 Gérer les profiles ​

sh
# Arrêter un profile spécifique
minikube stop -p staging

# Supprimer un profile
minikube delete -p staging

# Supprimer TOUS les profiles
minikube delete --all

6.4 Cas d'usage des profiles ​

ProfileUsage
minikubeDéveloppement quotidien
dev-clusterTests multi-nœuds
stagingTester une version K8s spécifique
ciTests CI/CD locaux

Partie 7 : Debugging Minikube ​

7.1 Logs Minikube ​

sh
# Logs du démarrage
minikube logs

# Logs en temps réel
minikube logs -f

# Logs d'un composant spécifique
minikube logs --problems  # Seulement les erreurs

7.2 État détaillé ​

sh
# État complet
minikube status

# Informations sur le cluster
minikube ip          # IP du nœud principal
minikube ssh-key     # Clé SSH pour se connecter
minikube docker-env  # Variables pour utiliser Docker dans Minikube

# Version et configuration
minikube version
minikube config view

7.3 Problèmes courants et solutions ​

Le cluster ne démarre pas ​

sh
# Supprimer et recréer
minikube delete
minikube start --alsologtostderr -v=2  # Mode verbose

# Vérifier Docker
docker info
systemctl status docker

Pas assez de ressources ​

sh
# Vérifier les ressources allouées
minikube ssh -- free -h
minikube ssh -- df -h

# Recréer avec plus de ressources
minikube delete
minikube start --cpus=4 --memory=8192

Pods en Pending (ImagePullBackOff) ​

sh
# Vérifier la connexion réseau du nœud
minikube ssh -- ping -c3 registry.k8s.io

# Configurer un proxy si nécessaire
minikube start --docker-env HTTP_PROXY=http://proxy:8080

DNS ne fonctionne pas ​

sh
# Vérifier CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns

# Redémarrer CoreDNS
kubectl rollout restart deployment/coredns -n kube-system

7.4 Réinitialisation complète ​

sh
# Arrêter et supprimer tout
minikube stop
minikube delete --all --purge

# Nettoyer les fichiers résiduels
rm -rf ~/.minikube
rm -rf ~/.kube/config  # Attention : supprime TOUS les contextes !

# Repartir de zéro
minikube start

Partie 8 : Utiliser Docker dans Minikube ​

8.1 Configurer Docker pour pointer vers Minikube ​

sh
# Afficher les variables d'environnement
minikube docker-env
# export DOCKER_TLS_VERIFY="1"
# export DOCKER_HOST="tcp://192.168.49.2:2376"
# export DOCKER_CERT_PATH="/home/user/.minikube/certs"
# export MINIKUBE_ACTIVE_DOCKERD="minikube"

# Appliquer dans le shell courant
eval $(minikube docker-env)

# Maintenant `docker` utilise le daemon Docker de Minikube
docker ps  # Affiche les containers du cluster !

8.2 Builder une image directement dans Minikube ​

sh
# Après eval $(minikube docker-env)
# Votre build se fait DANS Minikube

docker build -t mon-app:v1 .

# L'image est disponible immédiatement pour les pods
kubectl run mon-app --image=mon-app:v1 --image-pull-policy=Never

NOTE

--image-pull-policy=Never est important car l'image n'est pas dans un registry, elle est locale au nœud.

8.3 Charger une image locale dans Minikube ​

Alternative sans modifier Docker :

sh
# Builder normalement
docker build -t mon-app:v1 .

# Charger l'image dans Minikube
minikube image load mon-app:v1

# Vérifier
minikube image ls | grep mon-app
# docker.io/library/mon-app:v1

# Utiliser dans un pod
kubectl run mon-app --image=mon-app:v1 --image-pull-policy=Never

8.4 Builder directement dans Minikube ​

sh
# Builder sans configurer Docker
minikube image build -t mon-app:v1 .

# L'image est créée directement dans Minikube
minikube image ls | grep mon-app

Partie 9 : Scénarios avancés ​

9.1 Simuler un environnement de production ​

sh
# Créer un cluster "production-like"
minikube delete
minikube start \
  --nodes=3 \
  --cpus=2 \
  --memory=4096 \
  --kubernetes-version=v1.28.0 \
  --driver=docker

# Activer les addons essentiels
minikube addons enable metrics-server
minikube addons enable ingress
minikube addons enable dashboard

# Appliquer des labels aux nœuds (comme en prod)
kubectl label nodes minikube node-role.kubernetes.io/control-plane=
kubectl label nodes minikube-m02 node-role.kubernetes.io/worker= workload=general
kubectl label nodes minikube-m03 node-role.kubernetes.io/worker= workload=database

# Vérifier
kubectl get nodes --show-labels

9.2 Tester les limites de ressources ​

sh
# Voir les ressources disponibles
kubectl describe node minikube | grep -A5 "Allocatable"

# Déployer jusqu'à saturation
kubectl create deployment hungry --image=nginx --replicas=50

# Observer les pods Pending (pas assez de ressources)
kubectl get pods | grep Pending

# Voir pourquoi
kubectl describe pod hungry-xxx | grep -A10 Events
# Warning  FailedScheduling  Insufficient cpu/memory

9.3 Chaos Engineering basique ​

sh
# Script pour tuer des pods aléatoirement
while true; do
  POD=$(kubectl get pods -l app=nginx -o jsonpath='{.items[0].metadata.name}')
  echo "Killing $POD"
  kubectl delete pod $POD --wait=false
  sleep 10
done

# Dans un autre terminal, observer la résilience
kubectl get pods -l app=nginx -w

9.4 Benchmark réseau entre nœuds ​

sh
# Déployer iperf3 sur deux nœuds différents
kubectl run iperf-server --image=networkstatic/iperf3 -- -s
kubectl run iperf-client --image=networkstatic/iperf3 -- sleep 3600

# Attendre que les pods soient prêts
kubectl wait --for=condition=ready pod/iperf-server pod/iperf-client

# Obtenir l'IP du serveur
SERVER_IP=$(kubectl get pod iperf-server -o jsonpath='{.status.podIP}')

# Lancer le benchmark
kubectl exec iperf-client -- iperf3 -c $SERVER_IP
# [ ID] Interval           Transfer     Bitrate
# [  5]   0.00-10.00  sec  25.4 GBytes  21.8 Gbits/sec  sender

Partie 10 : Commandes Minikube - Référence rapide ​

Gestion du cluster ​

CommandeDescription
minikube startDémarrer le cluster
minikube stopArrêter le cluster
minikube deleteSupprimer le cluster
minikube statusÉtat du cluster
minikube pauseMettre en pause (économie ressources)
minikube unpauseReprendre

Multi-nœuds ​

CommandeDescription
minikube start --nodes=NCréer un cluster multi-nœuds
minikube node listLister les nœuds
minikube node addAjouter un nœud
minikube node delete NAMESupprimer un nœud
minikube node start NAMEDémarrer un nœud
minikube node stop NAMEArrêter un nœud

Addons ​

CommandeDescription
minikube addons listLister les addons
minikube addons enable NAMEActiver un addon
minikube addons disable NAMEDésactiver un addon

Accès ​

CommandeDescription
minikube sshSSH dans le nœud
minikube ipIP du nœud principal
minikube service NAMEOuvrir un service
minikube tunnelTunnel pour LoadBalancer
minikube dashboardOuvrir le dashboard

Profiles ​

CommandeDescription
minikube start -p NAMECréer un profile
minikube profile listLister les profiles
minikube profile NAMEChanger de profile
minikube delete -p NAMESupprimer un profile

Images ​

CommandeDescription
minikube image load IMAGECharger une image
minikube image build -t TAG .Builder une image
minikube image lsLister les images
eval $(minikube docker-env)Utiliser Docker de Minikube

Debug ​

CommandeDescription
minikube logsVoir les logs
minikube logs --problemsVoir les erreurs
minikube update-checkVérifier les mises à jour

Nettoyage final ​

sh
# Supprimer les déploiements de test
kubectl delete deployment --all
kubectl delete service --all
kubectl delete pvc --all

# Ou supprimer complètement le cluster
minikube delete

# Supprimer tous les profiles
minikube delete --all