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.
Définissez un hostname unique sur chaque machine et remplissez /etc/hosts pour la résolution locale.
# 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
Kubernetes exige que le swap soit désactivé. Sinon kubelet refuse de démarrer.
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.
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
apt-get update && apt-get upgrade -y
apt-get install -y apt-transport-https ca-certificates curl \
gnupg lsb-release software-properties-common
Phase suivante →
Container Runtime — containerd containerd est le runtime standard. Kubernetes lui parle via l'interface CRI (Container Runtime Interface).
1
Installer et configurer containerd
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.
← Précédent
Phase suivante →
Outils Kubernetes Installer kubeadm, kubelet et kubectl. À faire sur tous les nœuds .
1
Ajouter le dépôt Kubernetes
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
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
systemctl enable kubelet
# Vérifier
kubeadm version
kubectl version --client
← Précédent
Phase suivante →
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
apt-get install -y haproxy keepalived
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)
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
← Précédent
Phase suivante →
Init Control Plane #1 À exécuter uniquement sur control-plane-1 . Initialise le cluster et génère les tokens de jonction.
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
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.
← Précédent
Phase suivante →
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
# 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
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
← Précédent
Phase suivante →
Join Worker Nodes Intégrer les 4 workers au cluster. Les workers exécuteront les pods applicatifs.
kubeadm join 192.168.1.100:6443 \
--token <TOKEN> \
--discovery-token-ca-cert-hash sha256:<HASH>
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
← Précédent
Phase suivante →
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
kubectl create -f \
https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
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
← Précédent
Phase suivante →
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
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
# 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
# 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
← Précédent
Phase suivante →
ArgoCD — GitOps Déployez ArgoCD pour gérer toutes vos applications via Git. Le cluster s'auto-configure depuis votre repo.
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
# 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
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.
← Précédent
Voir la checklist ✓