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