feat: funk-cluster — arrêt k8s propre avec drain + vérification NFS

Remplace le talosctl shutdown immédiat par une séquence en 6 étapes :
1. kubectl cordon tous les nœuds (empêche rescheduling)
2. kubectl drain compute-02/03 (SIGTERM pods, 30s grace, PVCs NFS libérés)
3. kubectl drain compute-01 (ArgoCD, system pods)
4. Vérification NFS : ss confirme plus de sessions :2049 actives
5. talosctl shutdown (halt propre, plus rien ne tourne)
6. Attente extinction ping

Prometheus et Grafana ont 30s pour flusher WAL/SQLite avant terminaison.
storage-01 (NFS server) est éteint en dernier une fois la vérification passée.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alkatrazz 2026-05-13 22:20:14 +02:00
parent 8b6f906a89
commit a631a4ab6c
2 changed files with 86 additions and 15 deletions

View file

@ -357,31 +357,96 @@ cmd_stop() {
if [ -n "$with_k8s" ]; then
echo ""
echo "[ cluster k8s — arrêt compute-01/02/03 ]"
local alive=()
for ip in "${K8S_IPS[@]}"; do
ping -c1 -W2 "$ip" &>/dev/null && alive+=("$ip")
echo "[ cluster k8s — arrêt propre compute-01/02/03 ]"
# Quels nœuds sont en vie ?
local alive_ips=() alive_names=()
for i in 0 1 2; do
if ping -c1 -W2 "${K8S_IPS[$i]}" &>/dev/null; then
alive_ips+=("${K8S_IPS[$i]}")
alive_names+=("${K8S_NAMES[$i]}")
fi
done
if [ ${#alive[@]} -gt 0 ]; then
local nodes=$(IFS=,; echo "${alive[*]}")
info "talosctl shutdown → $nodes"
if [ ${#alive_ips[@]} -eq 0 ]; then
warn "Nœuds k8s déjà éteints"
else
# 1. Cordon de tous les nœuds — empêche tout rescheduling pendant le drain
info "Cordon (plus aucun pod ne peut être replanifié)..."
for name in "${alive_names[@]}"; do
$KUBECTL cordon "$name" 2>/dev/null \
&& ok "$name — cordonné" \
|| warn "$name — cordon échoué (nœud peut-être inaccessible)"
done
# 2. Drain workers en premier (compute-02, compute-03)
# Les pods reçoivent SIGTERM → flush WAL/SQLite → PVCs NFS démontés
echo ""
info "Drain workers (SIGTERM pods, 30s grace, 90s max)..."
for i in 1 2; do
if ping -c1 -W2 "${K8S_IPS[$i]}" &>/dev/null; then
info " Drain ${K8S_NAMES[$i]}..."
$KUBECTL drain "${K8S_NAMES[$i]}" \
--ignore-daemonsets \
--delete-emptydir-data \
--grace-period=30 \
--timeout=90s \
--force 2>&1 | grep -vE "^(Warning|I[0-9])" | tail -3 || true
ok "${K8S_NAMES[$i]} — pods évacués, PVCs NFS libérés"
fi
done
# 3. Drain control-plane (compute-01) — ArgoCD, kube-state-metrics, etc.
if ping -c1 -W2 "${K8S_IPS[0]}" &>/dev/null; then
echo ""
info "Drain control-plane (compute-01)..."
$KUBECTL drain compute-01 \
--ignore-daemonsets \
--delete-emptydir-data \
--grace-period=30 \
--timeout=90s \
--force 2>&1 | grep -vE "^(Warning|I[0-9])" | tail -3 || true
ok "compute-01 — drainé"
fi
# 4. Vérification NFS : plus aucune session active depuis les nœuds k8s
echo ""
info "Vérification montages NFS..."
local nfs_wait=0
while ss -tn 2>/dev/null | grep ':2049' | grep -qE '10\.1[123]\.'; do
sleep 3; nfs_wait=$((nfs_wait + 3))
[ $nfs_wait -ge 30 ] && break
echo -ne " → NFS encore actif depuis nœuds k8s... ${nfs_wait}s\r"
done; echo ""
if ss -tn 2>/dev/null | grep ':2049' | grep -qE '10\.1[123]\.'; then
warn "Sessions NFS toujours actives après 30s — extinction quand même"
else
ok "NFS libéré — aucune écriture en cours depuis le cluster"
fi
# 5. Extinction via talosctl (kernel halt propre — plus rien ne tourne)
echo ""
local nodes=$(IFS=,; echo "${alive_ips[*]}")
info "talosctl shutdown → ${alive_ips[*]}"
if $TALOSCTL shutdown --nodes "$nodes" 2>/dev/null; then
ok "Shutdown envoyé aux nœuds"
else
warn "Erreur talosctl shutdown — extinction manuelle requise"
return
fi
# 6. Attente extinction complète (ping)
local tries=0
while [ $tries -lt 20 ]; do
local still_up=0
for ip in "${alive[@]}"; do ping -c1 -W1 "$ip" &>/dev/null && still_up=$((still_up + 1)); done
for ip in "${alive_ips[@]}"; do
ping -c1 -W1 "$ip" &>/dev/null && still_up=$((still_up + 1))
done
[ $still_up -eq 0 ] && break
sleep 3; tries=$((tries + 1))
echo -ne " → Extinction k8s... $((tries * 3))s\r"
done; echo ""
ok "Cluster k8s éteint"
else
warn "Nœuds k8s déjà éteints"
ok "Cluster k8s éteint proprement"
fi
fi
@ -429,7 +494,7 @@ case "$CMD" in
echo " start Démarre gpu-01 (WOL) + vérifie tous les services"
echo " start --k8s Idem + démarre le cluster k8s (compute-01/02/03)"
echo " stop Arrêt propre gpu-01 + services storage-01"
echo " stop --k8s Idem + éteint le cluster k8s (talosctl shutdown)"
echo " stop --k8s Idem + arrêt propre k8s (drain → NFS check → talosctl shutdown)"
echo " status État complet (storage-01 + gpu-01 + k8s)"
exit 1
;;