Aller au contenu principal
Intermédiaire 12 chapitres

⎈ Kubernetes — Des fondamentaux à la production

Formation Kubernetes complète : architecture, Pods, Deployments, Services, Volumes, ConfigMaps, Secrets, RBAC, Network Policies. Du débutant à la production avec des providers Suisses.

Progression 12 chapitres

Programme

1

Pourquoi Kubernetes ? L'orchestration expliquée Gratuit

Découvre pourquoi Kubernetes est devenu le standard de l'orchestration : architecture, concepts fondamentaux et installation locale.

2

Architecture K8s et premières commandes kubectl

Installe Kind, lance ton premier déploiement et maîtrise les commandes kubectl essentielles.

3

Deployments : déployer et mettre à jour

Maîtrise les Deployments Kubernetes : ReplicaSets, rolling updates, rollbacks et scaling horizontal.

4

Services : exposer tes applications

Expose tes applications avec les Services, le DNS interne, Ingress et les NetworkPolicies.

5

Volumes et stockage persistant

Comprends les volumes Kubernetes : emptyDir, hostPath, PV, PVC et les StorageClasses pour le stockage persistant.

6

ConfigMaps et Secrets

Externalise ta configuration avec les ConfigMaps et protège tes données sensibles avec les Secrets et Sealed Secrets.

7

RBAC : qui a accès à quoi

Maîtrise le RBAC Kubernetes : Roles, ClusterRoles, Bindings et contrôle d'accès granulaire.

8

Network Policies et Pod Security

Sécurise tes workloads avec les Pod Security Standards, les NetworkPolicies, les Admission Controllers et l'audit logging.

9

CNI et networking K8s en détail

Comprends le modèle réseau Kubernetes, les plugins CNI et les Network Policies en profondeur.

10

Service Mesh : Istio et Linkerd

Découvre les Service Mesh avec Istio et Linkerd, les Ingress Controllers et le debugging réseau.

11

Helm : le package manager de K8s

Découvre Helm : installation, commandes de base, anatomie d'un chart, templates Go et values par environnement.

12

Créer et publier son chart Helm

Crée ton propre chart Helm, utilise Helmfile pour orchestrer tes releases et applique les best practices production.

Introduction — Kubernetes en 2026

Kubernetes est devenu le système d’exploitation du cloud. Ce n’est plus une technologie émergente ou un buzzword — c’est l’infrastructure standard sur laquelle tournent la majorité des applications modernes en production. Des startups aux banques suisses, des SaaS aux systèmes embarqués edge, Kubernetes est partout.

En 2026, la question n’est plus “faut-il utiliser Kubernetes ?” mais “comment bien l’utiliser ?”. Car K8s est puissant, mais il est aussi complexe. La courbe d’apprentissage est raide. La surface d’API est immense. Les erreurs de configuration en production peuvent être catastrophiques. Et pourtant, une fois maîtrisé, Kubernetes te donne un niveau de contrôle et d’automatisation qu’aucun autre outil n’offre.

Pourquoi Kubernetes existe

Avant Kubernetes, déployer et gérer des conteneurs en production était un casse-tête. Docker te permet de créer et exécuter des conteneurs, mais il ne répond pas aux questions fondamentales de la production :

  • Comment répartir 50 conteneurs sur 10 machines ?
  • Comment redémarrer automatiquement un conteneur qui crashe ?
  • Comment scaler de 3 à 30 instances quand le trafic explose ?
  • Comment faire une mise à jour sans downtime ?
  • Comment gérer le réseau entre des centaines de conteneurs ?
  • Comment stocker les données persistantes de manière fiable ?

Kubernetes répond à toutes ces questions. C’est un orchestrateur de conteneurs — il gère le cycle de vie complet de tes applications conteneurisées : déploiement, scaling, mise à jour, monitoring, réparation automatique.

Ce que cette formation couvre

Cette formation te prend par la main depuis les concepts de base (qu’est-ce qu’un Pod ?) jusqu’à la sécurisation d’un cluster de production. On ne survole pas — chaque sujet est traité en profondeur avec des exemples YAML que tu peux appliquer immédiatement.

