Kubernetes (K8s) : orchestration de conteneurs

🏷️ Cloud && Déploiement 📅 14/04/2026 15:00:00 👤 Mezgani said
Kubernetes K8S Orchestration Conteneurs Docker Kubectl
Kubernetes (K8s) : orchestration de conteneurs

Maîtrisez Kubernetes pour orchestrer vos conteneurs Docker en production. Architecture (pods, services, deployments), kubectl, configuration YAML, scaling automatique et déploiement d'applications cloud-native.

Qu'est-ce que Kubernetes ?

Kubernetes (souvent abrégé K8s) est un système d'orchestration de conteneurs open-source développé par Google. Il automatise le déploiement, la mise à l'échelle et la gestion d'applications conteneurisées.

Kubernetes résout les problèmes de gestion de conteneurs à grande échelle : répartition de charge, auto-scaling, redémarrage automatique en cas de crash, gestion des secrets, et bien plus encore.

☸️ Pourquoi K8s ? Le nombre "8" entre "K" et "s" représente les 8 lettres supprimées : K-ubernete-s.

Architecture Kubernetes

Un cluster Kubernetes est composé de deux types de machines :

Control Plane (Master Node)

Gère l'état global du cluster :

  • kube-apiserver : Point d'entrée API pour toutes les commandes
  • etcd : Base de données clé-valeur pour stocker l'état du cluster
  • kube-scheduler : Attribue les pods aux worker nodes
  • kube-controller-manager : Surveille l'état du cluster et effectue des actions correctives

Worker Nodes

Exécutent les applications conteneurisées :

  • kubelet : Agent qui communique avec le control plane
  • kube-proxy : Gère les règles réseau
  • Container runtime : Docker, containerd ou CRI-O
💡 Analogie : Le control plane est comme le cerveau d'une organisation, les worker nodes sont les employés qui exécutent le travail.

Installation et configuration

Minikube (pour développement local)

Minikube crée un cluster Kubernetes local avec un seul nœud.

# Installation sur Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Démarrer le cluster
minikube start

# Vérifier le statut
minikube status

# Accéder au dashboard
minikube dashboard

kubectl (CLI Kubernetes)

# Installation sur Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# Vérifier la version
kubectl version --client

# Configurer kubectl pour Minikube (automatique avec minikube start)
kubectl cluster-info

# Voir les nœuds du cluster
kubectl get nodes

Docker Desktop (Windows/macOS)

Docker Desktop inclut Kubernetes. Activez-le dans les paramètres : Settings → Kubernetes → Enable Kubernetes.

Concepts fondamentaux

Pod

Un Pod est la plus petite unité déployable dans Kubernetes. Il contient un ou plusieurs conteneurs qui partagent le même réseau et le même stockage.

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mon-app
spec:
  containers:
  - name: nginx
    image: nginx:1.24
    ports:
    - containerPort: 80

Deployment

Un Deployment gère les Pods et assure leur mise à l'échelle, les mises à jour et le rollback.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mon-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mon-app
  template:
    metadata:
      labels:
        app: mon-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80

Service

Un Service expose une application déployée via un ensemble de Pods avec une IP stable et un système de load balancing.

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mon-app-service
spec:
  type: LoadBalancer
  selector:
    app: mon-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

ConfigMap et Secret

ConfigMap stocke des données de configuration non sensibles, Secret stocke des données sensibles encodées en base64.

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  API_URL: "https://api.example.com"
  LOG_LEVEL: "info"

---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_PASSWORD: c2VjcmV0MTIz  # base64 de "secret123"

Namespace

Les Namespaces permettent d'isoler logiquement des ressources dans un même cluster.

# Créer un namespace
kubectl create namespace production

# Lister les namespaces
kubectl get namespaces

# Déployer dans un namespace spécifique
kubectl apply -f deployment.yaml -n production

Commandes kubectl essentielles

Gestion des ressources

# Appliquer une configuration YAML
kubectl apply -f deployment.yaml

