@@ -6,7 +6,6 @@
|
||||
set -e
|
||||
|
||||
# --- Détermination du rôle du nœud ---
|
||||
# Priorité : option --role > argument positionnel > autodetect via hostname
|
||||
NODE_ROLE=""
|
||||
|
||||
usage() {
|
||||
@@ -17,7 +16,6 @@ usage() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parsing des arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--role)
|
||||
@@ -37,14 +35,13 @@ while [[ $# -gt 0 ]]; do
|
||||
esac
|
||||
done
|
||||
|
||||
# Autodetect si aucun rôle fourni
|
||||
if [[ -z "$NODE_ROLE" ]]; then
|
||||
if [[ "$(hostname)" == *"master"* ]] || [[ "$(hostname)" == *"control"* ]]; then
|
||||
NODE_ROLE="master"
|
||||
echo "Autodetect: rôle 'master' détecté via hostname ($(hostname))"
|
||||
else
|
||||
NODE_ROLE="worker"
|
||||
echo "Autodetect: rôle 'worker' (hostname: $(hostname) ne contient pas 'master'/'control')"
|
||||
echo "Autodetect: rôle 'worker' (hostname: $(hostname))"
|
||||
fi
|
||||
else
|
||||
echo "Rôle: '$NODE_ROLE' (explicite)"
|
||||
@@ -53,75 +50,113 @@ fi
|
||||
echo "=== Installation des pré-requis Kubernetes sur CentOS 10 [rôle: $NODE_ROLE] ==="
|
||||
|
||||
# Désactiver le swap (requis par Kubernetes)
|
||||
# POURQUOI: Kubernetes doit connaître la RAM réelle disponible pour le scheduling.
|
||||
# Le swap introduit des latences imprévisibles et fausse les limites mémoire des pods.
|
||||
echo "Désactivation du swap..."
|
||||
sudo swapoff -a
|
||||
sudo sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
|
||||
# Désactiver SELinux (mode permissive pour le TD)
|
||||
# POURQUOI: Simplifie le troubleshooting. En production, utiliser SELinux enforcing
|
||||
# avec les policies container-selinux appropriées.
|
||||
echo "Configuration de SELinux en mode permissive..."
|
||||
sudo setenforce 0 || true
|
||||
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||||
# Installer container-selinux AVANT containerd pour que les labels SELinux soient corrects
|
||||
# POURQUOI: container-selinux fournit la policy qui confine chaque container dans le label
|
||||
# container_t — un container compromis ne peut pas lire /etc/passwd ni écrire
|
||||
# dans les répertoires système de l'hôte, même en root dans le container.
|
||||
echo "Installation de container-selinux..."
|
||||
sudo dnf install -y container-selinux
|
||||
|
||||
# Maintenir SELinux en mode enforcing
|
||||
# POURQUOI: Le mode permissive ne fait que logger les violations sans les bloquer —
|
||||
# c'est une fausse sécurité. En enforcing + container-selinux, les appels
|
||||
# système non autorisés depuis les containers sont bloqués au niveau kernel.
|
||||
echo "Vérification SELinux en mode enforcing..."
|
||||
sudo setenforce 1 || true
|
||||
SELINUX_CURRENT=$(getenforce 2>/dev/null || echo "Unknown")
|
||||
if [[ "$SELINUX_CURRENT" != "Enforcing" ]]; then
|
||||
echo "ATTENTION: SELinux n'est pas en mode Enforcing (actuel: $SELINUX_CURRENT)"
|
||||
echo "Vérifier /etc/selinux/config — SELINUX doit être 'enforcing'"
|
||||
fi
|
||||
|
||||
# Charger les modules kernel nécessaires
|
||||
# POURQUOI:
|
||||
# - overlay: Système de fichiers pour les layers des containers (utilisé par containerd)
|
||||
# - br_netfilter: Permet à iptables/nftables de voir le trafic bridgé (nécessaire pour CNI)
|
||||
# overlay, br_netfilter : requis par containerd et le CNI
|
||||
# ip_vs, ip_vs_rr/rr/wrr/sh : requis par Cilium en mode kube-proxy replacement (IPVS)
|
||||
# nf_conntrack : suivi des connexions réseau (requis par iptables/eBPF)
|
||||
echo "Configuration des modules kernel..."
|
||||
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
|
||||
overlay
|
||||
br_netfilter
|
||||
ip_vs
|
||||
ip_vs_rr
|
||||
ip_vs_wrr
|
||||
ip_vs_sh
|
||||
nf_conntrack
|
||||
EOF
|
||||
|
||||
sudo modprobe overlay
|
||||
sudo modprobe br_netfilter
|
||||
sudo modprobe ip_vs
|
||||
sudo modprobe ip_vs_rr
|
||||
sudo modprobe ip_vs_wrr
|
||||
sudo modprobe ip_vs_sh
|
||||
sudo modprobe nf_conntrack 2>/dev/null || sudo modprobe nf_conntrack_ipv4 2>/dev/null || true
|
||||
|
||||
# Configuration sysctl pour le réseau
|
||||
# POURQUOI:
|
||||
# - bridge-nf-call-iptables: Le trafic bridgé passe par iptables (requis par kube-proxy)
|
||||
# - ip_forward: Active le routage IP entre interfaces (requis par CNI pour pod-to-pod)
|
||||
# Configuration sysctl
|
||||
# bridge-nf-call-iptables/ip6tables : trafic bridgé traité par iptables (requis CNI)
|
||||
# ip_forward : routage IP entre interfaces (requis pod-to-pod)
|
||||
# rp_filter=0 : Cilium eBPF requiert que le reverse path filtering soit désactivé
|
||||
# inotify params : requis par Cilium pour surveiller les changements de configuration
|
||||
echo "Configuration sysctl..."
|
||||
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
|
||||
net.ipv4.conf.all.rp_filter = 0
|
||||
fs.inotify.max_user_watches = 524288
|
||||
fs.inotify.max_user_instances = 512
|
||||
EOF
|
||||
|
||||
sudo sysctl --system
|
||||
|
||||
# Désactiver firewalld
|
||||
# POURQUOI: Sur Exoscale (et la plupart des cloud providers), le filtrage réseau est
|
||||
# géré par les security groups au niveau hyperviseur. firewalld actif en doublon
|
||||
# bloque le trafic inter-pods (VXLAN UDP 4789, BGP TCP 179, etc.) localement
|
||||
# sur le nœud, même si le security group l'autorise.
|
||||
echo "Désactivation de firewalld (géré par le security group Exoscale)..."
|
||||
sudo systemctl stop firewalld 2>/dev/null || true
|
||||
sudo systemctl disable firewalld 2>/dev/null || true
|
||||
echo " ✓ firewalld désactivé"
|
||||
# Configurer firewalld avec les règles Kubernetes
|
||||
# POURQUOI: Désactiver firewalld entièrement supprime toute isolation réseau au niveau hôte.
|
||||
# Si un pod bypass le CNI (via un exploit), firewalld local est la dernière barrière.
|
||||
# Defense in depth : security group cloud + firewalld hôte + NetworkPolicy CNI.
|
||||
echo "Configuration de firewalld avec les règles Kubernetes..."
|
||||
sudo systemctl enable firewalld
|
||||
sudo systemctl start firewalld
|
||||
|
||||
if [[ "$NODE_ROLE" == "master" ]]; then
|
||||
echo " Règles control plane..."
|
||||
sudo firewall-cmd --permanent --add-port=6443/tcp # API server
|
||||
sudo firewall-cmd --permanent --add-port=2379-2380/tcp # etcd client + peer
|
||||
sudo firewall-cmd --permanent --add-port=10257/tcp # kube-controller-manager
|
||||
sudo firewall-cmd --permanent --add-port=10259/tcp # kube-scheduler
|
||||
fi
|
||||
|
||||
echo " Règles communes (kubelet + réseau)..."
|
||||
sudo firewall-cmd --permanent --add-port=10250/tcp # kubelet API
|
||||
sudo firewall-cmd --permanent --add-port=30000-32767/tcp # NodePort services
|
||||
sudo firewall-cmd --permanent --add-port=53/tcp # DNS (CoreDNS)
|
||||
sudo firewall-cmd --permanent --add-port=53/udp # DNS (CoreDNS)
|
||||
|
||||
echo " Règles Cilium..."
|
||||
sudo firewall-cmd --permanent --add-port=4240/tcp # Cilium health checks
|
||||
sudo firewall-cmd --permanent --add-port=4244/tcp # Hubble server
|
||||
sudo firewall-cmd --permanent --add-port=4245/tcp # Hubble relay
|
||||
sudo firewall-cmd --permanent --add-port=51871/udp # WireGuard (chiffrement inter-nœuds)
|
||||
sudo firewall-cmd --permanent --add-port=8472/udp # VXLAN (fallback)
|
||||
|
||||
sudo firewall-cmd --permanent --add-masquerade
|
||||
sudo firewall-cmd --reload
|
||||
echo " ✓ firewalld configuré"
|
||||
|
||||
# Installation de containerd depuis le repo Docker
|
||||
# POURQUOI: containerd.io du repo Docker est plus récent et mieux maintenu que celui des repos CentOS
|
||||
echo "Ajout du repo Docker pour containerd..."
|
||||
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
|
||||
echo "Installation de containerd..."
|
||||
sudo dnf install -y containerd.io
|
||||
|
||||
# Configuration de containerd
|
||||
sudo mkdir -p /etc/containerd
|
||||
containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
|
||||
|
||||
# Activer systemd cgroup driver (OBLIGATOIRE pour kubeadm)
|
||||
# POURQUOI: CentOS 10 utilise systemd comme init system et gestionnaire de cgroups v2.
|
||||
# Le kubelet utilise aussi systemd cgroup driver par défaut depuis K8s 1.22+.
|
||||
# Si containerd et kubelet utilisent des drivers différents (cgroupfs vs systemd):
|
||||
# - Conflits de gestion mémoire
|
||||
# - Pods qui ne démarrent pas ou crashent
|
||||
# - Métriques incorrectes
|
||||
# - Comportement OOM imprévisible
|
||||
echo "Activation du driver cgroup systemd pour containerd..."
|
||||
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
|
||||
|
||||
@@ -144,31 +179,48 @@ if [[ "$NODE_ROLE" == "master" ]]; then
|
||||
echo "Installation de kubeadm, kubelet, kubectl (control plane)..."
|
||||
sudo dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
|
||||
else
|
||||
echo "Installation de kubeadm, kubelet (worker — kubectl non requis)..."
|
||||
echo "Installation de kubeadm, kubelet (worker)..."
|
||||
sudo dnf install -y kubelet kubeadm --disableexcludes=kubernetes
|
||||
fi
|
||||
|
||||
# Verrouiller les versions pour éviter les mises à jour accidentelles
|
||||
# POURQUOI: Une mise à jour non planifiée de kubelet peut casser le cluster.
|
||||
# L'upgrade doit être fait de manière contrôlée via kubeadm upgrade.
|
||||
echo "Verrouillage des versions..."
|
||||
sudo dnf install -y 'dnf-command(versionlock)' 2>/dev/null || true
|
||||
if [[ "$NODE_ROLE" == "master" ]]; then
|
||||
sudo dnf versionlock add kubelet kubeadm kubectl 2>/dev/null || echo "Note: versionlock non disponible, pensez à surveiller les mises à jour"
|
||||
sudo dnf versionlock add kubelet kubeadm kubectl 2>/dev/null || echo "Note: versionlock non disponible"
|
||||
else
|
||||
sudo dnf versionlock add kubelet kubeadm 2>/dev/null || echo "Note: versionlock non disponible, pensez à surveiller les mises à jour"
|
||||
sudo dnf versionlock add kubelet kubeadm 2>/dev/null || echo "Note: versionlock non disponible"
|
||||
fi
|
||||
|
||||
# Installer Helm sur le master (requis pour Cilium, KubeArmor, Kyverno)
|
||||
if [[ "$NODE_ROLE" == "master" ]]; then
|
||||
if ! command -v helm &>/dev/null; then
|
||||
echo "Installation de Helm..."
|
||||
HELM_VERSION="v3.17.3"
|
||||
curl -L "https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz" -o /tmp/helm.tar.gz
|
||||
tar -xzf /tmp/helm.tar.gz -C /tmp
|
||||
sudo mv /tmp/linux-amd64/helm /usr/local/bin/helm
|
||||
rm -rf /tmp/linux-amd64 /tmp/helm.tar.gz
|
||||
echo " ✓ Helm ${HELM_VERSION} installé"
|
||||
else
|
||||
echo " ✓ Helm déjà installé: $(helm version --short)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Activer kubelet
|
||||
sudo systemctl enable kubelet
|
||||
|
||||
echo ""
|
||||
echo "=== Vérifications ==="
|
||||
echo "Swap désactivé: $(free -h | grep Swap | awk '{print $2}') (doit être 0)"
|
||||
echo "SELinux: $(getenforce)"
|
||||
echo "Modules kernel: $(lsmod | grep -E 'overlay|br_netfilter' | wc -l)/2 chargés"
|
||||
SELINUX_STATUS=$(getenforce 2>/dev/null || echo "Unknown")
|
||||
if [[ "$SELINUX_STATUS" == "Enforcing" ]]; then
|
||||
echo "SELinux: $SELINUX_STATUS ✓"
|
||||
else
|
||||
echo "SELinux: $SELINUX_STATUS ⚠ ATTENTION: doit être Enforcing"
|
||||
fi
|
||||
echo "Modules kernel: $(lsmod | grep -E 'overlay|br_netfilter|ip_vs|nf_conntrack' | wc -l)/7 chargés"
|
||||
echo "firewalld: $(systemctl is-active firewalld)"
|
||||
echo "containerd: $(systemctl is-active containerd)"
|
||||
echo "SystemdCgroup: $(grep 'SystemdCgroup = true' /etc/containerd/config.toml > /dev/null && echo 'activé' || echo 'ATTENTION: non activé!')"
|
||||
echo "SystemdCgroup: $(grep 'SystemdCgroup = true' /etc/containerd/config.toml > /dev/null && echo 'activé ✓' || echo 'ATTENTION: non activé!')"
|
||||
echo ""
|
||||
echo "✓ Pré-requis installés avec succès!"
|
||||
echo "Version kubeadm: $(kubeadm version -o short)"
|
||||
@@ -176,3 +228,6 @@ echo "Version kubelet: $(kubelet --version)"
|
||||
if command -v kubectl &>/dev/null; then
|
||||
echo "Version kubectl: $(kubectl version --client -o yaml | grep gitVersion)"
|
||||
fi
|
||||
if command -v helm &>/dev/null; then
|
||||
echo "Version helm: $(helm version --short)"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user