À la fin de ce parcours, tu seras capable de :

  • Comprendre l’architecture de Kubernetes et le rôle de chaque composant
  • Déployer des applications avec des Deployments et les exposer via des Services
  • Gérer le stockage persistant, la configuration et les secrets
  • Sécuriser un cluster avec RBAC, Network Policies et Pod Security Standards
  • Opérer un cluster en production (monitoring, logging, troubleshooting)
  • Choisir le bon provider Kubernetes pour tes besoins (y compris en Suisse)

Prérequis

Compétences requises

CompétenceNiveauPourquoi
DockerIntermédiaireK8s orchestre des conteneurs — tu dois savoir les construire
LinuxIntermédiaireLes nœuds K8s sont Linux, tu vas y SSH régulièrement
Réseau TCP/IPIntermédiaireDNS, load balancing, ports, CIDR — c’est omniprésent en K8s
YAMLBasesTout K8s se configure en YAML (beaucoup de YAML)
Ligne de commandeBon niveaukubectl est ton outil principal

💡 Conseil : Si tu ne maîtrises pas encore Docker, commence par notre Formation Docker. K8s sans Docker, c’est comme apprendre à conduire sans savoir ce qu’est un moteur.

Environnement technique

  • kubectl — Le CLI officiel Kubernetes (obligatoire)
  • Un cluster local — Choix recommandé : k3d (k3s dans Docker) ou kind (Kubernetes in Docker)
  • Helm — Le gestionnaire de packages K8s (v3+)
  • Lens ou k9s — Interface graphique / TUI pour explorer le cluster
  • 16 Go de RAM minimum — Un cluster local avec quelques services consomme facilement 4-8 Go

Installation rapide

# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/

# k3d — cluster K3s dans Docker (le plus rapide)
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash

# Créer un cluster local
k3d cluster create devlab --agents 2 --port "8080:80@loadbalancer"

# Vérifier
kubectl cluster-info
kubectl get nodes
# macOS — via Homebrew
brew install kubectl k3d helm k9s

k3d cluster create devlab --agents 2
kubectl get nodes
# NAME                   STATUS   ROLES                  AGE   VERSION
# k3d-devlab-server-0    Ready    control-plane,master   30s   v1.29.x
# k3d-devlab-agent-0     Ready    <none>                 25s   v1.29.x
# k3d-devlab-agent-1     Ready    <none>                 25s   v1.29.x

Durée estimée

ParcoursDurée
Lecture complète~16 heures
Avec exercices pratiques~30 heures
Certification CKA prep~80 heures (inclut pratique intensive)

Niveau : Intermédiaire (Docker requis) → Avancé


Architecture Kubernetes

Avant de plonger dans les chapitres, prenons du recul pour comprendre l’architecture globale. C’est indispensable — sans cette vision d’ensemble, tu ne comprendras pas pourquoi les choses fonctionnent (ou ne fonctionnent pas).