# Créer des ressources
kubectl create deployment nginx --image=nginx:1.24

# Lister les ressources
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get all  # Toutes les ressources

# Décrire une ressource (détails)
kubectl describe pod mon-pod

# Voir les logs
kubectl logs mon-pod
kubectl logs -f mon-pod  # Mode suivi

# Exécuter une commande dans un pod
kubectl exec -it mon-pod -- bash

# Supprimer des ressources
kubectl delete pod mon-pod
kubectl delete -f deployment.yaml

Scaling

# Scaler manuellement
kubectl scale deployment mon-app --replicas=5

# Auto-scaling basé sur CPU
kubectl autoscale deployment mon-app --min=2 --max=10 --cpu-percent=80

Mise à jour

# Mettre à jour l'image d'un conteneur
kubectl set image deployment/mon-app nginx=nginx:1.25

# Voir l'historique des déploiements
kubectl rollout history deployment/mon-app

# Rollback
kubectl rollout undo deployment/mon-app

# Rollback vers une version spécifique
kubectl rollout undo deployment/mon-app --to-revision=2

# Voir le statut d'un rollout
kubectl rollout status deployment/mon-app

Debug

# Voir les événements
kubectl get events --sort-by='.lastTimestamp'

# Copier des fichiers vers/depuis un pod
kubectl cp mon-pod:/app/logs.txt ./logs.txt

# Port-forward pour accéder à un service localement
kubectl port-forward service/mon-app 8080:80

# Proxy vers l'API Kubernetes
kubectl proxy

Déployer une application complète

Exemple : application web Node.js avec PostgreSQL

# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web
        image: mon-registry/web-app:1.0
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secret
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 3000
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15-alpine
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_DB
          value: "myapp"
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: postgres-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

Déployer l'application

# Créer les secrets
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=secret123

# Déployer toute l'infrastructure
kubectl apply -f app-deployment.yaml

# Vérifier le déploiement
kubectl get pods
kubectl get services

# Accéder à l'application
kubectl port-forward service/web-app-service 8080:80
# Ouvrir http://localhost:8080

Scaling et haute disponibilité

Horizontal Pod Autoscaler (HPA)

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Liveness et Readiness Probes

spec:
  containers:
  - name: web
    image: mon-app:1.0
    livenessProbe:
      httpGet:
        path: /health
        port: 3000
      initialDelaySeconds: 30
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 3000
      initialDelaySeconds: 5
      periodSeconds: 5
🔑 Différence :
  • Liveness : Redémarre le conteneur si le check échoue
  • Readiness : Retire le pod du load balancer si le check échoue

Bonnes pratiques

  • Utilisez des namespaces : Isolez les environnements (dev, staging, prod)
  • Resource limits : Définissez toujours requests et limits pour CPU/RAM
  • Health checks : Implémentez liveness et readiness probes
  • ConfigMaps et Secrets : Externalisez la configuration
  • Labels et selectors : Organisez vos ressources avec des labels cohérents
  • Rolling updates : Configurez maxUnavailable et maxSurge
  • RBAC : Activez le contrôle d'accès basé sur les rôles
  • Monitoring : Utilisez Prometheus + Grafana
  • Logs centralisés : ELK Stack ou Loki
  • Backup etcd : Sauvegardez régulièrement l'état du cluster

Exemple de stratégie de déploiement

spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1  # Max 1 pod indisponible pendant la mise à jour
      maxSurge: 1        # Max 1 pod supplémentaire pendant la mise à jour
🔒 Sécurité : N'utilisez jamais :latest comme tag d'image en production. Utilisez des tags versionnés explicites.

Conclusion

Kubernetes est devenu le standard de facto pour l'orchestration de conteneurs en production. Sa complexité initiale est compensée par sa puissance, sa flexibilité et son écosystème riche.

Explorez Jenkins et les pipelines CI/CD pour automatiser le déploiement de vos applications Kubernetes.

📚 Ressources officielles :