Kubernetes v1.31 · Production HA

Cluster Kubernetes
Haute Disponibilité
Guide Complet

3 Control Planes · 4 Workers · Longhorn CSI · ArgoCD GitOps
Architecture de production, explications pédagogiques, commandes réelles.

0
Nodes
0
Control Planes
0
Workers
Tolérance pannes
root@control-plane-1 ~ bash
Architecture

Topologie du Cluster

Vue en temps réel des flux de communication entre les composants. Survolez un nœud pour les détails.

TOPOLOGIE — FLUX DE COMMUNICATION EN DIRECT
── etcd RAFT CONSENSUS ── ── CONTROL PLANE (HA) ── ── DATA PLANE // WORKER NODES ──
⚖️
HAProxy · VIP
192.168.1.100:6443
Load Balancer VIP
HAProxy répartit le trafic sur les 3 API Servers. Keepalived gère l'IP virtuelle (VRRP). Point d'entrée unique du cluster.
haproxykeepalived
🗄
etcd-1
leader
etcd — Leader
Base de données clé-valeur distribuée. Protocole Raft. Stocke tout l'état du cluster. Leader actif.
raftstateful
🗄
etcd-2
follower
etcd — Follower
Réplique l'état du leader. Peut devenir leader si celui-ci tombe. Quorum = 2/3 minimum.
follower
🗄
etcd-3
follower
etcd — Quorum
3 nœuds = tolérance à 1 panne. Toujours un nombre impair ! 5 nœuds tolèrerait 2 pannes.
fault-tolerant
⚙️
control-plane-1
.101 · API · Scheduler
Control Plane #1
Héberge kube-apiserver, kube-scheduler, kube-controller-manager et etcd. Cerveau du cluster.
master192.168.1.101
⚙️
control-plane-2
.102 · API · CtrlMgr
Control Plane #2 — HA
3 CPs derrière HAProxy = aucune interruption si l'un tombe. Leader election automatique.
HA192.168.1.102
⚙️
control-plane-3
.103 · API · Scheduler
Control Plane #3
Garantit le quorum etcd. kube-scheduler place les pods sur les workers selon CPU, RAM, affinités.
scheduling192.168.1.103
🖥
worker-1
.111 · kubelet · LH
Worker Node #1
Exécute les pods applicatifs. kubelet gère les containers via containerd. Longhorn Engine pour le stockage.
data plane192.168.1.111
🖥
worker-2
.112 · LH Manager
Worker #2 — Longhorn Mgr
Héberge le Longhorn Manager. Orchestre la création et réplication des volumes persistants sur tous les workers.
storage192.168.1.112
🖥
worker-3
.113 · kubelet · LH
Worker Node #3
Réplique Longhorn. Si worker-1 tombe, les volumes restent accessibles via les réplicas sur w2/w3/w4.
resilience192.168.1.113
🖥
worker-4
.114 · ArgoCD Agent
Worker #4 — ArgoCD
Héberge l'ArgoCD Application Controller. Surveille le diff Git↔cluster et reconcile automatiquement.
GitOps192.168.1.114
💾
Longhorn CSI
Réplication ×3
Longhorn Distributed Storage
CSI driver natif K8s. Chaque volume répliqué sur 3 workers. Snapshots, backup S3, interface UI.
CSIreplicated
🐙
ArgoCD
GitOps Controller
ArgoCD — GitOps
Synchronise le cluster avec Git. Le dépôt = source de vérité. Tout changement passe par un commit.
GitOpsdeclarative
📦
Git Repo
Source of Truth
Source of Truth
Tous les manifests YAML (Deployments, Services, Ingress…). ArgoCD les applique automatiquement à chaque commit.
manifestIaC
Control Plane
Worker Node
etcd Raft
Longhorn CSI
ArgoCD GitOps
HAProxy VIP
Hover sur un nœud pour les détails
ÉTAT DES NŒUDS
control-plane-1
CP
CPU 18%
control-plane-2
CP
CPU 14%
control-plane-3
CP
CPU 16%
worker-1
WK
CPU 61%
worker-2
WK
CPU 74%
worker-3
WK
CPU 48%
worker-4
WK
CPU 55%
LONGHORN — VOLUMES PERSISTANTS

Réplication des blocs sur les workers. Panne d'un node → données toujours accessibles via les réplicas.

