From 727d7351eb881e45cc648775f7dcd9d7336c40e0 Mon Sep 17 00:00:00 2001 From: alkatrazz Date: Wed, 13 May 2026 21:04:39 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20ArgoCD=20+=20monitoring=20=E2=80=94=20d?= =?UTF-8?q?ocumentation=20compl=C3=A8te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - admin/argocd.md (NEW) : installation bootstrap, principe GitOps, structure k8s/, pattern App of Apps, déployer une app/chart Helm, commandes utiles, dépannage (OutOfSync, SSH key, field schema, StatefulSet PVC) - admin/monitoring.md (NEW) : accès+comptes Grafana/Prometheus/AlertManager, architecture scrape, node_exporter storage-01+gpu-01, ROCm sysfs collector, llama-server /metrics, webhook AlertManager→Hermes, admin Grafana+Prometheus, dashboards recommandés, points d'attention (persistence, RAM, Talos) - admin/cluster.md : section GitOps ArgoCD ajoutée - admin/README.md : index mis à jour avec argocd.md et monitoring.md Co-Authored-By: Claude Sonnet 4.6 --- admin/README.md | 2 + admin/argocd.md | 250 ++++++++++++++++++++++++++++++++++++++++++++ admin/cluster.md | 18 ++++ admin/monitoring.md | 229 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 499 insertions(+) create mode 100644 admin/argocd.md create mode 100644 admin/monitoring.md diff --git a/admin/README.md b/admin/README.md index 5b0645b..72b0a89 100644 --- a/admin/README.md +++ b/admin/README.md @@ -28,3 +28,5 @@ | [incidents.md](incidents.md) | Incidents passés — causes, résolutions, fixes permanents | | **Gestion cluster** | | | [cluster.md](cluster.md) | Démarrage / arrêt / status — `funk-start`, `funk-stop`, `funk-stop --k8s` | +| [argocd.md](argocd.md) | ArgoCD GitOps — installation, déploiement d'apps, dépannage | +| [monitoring.md](monitoring.md) | Grafana + Prometheus + AlertManager — accès, comptes, métriques GPU/llama-server, webhook Hermes | diff --git a/admin/argocd.md b/admin/argocd.md new file mode 100644 index 0000000..8cc6c77 --- /dev/null +++ b/admin/argocd.md @@ -0,0 +1,250 @@ +# ArgoCD — GitOps cluster Funk + +ArgoCD est l'opérateur GitOps du cluster. Il surveille le repo `Funk-lab` et +applique automatiquement tout ce qui se trouve dans `k8s/` vers le cluster Kubernetes. + +--- + +## Accès + +| Interface | URL | Login | Mot de passe | +|---|---|---|---| +| UI web | http://argocd.lab.local | `admin` | voir ci-dessous | +| CLI | `argocd` | — | — | + +**Mot de passe initial :** +```bash +kubectl -n argocd get secret argocd-initial-admin-secret \ + -o jsonpath="{.data.password}" | base64 -d && echo +``` + +> Supprimer ce secret après avoir changé le mot de passe : +> `kubectl -n argocd delete secret argocd-initial-admin-secret` + +--- + +## Principe GitOps + +``` +Modifier un fichier dans k8s/ → git commit + git push → ArgoCD détecte (~3 min) → kubectl apply automatique +``` + +**Tu ne fais plus jamais `helm install` ou `kubectl apply` manuellement pour les workloads.** +Tout passe par Git. Le repo est la source de vérité. + +--- + +## Installation (bootstrap — fait une seule fois) + +ArgoCD est bootstrappé manuellement via Helm, puis se gère ensuite lui-même via GitOps. + +```bash +# Ajouter le repo Helm ArgoCD +helm repo add argo https://argoproj.github.io/argo-helm +helm repo update + +# Installer ArgoCD +kubectl create namespace argocd +helm install argocd argo/argo-cd \ + --namespace argocd \ + --version 9.5.14 \ + -f k8s/argocd-bootstrap/values.yaml \ + --wait --timeout 5m + +# Donner accès au repo Git (SSH) +kubectl create secret generic argocd-repo-funk-lab \ + --namespace argocd \ + --from-literal=type=git \ + --from-literal=url=git@github.com:Alkatrazz24/Funk-lab.git \ + --from-file=sshPrivateKey=~/.ssh/id_ed25519 +kubectl label secret argocd-repo-funk-lab \ + -n argocd "argocd.argoproj.io/secret-type=repository" + +# Appliquer l'App of Apps racine +kubectl apply -f k8s/apps-of-apps/root.yaml +``` + +--- + +## Structure GitOps + +``` +k8s/ +├── argocd-bootstrap/ ← values.yaml Helm (bootstrap manuel uniquement) +├── apps-of-apps/ +│ ├── root.yaml ← Application racine (appliquée une seule fois) +│ └── apps/ +│ └── monitoring.yaml ← Application monitoring (créée par root) +└── infra/ + └── monitoring/ ← Manifests déployés par l'app monitoring + ├── namespace.yaml + ├── helmrelease.yaml ← Application kube-prometheus-stack + └── values.yaml +``` + +**Pattern App of Apps :** +- `root` surveille `k8s/apps-of-apps/apps/` → crée les Applications enfants +- Chaque Application enfant surveille son propre répertoire dans `k8s/infra/` ou `k8s/apps/` + +--- + +## Déployer une nouvelle application + +### 1. Créer les manifests + +```bash +mkdir -p k8s/apps/ +vim k8s/apps//deployment.yaml +# ... +``` + +### 2. Créer l'Application ArgoCD + +```bash +cat > k8s/apps-of-apps/apps/.yaml << 'EOF' +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: git@github.com:Alkatrazz24/Funk-lab.git + targetRevision: main + path: k8s/apps/ + destination: + server: https://kubernetes.default.svc + namespace: + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true +EOF +``` + +### 3. Pousser et attendre + +```bash +git add k8s/ +git commit -m "feat: " +git push +# ArgoCD déploie automatiquement en ~3 min +``` + +--- + +## Déployer un chart Helm via ArgoCD (multi-source) + +Pattern pour un chart Helm avec values dans le repo : + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: mon-chart + namespace: argocd +spec: + project: default + sources: + - repoURL: https://charts.exemple.com + chart: mon-chart + targetRevision: 1.2.3 + helm: + valueFiles: + - $values/k8s/infra/mon-chart/values.yaml + - repoURL: git@github.com:Alkatrazz24/Funk-lab.git + targetRevision: main + ref: values + destination: + server: https://kubernetes.default.svc + namespace: mon-namespace + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true +``` + +> **Important :** utiliser `sources` (pluriel) — pas `source` + `sources` en même temps. +> Le champ est `valueFiles` (pas `valuesFiles`). + +--- + +## Commandes utiles + +```bash +# État de toutes les applications +kubectl get applications -n argocd + +# Forcer un refresh (re-lire le repo Git) +kubectl -n argocd annotate application argocd.argoproj.io/refresh=hard --overwrite + +# Logs ArgoCD +kubectl logs -n argocd -l app.kubernetes.io/name=argocd-server --tail=50 +kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller --tail=50 + +# Redémarrer ArgoCD +kubectl rollout restart deployment -n argocd + +# Mettre à jour ArgoCD +helm upgrade argocd argo/argo-cd \ + --namespace argocd \ + --version \ + -f k8s/argocd-bootstrap/values.yaml +``` + +--- + +## Dépannage + +### Application bloquée en OutOfSync + +```bash +kubectl describe application -n argocd | grep -A5 "Message" +# Forcer un hard refresh +kubectl -n argocd annotate application argocd.argoproj.io/refresh=hard --overwrite +``` + +### Erreur "Repository not found" + +La clé SSH n'est pas configurée ou le secret a été supprimé : +```bash +kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=repository +# Recréer si absent (voir section Installation) +``` + +### Erreur "field not declared in schema" sur une Application + +Symptôme : ArgoCD essaie de patcher une ressource Application avec un champ invalide. +Fix : supprimer la ressource ArgoCD et laisser root la recréer depuis le Git corrigé. +```bash +kubectl delete application -n argocd +kubectl -n argocd annotate application root argocd.argoproj.io/refresh=hard --overwrite +``` + +### StatefulSet bloqué par PVC après changement de storageSpec + +Les StatefulSets n'autorisent pas la modification de `volumeClaimTemplates`. +```bash +# Patcher le CRD pour supprimer le storage +kubectl patch -n --type=merge -p '{"spec":{"storage":null}}' +# Supprimer StatefulSet + PVC +kubectl delete statefulset -n +kubectl delete pvc -n --all +``` + +--- + +## Configuration Helm (k8s/argocd-bootstrap/values.yaml) + +- Ingress Traefik sur `argocd.lab.local` +- `server.insecure: true` — TLS terminé par Traefik +- `dex.enabled: false` — pas de SSO pour l'instant +- Resources limitées (128-256 Mi RAM par composant) diff --git a/admin/cluster.md b/admin/cluster.md index e0f55b3..787739d 100644 --- a/admin/cluster.md +++ b/admin/cluster.md @@ -95,6 +95,24 @@ Vérifie dans l'ordre : --- +## GitOps — ArgoCD + +Les workloads k8s sont gérés par ArgoCD. **Ne jamais faire `helm install` ou `kubectl apply` manuellement pour les workloads.** + +```bash +# Déployer quelque chose : modifier k8s/ → git push → ArgoCD applique (~3 min) + +# Vérifier l'état des applications +kubectl get applications -n argocd + +# Forcer un refresh si ArgoCD n'a pas encore détecté un commit +kubectl -n argocd annotate application argocd.argoproj.io/refresh=hard --overwrite +``` + +UI : http://argocd.lab.local — voir [argocd.md](argocd.md) pour la doc complète. + +--- + ## Machines et MACs | Machine | IP | MAC | Rôle | diff --git a/admin/monitoring.md b/admin/monitoring.md new file mode 100644 index 0000000..e6bf625 --- /dev/null +++ b/admin/monitoring.md @@ -0,0 +1,229 @@ +# Monitoring — Grafana + Prometheus + AlertManager + +Stack de monitoring déployée via ArgoCD dans le namespace `monitoring`. +Chart : `kube-prometheus-stack` v85.0.2 (Prometheus Operator). + +--- + +## Accès et comptes + +| Service | URL | Login | Mot de passe | +|---|---|---|---| +| **Grafana** | http://grafana.lab.local | `admin` | `funk-grafana` | +| **AlertManager** | http://alertmanager.lab.local ¹ | — | — | +| **Prometheus** | http://prometheus.lab.local ¹ | — | — | + +¹ Ingress non encore créés — accessible via port-forward : +```bash +kubectl port-forward svc/kube-prometheus-stack-prometheus -n monitoring 9090:9090 +kubectl port-forward svc/kube-prometheus-stack-alertmanager -n monitoring 9093:9093 +``` + +> DNS `*.lab.local` ne résout que depuis le cluster LAN (192.168.10.0/24). +> Depuis le poste perso (192.168.1.x), les entrées sont dans `/etc/hosts` : +> ``` +> 192.168.10.200 grafana.lab.local argocd.lab.local +> ``` + +--- + +## Architecture + +``` +Prometheus (k8s, namespace monitoring) + ├── kube-state-metrics → ressources k8s (pods, deployments, nodes) + ├── node-exporter (daemonset) → métriques système compute-01/02/03 + ├── scrape storage-01:9100 → métriques système storage-01 + ├── scrape gpu-01:9100 → métriques système gpu-01 + ├── scrape gpu-01:9101 (ROCm) → température GPU, VRAM, utilisation + └── scrape gpu-01:1234/1236/1237 → llama-server (tokens/s, slots, queue) + ↓ +AlertManager + └── webhook → storage-01:9093/webhook → ask-agent monitor → Hermes profil monitor +``` + +--- + +## Installation (déjà faite via ArgoCD) + +Le monitoring est géré par ArgoCD. Pour le redéployer depuis zéro : + +```bash +# Ajouter le repo Helm +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update + +# L'application est créée automatiquement par ArgoCD depuis k8s/infra/monitoring/ +# Forcer un refresh si nécessaire : +kubectl -n argocd annotate application kube-prometheus-stack \ + argocd.argoproj.io/refresh=hard --overwrite +``` + +--- + +## Sources de métriques + +### Nœuds hors cluster (storage-01, gpu-01) + +`node_exporter` v1.9.1 déployé via Ansible (rôle `node_exporter`). + +```bash +# Vérifier node_exporter +systemctl status node_exporter +curl -s http://192.168.10.1:9100/metrics | grep node_memory_MemAvailable +curl -s http://192.168.10.20:9100/metrics | grep node_memory_MemAvailable +``` + +### Métriques GPU AMD (gpu-01) + +Collecteur sysfs via `rocm_scraper.timer` (toutes les 30s). +Lit directement `/sys/class/drm/card0/device/` — pas de dépendance `rocm-smi`. + +```bash +# Vérifier les métriques ROCm +ssh ansible@192.168.10.20 "cat /var/lib/node_exporter/textfile_collector/rocm.prom" + +# Forcer une collecte manuelle +ssh ansible@192.168.10.20 "sudo systemctl start rocm_scraper" +``` + +Métriques disponibles : +| Métrique | Description | +|---|---| +| `rocm_gpu_temperature_celsius` | Température (°C) | +| `rocm_gpu_utilization_percent` | Utilisation GPU (%) | +| `rocm_vram_used_bytes` | VRAM utilisée (bytes) | +| `rocm_vram_total_bytes` | VRAM totale (bytes) | + +### llama-server /metrics + +llama.cpp expose des métriques Prometheus nativement sur `/metrics` : +- `llamacpp:kv_cache_usage_ratio` — utilisation du contexte +- `llamacpp:requests_processing` — requêtes en cours +- `llamacpp:tokens_per_second` — débit + +```bash +curl -s http://192.168.10.20:1234/metrics | grep llamacpp +``` + +--- + +## AlertManager → Hermes monitor + +AlertManager envoie les alertes en POST vers `http://192.168.10.1:9093/webhook`. +Le service `alertmanager-webhook` (Python, storage-01) reçoit les alertes et appelle : + +```bash +ask-agent monitor "Alertes Prometheus : — analyse et recommandations" +``` + +Hermes (profil `monitor`) analyse et répond dans ses logs. + +```bash +# Vérifier le webhook +systemctl status alertmanager-webhook +journalctl -u alertmanager-webhook -n 20 --no-pager --output=cat + +# Tester manuellement +curl -s -X POST http://192.168.10.1:9093/webhook \ + -H "Content-Type: application/json" \ + -d '{"alerts":[{"status":"firing","labels":{"alertname":"TestAlert","severity":"warning","instance":"storage-01"},"annotations":{"summary":"Test alerte","description":"Vérification du webhook"}}]}' +``` + +--- + +## Administration Grafana + +### Changer le mot de passe admin + +```bash +# Via l'API +curl -X PUT http://admin:funk-grafana@grafana.lab.local/api/user/password \ + -H "Content-Type: application/json" \ + -d '{"oldPassword":"funk-grafana","newPassword":"","confirmNew":""}' +``` + +Ou mettre à jour `k8s/infra/monitoring/values.yaml` → `grafana.adminPassword` → `git push`. + +### Importer un dashboard + +```bash +# Via l'API (ID depuis grafana.com/dashboards) +curl -X POST http://admin:funk-grafana@grafana.lab.local/api/dashboards/import \ + -H "Content-Type: application/json" \ + -d '{"dashboard":{"id":null},"overwrite":true,"inputs":[{"name":"DS_PROMETHEUS","type":"datasource","pluginId":"prometheus","value":"prometheus"}],"folderId":0}' +``` + +Dashboards recommandés : +| Dashboard | ID Grafana.com | Usage | +|---|---|---| +| Node Exporter Full | 1860 | CPU, RAM, disque, réseau par nœud | +| Kubernetes cluster | 7249 | Vue d'ensemble k8s | +| kube-prometheus-stack | 15761 | Santé du monitoring lui-même | + +### Datasources configurées automatiquement + +| Nom | Type | URL | +|---|---|---| +| Prometheus | prometheus | `http://kube-prometheus-stack-prometheus:9090` | +| Alertmanager | alertmanager | `http://kube-prometheus-stack-alertmanager:9093` | + +--- + +## Administration Prometheus + +### Vérifier les targets de scrape + +```bash +# Via port-forward +kubectl port-forward svc/kube-prometheus-stack-prometheus -n monitoring 9090:9090 & +curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool | grep -E '"health"|"job"' | head -30 +``` + +### Ajouter un scrape config + +Modifier `k8s/infra/monitoring/values.yaml` → section `additionalScrapeConfigs` → `git push`. + +### Règles d'alerte + +Les règles par défaut couvrent : OOMKill, NodeNotReady, PodCrashLooping, DiskPressure, etc. +Pour ajouter des règles custom, créer un `PrometheusRule` dans `k8s/infra/monitoring/`. + +--- + +## Commandes d'administration + +```bash +# État de tous les pods monitoring +kubectl get pods -n monitoring + +# Logs Prometheus +kubectl logs -n monitoring prometheus-kube-prometheus-stack-prometheus-0 -c prometheus --tail=50 + +# Logs Grafana +kubectl logs -n monitoring -l app.kubernetes.io/name=grafana --tail=50 + +# Logs AlertManager +kubectl logs -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0 --tail=50 + +# Redémarrer Grafana +kubectl rollout restart deployment kube-prometheus-stack-grafana -n monitoring + +# Forcer re-sync ArgoCD +kubectl -n argocd annotate application kube-prometheus-stack \ + argocd.argoproj.io/refresh=hard --overwrite +``` + +--- + +## Points d'attention + +| Sujet | Détail | +|---|---| +| Persistance Prometheus | Désactivée (emptyDir) — données perdues au redémarrage du pod. Installer Longhorn pour activer | +| Persistance Grafana | Désactivée — dashboards custom perdus au redémarrage. Exporter en JSON ou activer Longhorn | +| RAM compute nodes | Prometheus + Grafana : ~1 GB total. Limites définies dans values.yaml | +| Talos — composants désactivés | `kubeEtcd`, `kubeScheduler`, `kubeControllerManager`, `kubeProxy` désactivés (non accessibles depuis Talos) | +| DNS lab.local | Résout uniquement depuis LAN (192.168.10.0/24) — ajouter `/etc/hosts` sur le poste perso pour grafana/argocd | +| ROCm scraper | Lit sysfs directement (`/sys/class/drm/`), pas de `rocm-smi` (retiré dans ROCm 7.x) | +| Webhook port 9093 | Ouvert uniquement depuis 192.168.10.0/24 (nftables storage-01) |