CKA - Domaine 2 : Architecture et Installation de Cluster (25%)
🎯 Objectifs
À la fin de ce module, tu seras capable de :
- ✅ Expliquer le rôle de chaque composant du control plane et des worker nodes
- ✅ Installer et joindre des nodes avec
kubeadm - ✅ Mettre à jour un cluster Kubernetes avec
kubeadm upgrade - ✅ Sauvegarder et restaurer la base de données
etcd - ✅ Créer et associer des rôles RBAC à des utilisateurs et ServiceAccounts
- ✅ Comprendre les certificats TLS qui sécurisent le cluster
📋 Prérequis
- Modules Kubernetes Débutant et Avancé complétés
- Module CKA : Guide et Stratégie lu
- Connaissances Linux :
systemctl,journalctl, édition de fichiers YAML
🏗️ Architecture interne d'un cluster
Vue d'ensemble
Un cluster Kubernetes est composé de deux types de machines :
Control Plane (1 ou 3+ nodes) Worker Nodes (N nodes)
┌──────────────────────────────┐ ┌──────────────────────────┐
│ kube-apiserver │ │ kubelet │
│ kube-controller-manager │◄──►│ kube-proxy │
│ kube-scheduler │ │ container runtime │
│ etcd │ │ (containerd / CRI-O) │
│ cloud-controller-manager │ └──────────────────────────┘
└──────────────────────────────┘Composants du Control Plane
kube-apiserver
- Le seul composant qui parle directement à etcd
- Toutes les commandes
kubectlpassent par lui - Valide et persiste chaque objet Kubernetes
- Écoute sur le port 6443 (HTTPS)
etcd
- Base de données clé/valeur distribuée
- Stocke tout l'état du cluster
- Écoute sur le port 2379 (clients) et 2380 (peering)
- Un snapshot etcd = une sauvegarde complète du cluster
kube-scheduler
- Observe les Pods en attente (
Pending) - Choisit le node optimal en fonction des ressources disponibles, des taints, de l'affinity...
- Ne démarre pas les Pods lui-même - il met à jour le champ
nodeNamedu Pod
kube-controller-manager
- Exécute en boucle des controllers : Node Controller, Replication Controller, Endpoints Controller...
- Chaque controller surveille l'état du cluster et agit pour atteindre l'état désiré
Composants des Worker Nodes
kubelet
- L'agent sur chaque node
- Reçoit les PodSpecs (via l'API server) et s'assure que les conteneurs tournent
- Communique avec le container runtime (containerd)
- Reporte l'état du node à l'API server
kube-proxy
- Maintient les règles réseau (iptables ou ipvs) sur chaque node
- Permet aux Services de fonctionner en redirigeant le trafic vers les bons Pods
container runtime
- Exécute réellement les conteneurs (containerd, CRI-O)
- L'interface est standardisée : CRI (Container Runtime Interface)
Static Pods
Les composants du control plane tournent en général comme des static pods : des Pods définis par des fichiers YAML sur le disque, gérés directement par kubelet (pas par l'API server).
# Emplacement des manifests statiques
ls /etc/kubernetes/manifests/
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml
# etcd.yaml
# Modifier un manifest = kubelet recrée automatiquement le pod
# Utile pour changer des flags de configuration📦 kubeadm : installer un cluster
Prérequis sur chaque machine
# Désactiver le swap (requis par Kubernetes)
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# Activer les modules kernel
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# Paramètres réseau
cat <<EOF | sudo 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
# Installer containerd
apt install -y containerdInstaller kubeadm, kubelet, kubectl
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/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.30/deb/ /' | \
tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectlInitialiser le control plane
# Sur le control plane node
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=v1.30.0
# Configurer kubectl pour l'utilisateur courant
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Installer un CNI (ex: Flannel)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.ymlRejoindre un worker node
# La commande est donnée en fin du kubeadm init
# Elle ressemble à :
kubeadm join 192.168.1.10:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:<hash>
# Si le token a expiré (durée de vie : 24h), en créer un nouveau
kubeadm token create --print-join-command⬆️ Mettre à jour le cluster (kubeadm upgrade)
La mise à jour se fait un composant à la fois : control plane d'abord, puis workers.
Mettre à jour le control plane
# Sur le control plane node
# 1. Mettre à jour kubeadm
apt-mark unhold kubeadm
apt-get install -y kubeadm=1.31.0-1.1
apt-mark hold kubeadm
# 2. Vérifier le plan de mise à jour
kubeadm upgrade plan
# 3. Appliquer la mise à jour
kubeadm upgrade apply v1.31.0
# 4. Drainer le control plane node
kubectl drain controlplane --ignore-daemonsets
# 5. Mettre à jour kubelet et kubectl
apt-mark unhold kubelet kubectl
apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1
apt-mark hold kubelet kubectl
systemctl daemon-reload
systemctl restart kubelet
# 6. Remettre le node en service
kubectl uncordon controlplaneMettre à jour les workers
# Sur CHAQUE worker (répéter pour chaque node)
# 1. Mettre à jour kubeadm sur le worker
apt-mark unhold kubeadm
apt-get install -y kubeadm=1.31.0-1.1
apt-mark hold kubeadm
# 2. Appliquer la mise à jour locale
kubeadm upgrade node
# 3. Depuis le control plane : drainer le worker
kubectl drain worker1 --ignore-daemonsets --delete-emptydir-data
# 4. Sur le worker : mettre à jour kubelet et kubectl
apt-mark unhold kubelet kubectl
apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1
apt-mark hold kubelet kubectl
systemctl daemon-reload
systemctl restart kubelet
# 5. Depuis le control plane : remettre en service
kubectl uncordon worker1💾 Sauvegarde et restauration etcd
C'est une question quasi-certaine à l'examen. Maîtrise chaque option.
Variables d'environnement utiles
# Trouver l'adresse etcd et les certificats
cat /etc/kubernetes/manifests/etcd.yaml | grep -A2 "listen-client"
# → --listen-client-urls=https://127.0.0.1:2379
ETCDCTL_API=3
ETCD_ENDPOINTS=https://127.0.0.1:2379
ETCD_CACERT=/etc/kubernetes/pki/etcd/ca.crt
ETCD_CERT=/etc/kubernetes/pki/etcd/server.crt
ETCD_KEY=/etc/kubernetes/pki/etcd/server.keySauvegarder
ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-backup.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# Vérifier le snapshot
ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup.db --write-out=tableRestaurer
# 1. Restaurer dans un nouveau répertoire de données
ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
--data-dir=/var/lib/etcd-restored
# 2. Modifier le manifest statique pour pointer vers le nouveau data-dir
vim /etc/kubernetes/manifests/etcd.yaml
# Changer :
# --data-dir=/var/lib/etcd ← ancienne valeur
# Par :
# --data-dir=/var/lib/etcd-restored
#
# Et dans volumes/hostPath :
# path: /var/lib/etcd ← ancienne valeur
# Par :
# path: /var/lib/etcd-restored
# 3. Attendre que le pod etcd redémarre automatiquement
watch kubectl get pods -n kube-system🔐 RBAC : contrôle d'accès basé sur les rôles
Pourquoi RBAC ?
Sans RBAC, tout utilisateur du cluster peut tout faire. RBAC permet de définir précisément qui peut faire quoi sur quoi.
Les 4 objets RBAC
| Objet | Portée | Description |
|---|---|---|
Role | Namespace | Ensemble de permissions dans un namespace |
ClusterRole | Cluster entier | Ensemble de permissions globales |
RoleBinding | Namespace | Associe un Role à un sujet |
ClusterRoleBinding | Cluster entier | Associe un ClusterRole à un sujet |
Créer des rôles
# Role dans un namespace (mode impératif)
kubectl create role pod-manager \
--verb=get,list,watch,create,delete \
--resource=pods \
--namespace=default
# ClusterRole (scope global)
kubectl create clusterrole node-viewer \
--verb=get,list,watch \
--resource=nodes# Role YAML (mode déclaratif)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-manager
namespace: default
rules:
- apiGroups: [""] # "" = core API group (pods, services, configmaps...)
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"] # Deployments, StatefulSets...
resources: ["deployments"]
verbs: ["get", "list"]Créer des bindings
# RoleBinding : lier un Role à un User
kubectl create rolebinding alice-pod-manager \
--role=pod-manager \
--user=alice \
--namespace=default
# RoleBinding : lier un Role à un ServiceAccount
kubectl create rolebinding sa-pod-manager \
--role=pod-manager \
--serviceaccount=default:mon-sa \
--namespace=default
# ClusterRoleBinding
kubectl create clusterrolebinding alice-node-viewer \
--clusterrole=node-viewer \
--user=aliceVérifier les permissions
# Est-ce qu'alice peut lister les pods dans default ?
kubectl auth can-i list pods --as alice
# Est-ce que le SA "mon-sa" peut créer des deployments ?
kubectl auth can-i create deployments \
--as system:serviceaccount:default:mon-sa
# Lister toutes les permissions d'un utilisateur
kubectl auth can-i --list --as alice
kubectl auth can-i --list --as alice -n productionServiceAccounts
# Créer un ServiceAccount
kubectl create serviceaccount mon-sa -n default
# Le pod utilise automatiquement le SA "default"
# Pour utiliser un SA spécifique :spec:
serviceAccountName: mon-sa
containers:
- name: app
image: nginx🔑 Certificats
Les composants Kubernetes communiquent via TLS. Tous les certificats sont dans /etc/kubernetes/pki/.
# Voir les certificats et leur expiration
kubeadm certs check-expiration
# Renouveler TOUS les certificats (avant qu'ils expirent)
kubeadm certs renew all
# Renouveler un certificat spécifique
kubeadm certs renew apiserver
# Après renouvellement, redémarrer les static pods
# (modifier temporairement un manifest pour forcer kubelet à les recréer)Structure des certificats
/etc/kubernetes/pki/
├── ca.crt / ca.key # CA racine du cluster
├── apiserver.crt / apiserver.key # TLS du kube-apiserver
├── apiserver-kubelet-client.crt/.key # apiserver → kubelet
├── front-proxy-ca.crt/.key # pour l'extension API
└── etcd/
├── ca.crt / ca.key # CA etcd
├── server.crt / server.key # TLS etcd
└── peer.crt / peer.key # peering etcd📊 Récapitulatif des commandes clés
# Architecture
kubectl get componentstatuses # état des composants (deprecated mais présent à l'examen)
kubectl get nodes -o wide # état des nodes avec IPs
ls /etc/kubernetes/manifests/ # static pods du control plane
# kubeadm
kubeadm token list # tokens actifs
kubeadm token create --print-join-command # recréer une commande join
kubeadm upgrade plan # versions disponibles
kubeadm certs check-expiration # validité des certificats
kubeadm certs renew all # renouveler tous les certs
# etcd (retenir les 3 options TLS !)
ETCDCTL_API=3 etcdctl snapshot save <file> \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# RBAC
kubectl auth can-i <verbe> <resource> --as <user>
kubectl create role / clusterrole / rolebinding / clusterrolebinding🚀 Prochaines Étapes
- Domaine suivant : CKA : Workloads et Scheduling
- Entraîne-toi : monte un cluster kubeadm sur des VMs (Vagrant + VirtualBox), casse etcd et restaure-le
- Référence : kubernetes.io/docs/tasks/administer-cluster/kubeadm/