## Introduction

Kubeadm init est l'étape fondamentale pour amorcer un plan de contrôle Kubernetes. Bien que la commande de base soit simple, l'opérer en production exige une approche disciplinée. Une liste de contrôle aide les opérateurs à passer d'un problème observé à un résultat vérifié, en minimisant les temps d'arrêt et la dérive de configuration. Cet article fournit une liste de contrôle opérationnelle complète pour kubeadm init, couvrant l'inventaire des versions et de l'environnement, la configuration sécurisée, la vérification, le diagnostic et la récupération en cas d'échec. Il s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui gèrent des clusters Kubernetes.

L'objectif est la sûreté opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et documenter les chemins de récupération avant qu'un incident ne force une décision.

## Inventaire des versions et de l'environnement

Avant d'exécuter toute commande kubeadm, vous devez savoir exactement avec quoi vous travaillez. Capturer l'inventaire de l'environnement prévient les surprises de compatibilité et garantit que les étapes suivantes sont adaptées à votre version de Kubernetes.

### Identifier les versions installées

Commencez par recueillir des informations en lecture seule sur kubeadm, kubelet et kubectl. Ces composants doivent être compatibles entre eux ; kubeadm suit les politiques de décalage de version définies dans la politique de décalage de version de Kubernetes. Exécutez les commandes suivantes sur le nœud destiné à être le plan de contrôle :

```bash
kubeadm version
kubelet --version
kubectl version --client
```

Exemple de sortie attendue (les versions peuvent différer) :

```text
kubeadm version: &version.Info{Major:"1", Minor:"28", GitVersion:"v1.28.2", ...}
Kubernetes v1.28.2
Client Version: v1.28.2
```

Notez que kubelet n'a pas toujours l'option `--version` ; utilisez `kubelet --version` si elle est prise en charge, sinon interrogez le gestionnaire de paquets (par exemple, `dpkg -l kubelet` sur Debian/Ubuntu ou `rpm -q kubelet` sur CentOS/RHEL).

Enregistrez les versions exactes dans un journal des modifications ou un runbook. Cela est crucial pour le dépannage et la planification des mises à niveau.

### Examiner la topologie de déploiement

Déterminez le rôle du nœud et sa configuration réseau. Utilisez :

```bash
hostnamectl
ip addr show
cat /etc/hosts
```

Sortie attendue : nom d'hôte, adresses IP et entrées du fichier hosts. Assurez-vous que le nœud du plan de contrôle a une IP stable et un nom d'hôte résoluble. Le serveur d'API Kubernetes se liera à cette IP (ou à 0.0.0.0 si non spécifié), alors confirmez qu'il n'y a pas de conflit.

### Vérifier les prérequis

Kubeadm exige certains paramètres du noyau, un moteur d'exécution de conteneurs et des réglages système. Vérifiez-les avec des commandes en lecture seule :

- Assurez-vous que le moteur d'exécution de conteneurs (par exemple, containerd, CRI-O) est en cours d'exécution et que sa socket existe :

```bash
sudo systemctl status containerd
ls -l /run/containerd/containerd.sock
```

- Vérifiez les modules du noyau requis et les paramètres sysctl :

```bash
cat /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/bridge/bridge-nf-call-iptables
```

Attendu : `1` pour les deux. Sinon, ne modifiez pas encore ; notez-le comme une action à mener lors de la phase de configuration sécurisée.

- Vérifiez l'état du swap (le swap doit être désactivé) :

```bash
swapon --show
free -h
```

Attendu : aucune entrée de swap dans `swapon --show`. Si le swap est activé, kubelet échouera au démarrage ; vous devez le désactiver avant l'initialisation.

Documentez tous les résultats, y compris les écarts par rapport aux valeurs attendues.

## Chemin de configuration sécurisé

Une fois l'inventaire de l'environnement terminé, vous pouvez planifier et appliquer les changements de configuration en toute sécurité. Le principe est d'apporter le plus petit changement justifié avec un chemin de retour en arrière clair.

### Préparer le fichier de configuration kubeadm

Au lieu de vous fier uniquement aux options de ligne de commande, utilisez un fichier de configuration pour la reproductibilité et le contrôle de version. Créez un `kubeadm-config.yaml` avec des paramètres explicites. Voici un exemple minimal pour Kubernetes v1.28 :

```yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.1.100  # Remplacez par l'IP de votre nœud
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
  name: control-plane-1
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
networking:
  podSubnet: 10.244.0.0/16  # Exemple pour Flannel ; ajustez selon votre CNI
  serviceSubnet: 10.96.0.0/12
controlPlaneEndpoint: "192.168.1.100:6443"
```

Ne stockez jamais de véritables identifiants ou jetons dans le fichier de configuration. Utilisez des espaces réservés ou des variables d'environnement pour les données sensibles.

### Valider la configuration

Avant d'appliquer, validez la configuration en utilisant la capacité de simulation de kubeadm :

```bash
kubeadm init --config kubeadm-config.yaml --dry-run
```