graph TB
    subgraph CP["CONTROL PLANE"]
        API["API Server
kube-apiserver"] CM["Controller Manager"] SCHED["Scheduler
kube-scheduler"] ETCD["etcd
key-value store"] API --> ETCD end API -->|":6443"| W1 API -->|":6443"| W2 API -->|":6443"| W3 subgraph W1["Worker Node 1"] K1["kubelet"] --> P1["kube-proxy"] --> C1["containerd"] C1 --> PA["Pod A"] C1 --> PB["Pod B"] end subgraph W2["Worker Node 2"] K2["kubelet"] --> P2["kube-proxy"] --> C2["containerd"] C2 --> PC["Pod C"] C2 --> PD["Pod D"] end subgraph W3["Worker Node 3"] K3["kubelet"] --> P3["kube-proxy"] --> C3["containerd"] C3 --> PE["Pod E"] end style CP fill:#1a2332,stroke:#dc2626,color:#f1f5f9 style API fill:#1a2332,stroke:#3b82f6,color:#f1f5f9 style CM fill:#1a2332,stroke:#3b82f6,color:#f1f5f9 style SCHED fill:#1a2332,stroke:#3b82f6,color:#f1f5f9 style ETCD fill:#1a2332,stroke:#f59e0b,color:#f1f5f9 style W1 fill:#0f172a,stroke:#22c55e,color:#f1f5f9 style W2 fill:#0f172a,stroke:#22c55e,color:#f1f5f9 style W3 fill:#0f172a,stroke:#22c55e,color:#f1f5f9 style PA fill:#1a2332,stroke:#a855f7,color:#f1f5f9 style PB fill:#1a2332,stroke:#a855f7,color:#f1f5f9 style PC fill:#1a2332,stroke:#a855f7,color:#f1f5f9 style PD fill:#1a2332,stroke:#a855f7,color:#f1f5f9 style PE fill:#1a2332,stroke:#a855f7,color:#f1f5f9

Les composants clés expliqués

API Server — C’est le cerveau du cluster. Tout passe par lui : quand tu tapes kubectl get pods, ta requête va à l’API Server. Quand le scheduler décide où placer un Pod, il passe par l’API Server. Quand un kubelet rapporte l’état d’un Pod, il passe par l’API Server. C’est le seul composant qui parle à etcd.

etcd — La base de données du cluster. Un key-value store distribué qui stocke l’intégralité de l’état du cluster : quels Pods existent, quelle est leur configuration, quels nœuds sont disponibles, quels secrets sont stockés. Perdre etcd = perdre le cluster. C’est pour ça qu’on le réplique en nombre impair (3 ou 5 instances).

Controller Manager — Le gardien de l’état désiré. Il exécute des boucles de réconciliation : “L’utilisateur veut 3 réplicas de l’app web. Il y en a 2 qui tournent. Je dois en créer un 3ème.” C’est le principe fondamental de Kubernetes : tu déclares ce que tu veux, les controllers s’assurent que la réalité correspond.

Scheduler — Le placeur. Quand un nouveau Pod doit être créé, le scheduler décide sur quel nœud le mettre. Il prend en compte les ressources disponibles, les contraintes d’affinité, les taints et tolerations, et plein d’autres critères.

kubelet — L’agent sur chaque nœud worker. Il reçoit les instructions de l’API Server (“lance ce Pod”) et s’assure que les conteneurs tournent comme prévu. Il rapporte aussi l’état de santé des Pods.

kube-proxy — Gère le réseau sur chaque nœud. Il maintient les règles réseau (iptables/IPVS) qui permettent aux Services Kubernetes de router le trafic vers les bons Pods.


Parcours de formation

<pre class="mermaid">
graph LR
  A["Ch.1<br>Intro & Concepts<br>~4h"] --> B["Ch.2<br>Deployments & Services<br>~5h"]
  B --> C["Ch.3<br>Volumes & Config<br>~4h"]
  C --> D["Ch.4<br>Sécurité & RBAC<br>~4h"]
  style A fill:#1a2332,stroke:#3b82f6,color:#f1f5f9
  style B fill:#1a2332,stroke:#22c55e,color:#f1f5f9
  style C fill:#1a2332,stroke:#f59e0b,color:#f1f5f9
  style D fill:#1a2332,stroke:#dc2626,color:#f1f5f9
</pre>

Chapitre 1 — Introduction à Kubernetes

📖 Accéder au cours complet — Chapitre 1

De quoi parle ce chapitre ?

Ce premier chapitre pose les fondations conceptuelles de Kubernetes. Avant de taper la moindre commande kubectl, tu dois comprendre les abstractions fondamentales de K8s : Pods, Nodes, Namespaces, Labels, et le principe déclaratif qui gouverne tout.

Kubernetes a été créé par Google, inspiré de leur système interne Borg qui gérait des millions de conteneurs. Donné à la Cloud Native Computing Foundation (CNCF) en 2015, il est devenu le standard de l’orchestration en quelques années. Son architecture est élégante : tu déclares l’état désiré de ton système (dans des fichiers YAML), et Kubernetes s’assure en permanence que la réalité correspond à ton intention.

Le concept central est le Pod. Un Pod est la plus petite unité déployable dans Kubernetes — c’est un wrapper autour d’un ou plusieurs conteneurs qui partagent le même réseau et le même stockage. Dans 90% des cas, un Pod = un conteneur. Mais le modèle multi-conteneurs (sidecar pattern) est puissant pour des cas comme le logging, le monitoring, ou les proxies de service mesh.

Ce chapitre couvre aussi l’installation d’un cluster local (k3d, kind, minikube), les bases de kubectl, et les premiers déploiements. Tu vas apprendre à naviguer dans un cluster, à comprendre les Namespaces, et à utiliser les Labels et Selectors qui sont le mécanisme de lien entre toutes les ressources K8s.

Ce que tu vas apprendre

  • L’histoire et la philosophie de Kubernetes (déclaratif vs impératif)
  • L’architecture complète : Control Plane et Worker Nodes
  • Les concepts fondamentaux : Pod, Node, Namespace, Label, Selector
  • Installation d’un cluster local avec k3d ou kind
  • Les commandes kubectl essentielles
  • Le format des manifestes YAML Kubernetes
  • Le cycle de vie d’un Pod (Pending → Running → Succeeded/Failed)

Extrait de code clé

# mon-premier-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-demo
  namespace: default
  labels:
    app: nginx
    env: demo
    tier: frontend
spec:
  containers:
    - name: nginx
      image: nginx:1.25-alpine
      ports:
        - containerPort: 80
          name: http
      resources:
        requests:
          memory: "64Mi"
          cpu: "100m"
        limits:
          memory: "128Mi"
          cpu: "250m"
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 5
        periodSeconds: 10
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 5
# Appliquer le manifeste
kubectl apply -f mon-premier-pod.yaml

# Vérifier l'état
kubectl get pods -o wide
kubectl describe pod nginx-demo

# Voir les logs
kubectl logs nginx-demo

# Entrer dans le Pod
kubectl exec -it nginx-demo -- sh

# Port-forward pour tester localement
kubectl port-forward pod/nginx-demo 8080:80
# → http://localhost:8080

# Supprimer
kubectl delete pod nginx-demo
# ou
kubectl delete -f mon-premier-pod.yaml

Points clés à retenir

Kubernetes est déclaratif, pas impératif. Tu ne dis pas “lance 3 conteneurs nginx”. Tu dis “je veux un Deployment avec 3 réplicas de nginx” et Kubernetes s’en occupe. Si un Pod crashe, K8s le recrée automatiquement. Si un nœud tombe, K8s replanifie les Pods sur les nœuds restants. C’est ce qu’on appelle la réconciliation — la boucle qui rapproche en permanence l’état réel de l’état désiré.

Ne déploie jamais des Pods seuls en production. Un Pod seul n’a pas de mécanisme de redémarrage, pas de scaling, pas de rolling update. C’est comme un processus nu sans supervision. En production, tu utilises toujours un controller (Deployment, StatefulSet, DaemonSet) qui gère les Pods pour toi.


Chapitre 2 — Deployments & Services

📖 Accéder au cours complet — Chapitre 2

De quoi parle ce chapitre ?

C’est le chapitre le plus important de la formation. Les Deployments et les Services sont les deux ressources que tu utiliseras le plus en Kubernetes — probablement 80% de ton temps kubectl sera consacré à ces deux objets.

Un Deployment gère le cycle de vie de tes Pods applicatifs. Tu lui dis combien de réplicas tu veux, quelle image utiliser, et comment faire les mises à jour. Il crée un ReplicaSet sous le capot, qui à son tour crée les Pods. Le Deployment te donne le rolling update (mise à jour progressive sans downtime), le rollback (retour arrière en cas de problème), et le scaling (ajuster le nombre de réplicas).

Un Service expose tes Pods sur le réseau. Les Pods sont éphémères — ils naissent, meurent, et obtiennent des IP différentes à chaque fois. Un Service fournit une adresse stable (IP virtuelle + nom DNS) qui route le trafic vers les Pods correspondants via un sélecteur de labels. C’est le mécanisme de service discovery natif de Kubernetes.

Ce chapitre couvre aussi les Ingress, qui sont la porte d’entrée HTTP/HTTPS de ton cluster. Un Ingress te permet de router le trafic externe vers tes Services internes en fonction du hostname ou du path URL. Combiné avec un Ingress Controller (Traefik, nginx-ingress, ou Cilium), c’est comme ça que tu exposes tes applications au monde extérieur.

On aborde aussi le Horizontal Pod Autoscaler (HPA) qui ajuste automatiquement le nombre de réplicas en fonction de la charge (CPU, mémoire, ou métriques custom).

Ce que tu vas apprendre

  • Les Deployments : création, scaling, rolling updates, rollbacks
  • Les ReplicaSets : pourquoi ils existent et comment ils fonctionnent
  • Les Services : ClusterIP, NodePort, LoadBalancer, ExternalName
  • Le DNS interne de Kubernetes (<service>.<namespace>.svc.cluster.local)
  • Les Ingress et Ingress Controllers
  • Le Horizontal Pod Autoscaler (HPA)
  • Les stratégies de déploiement : RollingUpdate vs Recreate

Extrait de code clé — Deployment + Service + Ingress

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: production
  labels:
    app: api
    version: v2.1.0
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 1 Pod en plus pendant la MAJ
      maxUnavailable: 0   # Jamais moins que 3 Pods dispo
  template:
    metadata:
      labels:
        app: api
        version: v2.1.0
    spec:
      containers:
        - name: api
          image: ghcr.io/monorg/api:v2.1.0
          ports:
            - containerPort: 3000
              name: http
          env:
            - name: NODE_ENV
              value: "production"
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: url
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "512Mi"
              cpu: "1000m"
          livenessProbe:
            httpGet:
              path: /health
              port: http
            initialDelaySeconds: 15
            periodSeconds: 20
          readinessProbe:
            httpGet:
              path: /ready
              port: http
            initialDelaySeconds: 5
            periodSeconds: 10
          startupProbe:
            httpGet:
              path: /health
              port: http
            failureThreshold: 30
            periodSeconds: 10
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: api      # ← Route vers les Pods avec label app=api
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - api.monapp.ch
      secretName: api-tls
  rules:
    - host: api.monapp.ch
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 80

Commandes de gestion courantes

# Déployer
kubectl apply -f deployment.yaml -f service.yaml -f ingress.yaml

# Vérifier le déploiement
kubectl -n production get deployments
kubectl -n production get pods -l app=api
kubectl -n production get svc api
kubectl -n production get ingress api

# Scaler manuellement
kubectl -n production scale deployment api --replicas=5

# Mettre à jour l'image (rolling update)
kubectl -n production set image deployment/api api=ghcr.io/monorg/api:v2.2.0

# Suivre le rollout en temps réel
kubectl -n production rollout status deployment/api

# Rollback si ça va mal
kubectl -n production rollout undo deployment/api

# Historique des déploiements
kubectl -n production rollout history deployment/api

# HPA — autoscaling
kubectl -n production autoscale deployment api \
  --min=3 --max=10 --cpu-percent=70

Points clés à retenir

Toujours définir des requests ET des limits de ressources. Sans requests, le scheduler ne sait pas sur quel nœud placer ton Pod. Sans limits, un Pod peut consommer toute la mémoire d’un nœud et provoquer un OOM kill en cascade. Les requests sont le “minimum garanti”, les limits sont le “maximum autorisé”.

Les trois types de probes sont complémentaires :

  • startupProbe — “L’app a-t-elle fini de démarrer ?” (désactive liveness/readiness pendant le startup)
  • livenessProbe — “L’app est-elle vivante ?” (si non → restart du conteneur)
  • readinessProbe — “L’app est-elle prête à recevoir du trafic ?” (si non → retirée du Service)

Ne confonds pas liveness et readiness. Une app qui charge un gros cache en mémoire peut être “vivante” (liveness OK) mais “pas prête” (readiness KO) pendant le chargement. Si tu mets la même probe pour les deux, un démarrage lent va provoquer des restarts en boucle.


Chapitre 3 — Volumes & Configuration

📖 Accéder au cours complet — Chapitre 3

De quoi parle ce chapitre ?

Les conteneurs sont éphémères — quand un Pod meurt, ses données disparaissent. C’est parfait pour des applications stateless (API, workers), mais catastrophique pour une base de données, un système de fichiers partagé, ou tout service qui a besoin de persister des données.

Kubernetes résout ce problème avec le système de volumes. Mais contrairement à Docker où tu as juste des bind mounts et des named volumes, Kubernetes a un système bien plus sophistiqué avec les PersistentVolumes (PV), les PersistentVolumeClaims (PVC), et les StorageClasses. C’est un système d’abstraction à trois niveaux qui découple le stockage physique de son utilisation par les Pods.

L’idée est simple et élégante :

  1. L’admin du cluster configure des StorageClasses (types de stockage disponibles : SSD, HDD, NFS, cloud…)
  2. Le développeur crée un PersistentVolumeClaim (“j’ai besoin de 10 Go de stockage SSD”)
  3. Kubernetes provisionne automatiquement un PersistentVolume correspondant et le lie au PVC

Ce chapitre couvre aussi la configuration des applications dans Kubernetes. Au lieu de hardcoder des valeurs dans tes images Docker, tu utilises des ConfigMaps pour la configuration non-sensible (URLs, feature flags, fichiers de config) et des Secrets pour les données sensibles (mots de passe, clés API, certificats TLS).

On traite aussi les StatefulSets, le controller Kubernetes conçu pour les applications avec état (bases de données, clusters Kafka, systèmes distribués). Contrairement aux Deployments où les Pods sont interchangeables, un StatefulSet garantit des identités stables (pod-0, pod-1, pod-2), un ordre de démarrage/arrêt, et des volumes persistants individuels.

Ce que tu vas apprendre

  • Les types de volumes Kubernetes (emptyDir, hostPath, PV/PVC, CSI)
  • Le provisionning dynamique avec les StorageClasses
  • ConfigMaps : créer, monter en volume, injecter en env vars
  • Secrets : gestion, chiffrement au repos, rotation
  • StatefulSets : quand et comment les utiliser
  • Les patterns de données : sidecar de backup, init containers pour migrations

Extrait de code clé — PVC + ConfigMap + Secret

# storage-class.yaml (généralement pré-configuré par le provider)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: csi.exoscale.com  # Provider Suisse 🇨🇭
parameters:
  type: ssd
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-data
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 20Gi
---
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  # Valeurs simples
  LOG_LEVEL: "info"
  FEATURE_NEW_UI: "true"
  MAX_CONNECTIONS: "100"

  # Fichier de configuration complet
  nginx.conf: |
    server {
      listen 80;
      server_name _;

      location / {
        proxy_pass http://api:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
      }

      location /health {
        return 200 'OK';
        add_header Content-Type text/plain;
      }
    }
---
# secret.yaml (en prod, utilise sealed-secrets ou external-secrets)
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: production
type: Opaque
stringData:
  url: "postgres://app:SuperSecret123@postgres:5432/myapp?sslmode=require"
  password: "SuperSecret123"

StatefulSet pour PostgreSQL

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: production
spec:
  serviceName: postgres  # Requis pour le DNS stable
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: myapp
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: username
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: password
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
          resources:
            requests:
              memory: "256Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1000m"
  # Volume claim template — chaque réplica obtient son propre PVC
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 20Gi

Points clés à retenir

Ne stocke jamais de secrets dans tes manifestes Git en clair. Les Secrets Kubernetes sont encodés en base64, pas chiffrés. Tout le monde avec accès au cluster peut les lire. Utilise des outils comme Sealed Secrets (chiffrement côté client), External Secrets Operator (synchro depuis un vault externe), ou SOPS (chiffrement de fichiers YAML) pour gérer les secrets proprement.

Le choix entre Deployment et StatefulSet est simple :

  • Deployment → application stateless (API, worker, frontend). Les Pods sont interchangeables.
  • StatefulSet → application stateful (DB, cache, broker). Les Pods ont des identités stables et des volumes individuels.

Si tu peux utiliser un Deployment, utilise un Deployment. Les StatefulSets sont plus complexes à opérer (scaling, updates, backups).


Chapitre 4 — Sécurité & RBAC

📖 Accéder au cours complet — Chapitre 4

De quoi parle ce chapitre ?

La sécurité Kubernetes est un sujet vaste et critique. Un cluster mal sécurisé, c’est une porte ouverte sur toute ton infrastructure. Ce chapitre couvre les mécanismes de sécurité natifs de Kubernetes : RBAC, Network Policies, Pod Security Standards, et les bonnes pratiques qui font la différence entre un cluster passoire et un cluster durci.

Le RBAC (Role-Based Access Control) est le système d’autorisation de Kubernetes. Il contrôle qui peut faire quoi sur quelles ressources. Tu définis des Roles (ensemble de permissions) et des RoleBindings (liaison entre un rôle et un utilisateur/groupe/service account). Le RBAC est activé par défaut sur tous les clusters modernes, mais sa configuration par défaut est souvent trop permissive.

Les Network Policies sont le firewall de Kubernetes. Par défaut, tous les Pods peuvent communiquer avec tous les autres Pods dans le cluster — c’est un réseau plat, ouvert. Les Network Policies te permettent de définir des règles d’ingress (trafic entrant) et d’egress (trafic sortant) par Pod, namespace, ou CIDR. C’est la microsegmentation réseau appliquée aux conteneurs.

Les Pod Security Standards (PSS) remplacent les anciennes Pod Security Policies (dépréciées depuis K8s 1.25). Ils définissent trois niveaux de restriction :

  • Privileged — aucune restriction (déconseillé)
  • Baseline — restrictions minimales (bloque les conteneurs privileged, hostNetwork, etc.)
  • Restricted — restrictions strictes (non-root obligatoire, pas de capabilities dangereuses)

Ce chapitre couvre aussi la sécurité des images (scan, signatures, admission controllers), le chiffrement des secrets au repos, et les service accounts.

Ce que tu vas apprendre

  • RBAC : Roles, ClusterRoles, RoleBindings, ClusterRoleBindings
  • Service Accounts et leur utilisation sécurisée
  • Network Policies : isolation réseau entre Pods et Namespaces
  • Pod Security Standards / Pod Security Admission
  • Security Contexts (runAsNonRoot, readOnlyRootFilesystem, capabilities)
  • Admission Controllers (OPA Gatekeeper, Kyverno)
  • Audit logging et détection d’anomalies

Extrait de code clé — RBAC + Network Policy

# rbac.yaml — Accès en lecture seule pour l'équipe monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: monitoring-reader
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "endpoints"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: monitoring-reader-binding
  namespace: production
subjects:
  - kind: Group
    name: monitoring-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: monitoring-reader
  apiGroup: rbac.authorization.k8s.io
---
# network-policy.yaml — Isolation stricte de la base de données
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-isolation
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # Seul le service API peut parler à la DB
    - from:
        - podSelector:
            matchLabels:
              app: api
      ports:
        - protocol: TCP
          port: 5432
  egress:
    # La DB peut résoudre le DNS (nécessaire pour K8s)
    - to: []
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
---
# Deny all par défaut — bonne pratique de base
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}   # Tous les Pods du namespace
  policyTypes:
    - Ingress
    - Egress

