From 494184b025803df2dcdbd5f5bd7061693e6aa884 Mon Sep 17 00:00:00 2001 From: alkatrazz Date: Thu, 14 May 2026 17:54:18 +0200 Subject: [PATCH] feat(funk-cluster): check k8s pod health in funk-start et funk-status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute check_k8s_pods / check_k8s_workloads (argocd, infra, monitoring). funk-start vérifie désormais les pods k8s si les nœuds sont joignables, même sans --k8s. En mode --k8s : attente ArgoCD + infra avant le check. funk-status montre aussi l'état des pods si cluster up. Co-Authored-By: Claude Sonnet 4.6 --- ansible/roles/litellm/files/funk-cluster | 80 +++++++++++++++++++++--- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/ansible/roles/litellm/files/funk-cluster b/ansible/roles/litellm/files/funk-cluster index a0c418f..1c2e89f 100644 --- a/ansible/roles/litellm/files/funk-cluster +++ b/ansible/roles/litellm/files/funk-cluster @@ -150,6 +150,34 @@ check_k8s() { fi } +check_k8s_pods() { + local ns=$1 label=$2 + local total running + total=$($KUBECTL get pods -n "$ns" --no-headers 2>/dev/null | wc -l) + running=$($KUBECTL get pods -n "$ns" --no-headers 2>/dev/null | grep -c "^[^ ]* *[0-9]*/[0-9]* *Running" || echo 0) + + if [ "$total" -eq 0 ]; then + warn "$label — namespace vide ou inaccessible" + return + fi + + if [ "$running" -eq "$total" ]; then + check_ok "$label — $running/$total Running" + else + check_fail "$label — $running/$total Running" + $KUBECTL get pods -n "$ns" --no-headers 2>/dev/null \ + | grep -v " Running " \ + | awk '{printf " %-45s %s\n", $1, $3}' \ + | head -6 + fi +} + +check_k8s_workloads() { + check_k8s_pods "argocd" "ArgoCD" + check_k8s_pods "infra" "Infra (Traefik · MetalLB · NFS)" + check_k8s_pods "monitoring" "Monitoring (Grafana · Prometheus · AlertManager)" +} + wait_ping() { local host=$1 timeout=${2:-120} elapsed=0 while ! ping -c1 -W1 "$host" &>/dev/null; do @@ -230,6 +258,20 @@ cmd_status() { fi check_k8s + + # Pods si au moins un nœud est joignable + local k8s_up=0 + for ip in "${K8S_IPS[@]}"; do ping -c1 -W2 "$ip" &>/dev/null && k8s_up=$((k8s_up + 1)); done + if [ $k8s_up -gt 0 ]; then + local ready + ready=$($KUBECTL get nodes --no-headers 2>/dev/null | grep -c " Ready" || echo 0) + if [ "$ready" -gt 0 ]; then + echo "" + echo "[ cluster k8s — pods ]" + check_k8s_workloads + fi + fi + print_score echo "" } @@ -305,11 +347,11 @@ cmd_start() { wait_llama 1236 120; check_llama_server 1236 "CPU1 (Qwen3-1.7B system)" wait_llama 1237 60; check_llama_server 1237 "CPU2 (Qwen3-1.7B monitor)" + # ---- Boot k8s si --k8s ---- if [ -n "$with_k8s" ]; then echo "" echo "[ cluster k8s — démarrage compute-01/02/03 ]" - # Envoi WOL pour les nœuds éteints for i in 0 1 2; do local ip="${K8S_IPS[$i]}" name="${K8S_NAMES[$i]}" mac="${K8S_MACS[$i]}" if ping -c1 -W2 "$ip" &>/dev/null; then @@ -320,13 +362,11 @@ cmd_start() { fi done - # Attente ping info "Attente ping des nœuds..." for ip in "${K8S_IPS[@]}"; do wait_ping "$ip" 120 && ok "$ip joignable" || warn "$ip n'a pas répondu" done - # Attente nœuds Ready (kubelet enregistré + CNI ok) info "Attente nœuds Ready (jusqu'à 3 min)..." local k8s_elapsed=0 until [ "$($KUBECTL get nodes --no-headers 2>/dev/null | grep -c " Ready" || echo 0)" -ge 3 ] \ @@ -340,7 +380,6 @@ cmd_start() { || warn "Nœuds pas encore Ready (vérifier avec kubectl get nodes)" # Uncordon — les nœuds restent SchedulingDisabled après un funk-stop --k8s - # Sans ça, ArgoCD déploie des pods qui restent Pending indéfiniment echo "" info "Uncordon des nœuds (autorise le scheduling des pods)..." local uncordoned=0 @@ -352,7 +391,7 @@ cmd_start() { done [ $uncordoned -eq 0 ] && ok "Nœuds déjà schedulables (pas de cordon résiduel)" - # Attente ArgoCD opérationnel (signe que les workloads peuvent se déployer) + # Attente ArgoCD opérationnel echo "" info "Attente ArgoCD opérationnel (jusqu'à 3 min)..." local argocd_elapsed=0 @@ -362,10 +401,33 @@ cmd_start() { sleep 10; argocd_elapsed=$((argocd_elapsed + 10)) echo -ne " → Attente ArgoCD... ${argocd_elapsed}s\r" done; echo "" - local argocd_pods="$($KUBECTL get pods -n argocd --no-headers 2>/dev/null | grep -c "Running" || echo 0)" - [ "$argocd_pods" -ge 1 ] \ - && check_ok "ArgoCD — $argocd_pods pod(s) Running (GitOps opérationnel)" \ - || warn "ArgoCD pas encore prêt — workloads k8s en cours de déploiement" + + # Attente pods infra + monitoring (Traefik peut prendre ~1 min après ArgoCD) + info "Attente pods infra (jusqu'à 2 min)..." + local infra_elapsed=0 + until [ "$($KUBECTL get pods -n infra --no-headers 2>/dev/null \ + | grep -c "Running" || echo 0)" -ge 2 ] \ + || [ $infra_elapsed -ge 120 ]; do + sleep 10; infra_elapsed=$((infra_elapsed + 10)) + echo -ne " → Attente infra... ${infra_elapsed}s\r" + done; echo "" + fi + + # ---- Vérification pods k8s (toujours si nœuds joignables) ---- + local k8s_up=0 + for ip in "${K8S_IPS[@]}"; do ping -c1 -W2 "$ip" &>/dev/null && k8s_up=$((k8s_up + 1)); done + + if [ $k8s_up -gt 0 ]; then + local ready + ready=$($KUBECTL get nodes --no-headers 2>/dev/null | grep -c " Ready" || echo 0) + echo "" + echo "[ cluster k8s — santé pods ]" + if [ "$ready" -gt 0 ]; then + check_ok "Nœuds — $ready/3 Ready" + check_k8s_workloads + else + warn "Nœuds joignables mais pas encore Ready" + fi fi print_score