postgres-data
20 Gi · RWO
✓ replicas ×3
prometheus-tsdb
50 Gi · RWO
✓ replicas ×3
loki-chunks
100 Gi · RWO
✓ replicas ×2
minio-data
200 Gi · RWX
✓ replicas ×3
RWO = ReadWriteOnce · RWX = ReadWriteMany
UI Longhorn → NodePort :30080
ARGOCD — GITOPS APPLICATIONS

Git = source de vérité. ArgoCD reconcile en continu l'état réel vs désiré.

SYNCED
monitoring-stack
Prometheus · Grafana · Alertmanager
SYNCED
ingress-nginx
Ingress Controller · Cert-Manager
OUT OF SYNC
app-backend
Pending deploy → v2.4.1
🔄
Flux GitOps
commit → push → ArgoCD détecte diff → applique → cluster à jour
Composants

Anatomie du Cluster

Chaque composant a un rôle précis. Comprendre leur interaction est essentiel pour opérer un cluster en production.

COMPOSANTS CONTROL PLANE
🔌
kube-apiserver
Point d'entrée unique. Valide et persiste TOUS les objets dans etcd. Expose l'API REST. Authentification, autorisation (RBAC), admission controllers.
📅
kube-scheduler
Surveille les pods Pending et choisit le meilleur worker. Critères : ressources disponibles, affinités, anti-affinités, taints/tolerations, topologie.
🔁
kube-controller-manager
Boucles de réconciliation : ReplicaSet, Deployment, StatefulSet, Job, Node, Endpoint… État réel → état désiré en permanence.
🗄
etcd
Base clé-valeur distribuée (protocole Raft). Stocke l'intégralité du cluster. 3 instances = quorum. Sauvegardez-le régulièrement !
COMPOSANTS WORKER NODE
🤖
kubelet
Agent sur chaque node. Reçoit les PodSpecs depuis l'API Server, pilote containerd/CRI-O, remonte les métriques (cAdvisor). Cœur du data plane.
🌐
kube-proxy
Implémente les Services via iptables ou eBPF (avec Cilium). Load-balance le trafic entre les pods d'un même Service.
📦
containerd
Container runtime (CRI). Lance les images OCI. Kubernetes ne parle plus directement à Docker depuis v1.24. containerd = standard de facto.
💾
Longhorn CSI Driver
Plugin CSI sur chaque node. Monte les volumes Longhorn dans les pods via iSCSI. Réplique les blocs de données de façon transparente.
LONGHORN — STOCKAGE DISTRIBUÉ
🏗
Architecture
Chaque volume = 1 Engine + N Replicas distribués sur les workers. Le CSI driver expose le volume au pod via un device bloc virtuel.
🔄
Réplication synchrone
Écriture confirmée quand tous les replicas (×3 par défaut) ont acknowledgé. Lecture depuis l'Engine local → latence minimale.
📸
Snapshots & Backup
Snapshots COW (Copy-on-Write) incrémentaux. Backup vers S3-compatible (MinIO, AWS S3). Restore en 1 clic depuis l'UI.
Failover automatique
Si un worker tombe, l'Engine bascule sur un replica disponible en quelques secondes. Le pod peut continuer à écrire sans interruption.
ARGOCD — GITOPS
📜
Principe GitOps
Git = source de vérité absolue. Toute modification d'infra passe par un commit. Traçabilité complète, rollback = git revert.
🔍
Reconciliation loop
ArgoCD compare en continu l'état désiré (Git) avec l'état réel (cluster K8s) et applique les diffs automatiquement si sync-policy=automated.
🌲
App of Apps pattern
Une Application ArgoCD gère d'autres Applications. Déploiement de tout le cluster en 1 commit sur le repo "apps/". Bootstrap instantané.
🔐
RBAC & Projects
Projects ArgoCD pour isoler les équipes/environnements. RBAC fin sur qui peut sync/delete/override. Intégration SSO (Dex, OIDC).
Guide d'installation

Déploiement pas à pas

Commandes réelles, testées sur Ubuntu 22.04. Adaptez les IPs à votre environnement.

Phases d'installation

Prérequis système

À exécuter sur tous les nœuds (3 CP + 4 workers). Prépare l'OS pour Kubernetes.