Security Context — Pod durci

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-secure
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: api
          image: ghcr.io/monorg/api:v2.1.0
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          volumeMounts:
            # Le filesystem est en lecture seule,
            # on monte un tmpfs pour les fichiers temporaires
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: tmp
          emptyDir:
            medium: Memory
            sizeLimit: 100Mi

Points clés à retenir

Le principe du moindre privilège s’applique partout. Chaque service account ne doit avoir que les permissions strictement nécessaires. Chaque conteneur doit tourner en non-root avec un filesystem en lecture seule. Chaque Pod ne doit pouvoir communiquer qu’avec les services dont il a besoin. C’est plus de configuration, mais c’est la différence entre un cluster qui résiste à une compromission et un cluster où un conteneur compromis donne accès à tout.

Les Network Policies ne fonctionnent que si ton CNI les supporte. Calico, Cilium, et Weave les supportent. Flannel ne les supporte PAS (il les ignore silencieusement). Vérifie ton CNI avant de compter sur les Network Policies pour ta sécurité.


Providers Kubernetes en Suisse 🇨🇭

Si tu cherches un cluster Kubernetes managé avec des données hébergées en Suisse, voici les options principales en 2026 :

Exoscale SKS (Scalable Kubernetes Service)

Exoscale est un provider cloud suisse basé à Lausanne. Leur offre SKS est un Kubernetes managé propre et simple :

  • Datacenters : Zurich (CH-DK-2), Genève (CH-GVA-2)
  • Control plane managé — tu ne gères que les worker nodes
  • Intégration native avec le stockage block Exoscale (CSI driver)
  • Pricing transparent — tu paies les worker nodes, le control plane est gratuit
  • Conformité : Données en Suisse, FINMA-compatible