Cette commande simule l'initialisation et affiche les actions qu'elle entreprendrait sans apporter de modifications. Examinez la sortie pour détecter tout avertissement ou erreur. Par exemple, si l'adresse annoncée est injoignable, kubeadm vous avertira.

### Appliquer le changement

Seulement après validation, lancez l'initialisation réelle :

```bash
sudo kubeadm init --config kubeadm-config.yaml
```

Capturez la sortie dans un fichier journal pour l'audit :

```bash
sudo kubeadm init --config kubeadm-config.yaml 2>&1 | tee kubeadm-init-$(date +%Y%m%d-%H%M%S).log
```

La sortie attendue en cas de succès inclut des messages comme :

```text
Your Kubernetes control-plane has initialized successfully!
...
You can now join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.100:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
```

Enregistrez la commande de jonction de manière sécurisée ; vous en aurez besoin pour ajouter des nœuds de travail. Envisagez de la conserver dans un gestionnaire de mots de passe.

### Configuration post-initialisation

Après l'initialisation, configurez kubectl pour l'utilisateur non root :

```bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

Vérifiez l'accès au cluster :

```bash
kubectl get nodes
```

Attendu : le nœud du plan de contrôle apparaît avec le statut NotReady car aucun réseau de pods n'est encore installé.

## Vérification et diagnostic

La vérification est continue. Après l'initialisation et après tout changement de configuration, effectuez des contrôles pour confirmer que le cluster est sain.

### Vérifier les composants du plan de contrôle

Vérifiez l'état des pods statiques qui forment le plan de contrôle :

```bash
kubectl get pods -n kube-system
```

Sortie attendue : les pods `kube-apiserver-control-plane-1`, `kube-controller-manager-control-plane-1`, `kube-scheduler-control-plane-1` et `etcd-control-plane-1` sont tous en état Running. Si l'un d'eux est Pending ou en CrashLoopBackOff, enquêtez immédiatement.

Inspectez les journaux d'un composant spécifique :

```bash
kubectl logs -n kube-system kube-apiserver-control-plane-1
```

Alternativement, utilisez `crictl` sur le nœud pour voir les journaux des conteneurs si kubectl n'est pas disponible.

### Vérifier l'état de préparation du nœud

Après avoir installé un module de réseau de pods (par exemple, Flannel, Calico), le nœud devrait devenir Ready :

```bash
kubectl get nodes -o wide
```

Attendu : STATUT Ready, avec l'IP interne correspondant à l'adresse annoncée.

### Valider CoreDNS

Les pods CoreDNS doivent être en cours d'exécution et capables de résoudre les noms :

```bash
kubectl get pods -n kube-system -l k8s-app=kube-dns
```

Ensuite, testez le DNS en créant un pod temporaire et en exécutant nslookup à l'intérieur :

```bash
kubectl run -i --tty --rm --restart=Never dns-test --image=busybox:1.28
```

Cela ouvre un shell interactif. À l'intérieur du conteneur, exécutez :

```bash
nslookup kubernetes.default
```

La sortie attendue inclut une adresse IP pour le service. Pour sortir et nettoyer, tapez `exit`.

### Vérifier l'accessibilité du serveur API

Depuis le nœud du plan de contrôle, interrogez le point de terminaison de santé du serveur API :

```bash
curl -k https://localhost:6443/healthz
```

Attendu : `ok`.

### Diagnostiquer les problèmes courants

Si la vérification échoue, utilisez des diagnostics pour identifier le problème.

- **Échec du démarrage de kubelet** : Vérifiez le statut et les journaux de kubelet :

```bash
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 50 --no-pager
```

Causes courantes : swap activé, socket du moteur d'exécution de conteneurs manquante ou pilote cgroup incorrect.

- **Crash du pod du serveur API** : Inspectez les journaux du pod comme indiqué précédemment. Cherchez des erreurs de certificat, des échecs de connexion etcd ou une adresse annoncée mal configurée.

- **Problèmes de réseau** : Assurez-vous que le CIDR du réseau de pods ne chevauche pas le réseau hôte et que le plugin CNI est installé correctement.

Documentez chaque résultat de diagnostic et l'action entreprise.

## Modes de défaillance et récupération

Même avec une planification minutieuse, des échecs surviennent. Cette section décrit les modes de défaillance courants pendant kubeadm init et les étapes de récupération.

### Échec : les contrôles préalables échouent

Kubeadm exécute des contrôles préalables avant d'apporter des modifications. S'ils échouent, il abandonnera avec des messages comme :

```text
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Swap]: running with swap on is not supported. Please disable swap
```

**Récupération** : Corrigez chaque erreur signalée. Pour le swap, désactivez-le :

```bash
sudo swapoff -a
# Rendre permanent en commentant la ligne de swap dans /etc/fstab
```

Puis relancez l'initialisation. Aucun état du cluster n'est modifié car l'initialisation ne s'est pas poursuivie.

### Échec : l'initialisation se termine partiellement

Si l'initialisation échoue à mi-chemin (par exemple, après le démarrage d'etcd mais avant que le serveur API ne soit prêt), le cluster peut être dans un état incohérent. La récupération la plus sûre est de réinitialiser et de recommencer :

```bash
sudo kubeadm reset -f
```

Cela supprime tous les artefacts Kubernetes du nœud. Ensuite, relancez l'initialisation après avoir corrigé la cause racine.

**Vérification** : Après la réinitialisation, vérifiez que les répertoires `/etc/kubernetes/` et `/var/lib/etcd/` sont supprimés ou vides, et qu'aucun processus kubelet n'est en cours d'exécution.

### Échec : certificat expiré ou invalide

Si les certificats sont mal configurés ou expirés, le serveur API peut échouer. Kubeadm gère les certificats automatiquement, mais si vous devez les renouveler sur un cluster existant, utilisez :

```bash
sudo kubeadm certs renew all
```

**Vérification** : Vérifiez les dates d'expiration des certificats :

```bash
sudo kubeadm certs check-expiration
```

### Échec : commande de jonction perdue ou expirée

Le jeton de jonction expire après 24 heures par défaut. Pour générer un nouveau jeton et un nouveau hash :

```bash
sudo kubeadm token create --print-join-command
```

Cela affiche une nouvelle commande de jonction. Utilisez-la sur les nœuds de travail.

**Vérification** : Assurez-vous que le nouveau jeton apparaît dans `kubeadm token list` et n'a pas expiré.

### Documentation de récupération

Tenez un runbook avec les modes de défaillance, les symptômes, les commandes de diagnostic et les étapes de récupération. Pour chaque défaillance, incluez la sortie attendue de la commande de récupération pour confirmer le succès.

## Liste de contrôle opérationnelle

La liste de contrôle suivante résume l'ensemble du cycle de vie des opérations kubeadm init. Utilisez-la avant, pendant et après l'initialisation pour garantir la cohérence.

### Liste de pré-initialisation

- [ ] Confirmer la compatibilité du système d'exploitation (par exemple, Ubuntu 20.04+, CentOS 7+) et la version du noyau `uname -r`.
- [ ] Vérifier que le moteur d'exécution de conteneurs est installé et actif : `sudo systemctl status containerd`.
- [ ] Désactiver le swap : `sudo swapoff -a` et retirer de `/etc/fstab`.
- [ ] Activer les modules noyau requis : `br_netfilter`, overlay ; définir les paramètres sysctl net.ipv4.ip_forward=1, net.bridge.bridge-nf-call-iptables=1.
- [ ] S'assurer que le nom d'hôte se résout et que l'IP est statique.
- [ ] Enregistrer les versions de kubeadm, kubelet, kubectl et vérifier le décalage de compatibilité.
- [ ] Préparer le fichier de configuration kubeadm avec les IP, sous-réseaux et socket CRI corrects.
- [ ] Exécuter `kubeadm init --config ... --dry-run` et examiner la sortie.

### Liste d'exécution de l'initialisation

- [ ] Exécuter la commande d'initialisation et capturer les journaux.
- [ ] Enregistrer la sortie de la commande de jonction de manière sécurisée.
- [ ] Configurer kubectl pour l'utilisateur non root.
- [ ] Installer le module de réseau de pods (par exemple, `kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml`).
- [ ] Attendre que le nœud devienne Ready.

### Liste de vérification post-initialisation

- [ ] `kubectl get nodes` montre le nœud du plan de contrôle Ready.
- [ ] Tous les pods du plan de contrôle Running dans kube-system.
- [ ] Les pods CoreDNS Running.
- [ ] Le pod de test DNS résout `kubernetes.default`.
- [ ] Le point de terminaison de santé du serveur API renvoie `ok`.
- [ ] Vérifier les journaux de kubelet et du moteur d'exécution de conteneurs pour détecter des erreurs.

### Maintenance et prévention de la dérive

- [ ] Exécuter périodiquement `kubeadm certs check-expiration`.
- [ ] Comparer la configuration kubeadm avec l'état réel du cluster pour détecter la dérive.
- [ ] Tenir un journal de tous les changements avec horodatage.
- [ ] Tester le processus de jonction sur un nœud hors production.
- [ ] Documenter toute intervention manuelle pour référence future.

## Conclusion

Opérer kubeadm init en production n'est pas une commande ponctuelle ; c'est un processus qui exige planification, vérification et stratégies de récupération. Cette liste de contrôle fournit une approche structurée pour minimiser les risques et garantir la fiabilité du cluster. En suivant les étapes décrites – de l'inventaire de l'environnement à la vérification post-initialisation et à la récupération en cas d'échec – vous pouvez construire et maintenir un plan de contrôle Kubernetes robuste.

Comme prochaine étape, mettez en œuvre la liste de contrôle dans votre environnement. Commencez par un inventaire en lecture seule, puis procédez à la validation de la configuration avec une simulation, et enfin exécutez l'initialisation avec journalisation et vérification. Documentez vos observations et mettez à jour le runbook à mesure que vous rencontrez de nouveaux modes de défaillance. Avec des opérations disciplinées, vous pouvez garder vos clusters Kubernetes sains et votre équipe confiante.

Rappelez-vous : observez avant de modifier, limitez le rayon d'impact, utilisez des espaces réservés plutôt que des secrets, vérifiez le résultat et documentez comment récupérer.