⚠ Adaptez les hostnames et IPs à votre infrastructure avant de copier les commandes.
1
Hostname et /etc/hosts
Définissez un hostname unique sur chaque machine et remplissez /etc/hosts pour la résolution locale.
bashtous les nœuds
# Sur chaque node, adaptez le hostname hostnamectl set-hostname control-plane-1 # ou worker-1, etc. # Remplir /etc/hosts sur TOUS les nodes cat <<EOF >> /etc/hosts 192.168.1.100 lb.kube.local 192.168.1.101 control-plane-1 192.168.1.102 control-plane-2 192.168.1.103 control-plane-3 192.168.1.111 worker-1 192.168.1.112 worker-2 192.168.1.113 worker-3 192.168.1.114 worker-4 EOF
2
Désactiver le swap
Kubernetes exige que le swap soit désactivé. Sinon kubelet refuse de démarrer.
bashtous les nœuds
swapoff -a sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # Vérifier free -h # Swap doit afficher 0
3
Modules kernel et sysctl
overlay et br_netfilter sont requis par containerd et le réseau Kubernetes.
bashtous les nœuds
cat <<EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter cat <<EOF | tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF sysctl --system
4
Paquets requis
bashtous les nœuds
apt-get update && apt-get upgrade -y apt-get install -y apt-transport-https ca-certificates curl \ gnupg lsb-release software-properties-common

Container Runtime — containerd

containerd est le runtime standard. Kubernetes lui parle via l'interface CRI (Container Runtime Interface).

1
Installer et configurer containerd
bashtous les nœuds
apt-get install -y containerd # Générer la config par défaut mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml # IMPORTANT : activer SystemdCgroup sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' \ /etc/containerd/config.toml # Redémarrer et activer systemctl restart containerd systemctl enable containerd # Vérifier systemctl status containerd
ℹ SystemdCgroup = true est crucial. Sans ça, kubelet et containerd utilisent des cgroup drivers différents → instabilité du cluster.

Outils Kubernetes

Installer kubeadm, kubelet et kubectl. À faire sur tous les nœuds.

1
Ajouter le dépôt Kubernetes
bashtous les nœuds
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | \ 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.31/deb/ /' | \ tee /etc/apt/sources.list.d/kubernetes.list apt-get update
2
Installer et verrouiller les versions
bashtous les nœuds
apt-get install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl systemctl enable kubelet # Vérifier kubeadm version kubectl version --client

HAProxy + Keepalived

Configurez un load balancer avec IP virtuelle (VIP) devant les 3 API Servers. Sur un node dédié ou le premier CP.

1
Installer HAProxy et Keepalived
bashnode LB
apt-get install -y haproxy keepalived
2
Configurer HAProxy
bash/etc/haproxy/haproxy.cfg
cat <<EOF | tee /etc/haproxy/haproxy.cfg global log /dev/log local0 maxconn 2000 daemon defaults log global mode tcp option tcplog timeout connect 5000 timeout client 50000 timeout server 50000 frontend k8s-frontend bind *:6443 mode tcp default_backend k8s-backend backend k8s-backend mode tcp balance roundrobin option tcp-check server cp1 192.168.1.101:6443 check fall 3 rise 2 server cp2 192.168.1.102:6443 check fall 3 rise 2 server cp3 192.168.1.103:6443 check fall 3 rise 2 EOF
3
Configurer Keepalived (MASTER)
bash/etc/keepalived/keepalived.conf
cat <<EOF | tee /etc/keepalived/keepalived.conf vrrp_script check_haproxy { script "killall -0 haproxy" interval 2 weight -2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 authentication { auth_type PASS auth_pass k8s-ha-2024 } virtual_ipaddress { 192.168.1.100 } track_script { check_haproxy } } EOF systemctl enable --now haproxy keepalived

Init Control Plane #1

À exécuter uniquement sur control-plane-1. Initialise le cluster et génère les tokens de jonction.

1
Créer la config kubeadm
yamlkubeadm-config.yaml
cat <<EOF | tee kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.31.0 controlPlaneEndpoint: "192.168.1.100:6443" networking: podSubnet: "10.244.0.0/16" serviceSubnet: "10.96.0.0/12" --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd EOF
2
Initialiser le cluster
bashcontrol-plane-1
kubeadm init --config kubeadm-config.yaml --upload-certs # Configurer kubectl mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # Vérifier kubectl get nodes
✓ Conservez précieusement les commandes "kubeadm join" affichées en sortie ! Vous en aurez besoin pour les phases 6 et 7.

Join Control Planes #2 et #3

Intégrer les deux autres control planes au cluster pour la haute disponibilité.

1
Régénérer les tokens si nécessaire
bashcontrol-plane-1
# Obtenir le certificate-key kubeadm init phase upload-certs --upload-certs # => Certificate key: <CERT_KEY> # Obtenir le token de jonction kubeadm token create --print-join-command
2
Joindre CP2 et CP3
bashcontrol-plane-2 et control-plane-3
kubeadm join 192.168.1.100:6443 \ --token <TOKEN> \ --discovery-token-ca-cert-hash sha256:<HASH> \ --control-plane \ --certificate-key <CERT_KEY> # Sur chaque CP, configurer kubectl mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # Vérifier depuis CP1 kubectl get nodes