# Créer un cluster SKS avec exo CLI
exo compute sks create my-cluster \
  --zone ch-dk-2 \
  --service-level pro \
  --nodepool-size 3 \
  --nodepool-instance-type standard.medium

Infomaniak Jelastic / Kubernetes

Infomaniak, basé à Genève, propose une plateforme Kubernetes intégrée :

  • Datacenters : Genève, Zurich
  • Kubernetes managé avec interface Jelastic Cloud
  • Stockage S3 compatible inclus
  • Support en français
  • Hébergement éco-responsable — énergie 100% renouvelable

Comparatif rapide

CritèreExoscale SKSInfomaniakScaleway KapsuleGKE/EKS/AKS
Données en Suisse✅ Zurich, Genève✅ Genève, Zurich❌ Paris, Amsterdam❌ (sauf GKE Zurich)
FINMA compatibleVariable
Control planeGratuitInclusGratuitGratuit (GKE), payant (EKS)
Prix worker node~60 CHF/mois (medium)Variable~40€/moisVariable
Simplicité⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Support FR❌ (anglais)

💡 Notre recommandation : Pour un projet hébergé en Suisse avec des contraintes réglementaires, Exoscale SKS est le choix le plus solide. L’API est propre, le support est réactif, et le pricing est transparent. Pour du développement/staging sans contrainte de localisation, k3s sur un VPS est imbattable en rapport qualité/prix.


Outils essentiels de l’écosystème

Gestion du cluster

OutilDescriptionInstallation
kubectlCLI officiel — obligatoirebrew install kubectl
k9sTUI interactive — indispensablebrew install k9s
kubectx/kubensChanger de contexte/namespace rapidementbrew install kubectx
LensIDE Kubernetes graphiquelens.dev

Déploiement

OutilDescriptionQuand l’utiliser
HelmGestionnaire de packages K8sApps complexes, charts communautaires
KustomizePatching de manifestes YAMLQuand Helm est overkill
ArgoCDGitOps — déploiement automatique depuis GitProduction, CI/CD avancé
FluxAlternative GitOps à ArgoCDSi tu préfères l’approche CNCF

Observabilité

OutilDescription
Prometheus + GrafanaMonitoring et dashboards — le standard
LokiAgrégation de logs (le “Prometheus des logs”)
Jaeger / TempoTracing distribué

Sécurité

OutilDescription
TrivyScan de vulnérabilités (images + manifestes)
FalcoDétection d’intrusion runtime
KyvernoPolicy engine (alternative à OPA/Gatekeeper)
cert-managerGestion automatique des certificats TLS

Ressources complémentaires


Prêt à commencer ?

Kubernetes a la réputation d’être complexe. C’est vrai — mais cette complexité est le reflet de la complexité réelle de l’orchestration en production. Chaque concept que tu vas apprendre résout un problème concret que tu rencontreras en prod.

Le parcours recommandé :

  1. Chapitre 1 — Introduction — Les fondations : architecture, Pods, kubectl
  2. Chapitre 2 — Deployments & Services — Déployer et exposer tes applications
  3. Chapitre 3 — Volumes & Config — Persister les données et gérer la configuration
  4. Chapitre 4 — Sécurité — Sécuriser ton cluster pour la production

🚀 Commencer le Chapitre 1 — Introduction à Kubernetes


Cette formation est maintenue activement et mise à jour régulièrement. Dernière mise à jour : mars 2026. Tu as une question ou une suggestion ? Ouvre une issue sur le dépôt GitHub du site.