Join Worker Nodes

Intégrer les 4 workers au cluster. Les workers exécuteront les pods applicatifs.

1
Joindre les workers
bashworker-1, worker-2, worker-3, worker-4
kubeadm join 192.168.1.100:6443 \ --token <TOKEN> \ --discovery-token-ca-cert-hash sha256:<HASH>
2
Labelliser les workers
bashcontrol-plane-1
for i in 1 2 3 4; do kubectl label node worker-$i node-role.kubernetes.io/worker=worker done # Vérifier — tous les nodes doivent être NotReady (CNI pas encore installé) kubectl get nodes -o wide

CNI — Calico

Le réseau de pods (CNI) est requis pour que les nodes passent en Ready et que les pods puissent communiquer.

1
Installer l'opérateur Calico
bashcontrol-plane-1
kubectl create -f \ https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
2
Configurer le pod CIDR
bashcontrol-plane-1
cat <<EOF | kubectl apply -f - apiVersion: operator.tigera.io/v1 kind: Installation metadata: name: default spec: calicoNetwork: ipPools: - name: default-ipv4-ippool cidr: 10.244.0.0/16 encapsulation: VXLANCrossSubnet natOutgoing: Enabled EOF # Attendre que tous les nodes soient Ready kubectl wait --for=condition=Ready nodes --all --timeout=300s kubectl get nodes

Longhorn — Stockage Distribué

Déployez Longhorn pour le stockage persistant répliqué. Pré-requis : open-iscsi sur tous les workers.

1
Prérequis sur tous les workers
bashtous les workers
apt-get install -y open-iscsi nfs-common cryptsetup dmsetup systemctl enable --now iscsid # Vérifier les prérequis curl -sSfL \ https://raw.githubusercontent.com/longhorn/longhorn/v1.6.0/scripts/environment_check.sh \ | bash
2
Installer Helm puis Longhorn
bashcontrol-plane-1
# Installer Helm curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # Ajouter le repo Longhorn helm repo add longhorn https://charts.longhorn.io helm repo update # Installer Longhorn helm install longhorn longhorn/longhorn \ --namespace longhorn-system \ --create-namespace \ --version 1.6.0 \ --set defaultSettings.defaultReplicaCount=3 \ --set defaultSettings.storageMinimalAvailablePercentage=15 # Attendre kubectl -n longhorn-system rollout status deploy/longhorn-driver-deployer
3
Définir Longhorn comme StorageClass par défaut
bashcontrol-plane-1
# Retirer l'annotation default de local-path kubectl patch storageclass local-path -p \ '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' # Définir Longhorn comme défaut kubectl patch storageclass longhorn -p \ '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' kubectl get storageclass

ArgoCD — GitOps

Déployez ArgoCD pour gérer toutes vos applications via Git. Le cluster s'auto-configure depuis votre repo.

1
Installer ArgoCD
bashcontrol-plane-1
kubectl create namespace argocd kubectl apply -n argocd -f \ https://raw.githubusercontent.com/argoproj/argo-cd/v2.9.0/manifests/install.yaml # Attendre que tout soit Ready kubectl -n argocd wait --for=condition=Ready pods --all --timeout=300s # Récupérer le mot de passe admin initial kubectl -n argocd get secret argocd-initial-admin-secret \ -o jsonpath="{.data.password}" | base64 -d && echo
2
Exposer l'interface web
bashcontrol-plane-1
# Option NodePort (accès direct) kubectl patch svc argocd-server -n argocd \ -p '{"spec":{"type":"NodePort"}}' # Ou port-forward pour test kubectl port-forward svc/argocd-server -n argocd 8080:443
3
Créer votre première Application
yamlapp.yaml
cat <<EOF | kubectl apply -f - apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app namespace: argocd spec: project: default source: repoURL: https://github.com/mon-org/mon-repo.git targetRevision: HEAD path: k8s/ destination: server: https://kubernetes.default.svc namespace: my-app syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true EOF
✓ Cluster complet ! Kubernetes HA + Longhorn + ArgoCD opérationnels. Utilisez la checklist ci-dessous pour valider chaque étape.
Checklist

Suivi d'installation

Cochez chaque étape au fur et à mesure. Votre progression est sauvegardée localement.

Progression globale
0% complété