Introducció

Executar un cluster K3s que serveix models d’IA 24/7 ens ha ensenyat molt sobre les realitats operatives. Aquesta entrada documenta les incidències que hem patit, les lliçons après i els llibres de manual operatives que ara mantenen les coses funcionant de manera suau.

Cronologia d’Incidències

Incidència #1: GPU OOM en la Càrrega de Models

Data: 2026-06-15 Severitat: P2 (interrupció parcial) Durada: 45 minuts

Què va passar: Una actualització de model va augmentar els requisits de VRAM. El pod de LiteLLM va fallar repetidament amb OOMKilled a la memòria de GPU.

Causa arrel: Els límits de recursos es van establir en base als requisits del model antic. El nou model Nemotron-4 necessitava ~20 GB de VRAM, però el límit del contenidor estava fixat a 16 GB.

Resolució:

# Updated resource limits
resources:
  limits:
    nvidia.com/gpu: "1"
    memory: "24Gi"  # Increased from 16Gi

Lliçó: Els límits de memòria de GPU han de coincidir exactament amb els requisits del model. Afegiu una alerta de monitoratge per a la memòria de GPU al 90% de capacitat.

Incidència #2: Inflació de la Base de Dades etcd

Data: 2026-06-28 Severitat: P3 (rendiment degradat) Durada: 2 hores

Què va passar: El pla de control de K3s es va aturar. Els temps de resposta de l’API van passar de 50ms a 3000ms+.

Causa arrel: La base de dades etcd va excedir el llindal de compactació per defecte. Amb desplegaments de CronJob freqüents, el compte d’objectes va créixer ràpidament.

Resolució:

# Check etcd size
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/var/lib/rancher/k3s/server/tls/etcd/ca.crt \
  --cert=/var/lib/rancher/k3s/server/tls/etcd/server.crt \
  --key=/var/lib/rancher/k3s/server/tls/etcd/server.key \
  endpoint health

# Trigger compaction
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/var/lib/rancher/k3s/server/tls/etcd/ca.crt \
  --cert=/var/lib/rancher/k3s/server/tls/etcd/server.crt \
  --key=/var/lib/rancher/k3s/server/tls/etcd/server.key \
  defrag

# Check etcd status
kubectl get etcdmembers.etcd.database.coreos.com -n k3s

Lliçó: Configureu còpies de seguretat i compactació d’etcd automatitzades. Monitoreu la mida de la base de dades etcd amb una alerta de Grafana a 500 MB.

Incidència #3: Bloqueig de Política de Xarxa

Data: 2026-07-05 Severitat: P1 (interrupció completa) Durada: 30 minuts

Què va passar: Tots els pod d’agents no podien arribar al gateway de LiteLLM.

Causa arrel: Una actualització de NetworkPolicy va bloquejar per error el trànsit des de l’espai de noms forgejo-runners a ia-services-payed.

Resolució:

# Temporary fix: remove the policy
kubectl delete networkpolicy litellm-policy -n ia-services-payed

# Verify connectivity
kubectl run --rm -it --restart=Never --namespace=forgejo-runners \
  temp-test --image=busybox -- \
  wget -qO- --timeout=5 http://litellm.ia-services-payed.svc.cluster.local:4000/health

Lliçó: Proveu sempre els canvis de NetworkPolicy primer en un espai de noms d’encesa. Utilitzeu un enfocament de negació per defecte i afegiu regles de permís una per una.

Estratègia de Còpia de Seguretat

Còpies de Seguretat d’etcd

K3s proporciona còpia de seguretat integrada d’etcd a emmagatzematge compatible amb S3:

# Manual backup
kubectl exec -n k3s k3s-server-0 -- k3s etcd-snapshot save \
  /backup/k3s-etcd-$(date +%Y%m%d).db

# Automated with crontab
0 3 * * * /usr/local/bin/k3s-backup.sh

El script de còpia de seguretat:

#!/bin/bash
set -euo pipefail

DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/k3s-etcd"
S3_BUCKET="s3://company-backups/k3s-etcd"

mkdir -p "$BACKUP_DIR"

# Create snapshot
kubectl exec -n k3s k3s-server-0 -- \
  k3s etcd-snapshot save "${BACKUP_DIR}/k3s-etcd-${DATE}.db"

# Upload to S3
aws s3 cp "${BACKUP_DIR}/k3s-etcd-${DATE}.db" "${S3_BUCKET}/"

# Clean old backups (keep 30 days)
aws s3 ls "${S3_BUCKET}/" --recursive \
  --expires $(date -d '30 days ago' +%Y-%m-%d) \
  | awk '{print $NF}' | xargs -r aws s3 rm

Còpia de Seguretat de Models

Els pesos de models han de fer-se còpia de seguretat per separat:

#!/bin/bash
# backup-models.sh

MODEL_DIR="/data/model-registry"
BACKUP_DIR="/backup/models"

rsync -avz --delete "$MODEL_DIR/" "$BACKUP_DIR/models-$(date +%Y%m%d)/"

# Verify backup
echo "Backup size: $(du -sh "$BACKUP_DIR/models-$(date +%Y%m%d)/" | cut -f1)"

Recuperació de Desastre

Proveu la recuperació trimestralment:

# 1. Create a test cluster on a different node
curl -sfL https://get.k3s.io | K3S_TOKEN=$(cat /var/lib/rancher/k3s/server/node-token) sh -

# 2. Restore etcd from backup
kubectl exec -n k3s k3s-server-0 -- \
  k3s etcd-snapshot restore --dir=/backup/k3s-etcd/latest \
  /var/lib/rancher/k3s/server/db

# 3. Verify services
kubectl get pods -A
kubectl logs -n ia-services-payed -l app=litellm --tail=10

Estratègia d’Escalat

Escalat Vertical (Ja En Execució)

Quan els recursos d’un sol node s’agoten:

  1. Afegir memòria de GPU: millorar de L4 (24 GB) a A100 (80 GB)
  2. Afegir RAM: augmentar de 32 GB a 64 GB
  3. Afegir emmagatzematge: millora NVMe per al registre de models

Escalat Horitzontal (Múltiples Nodes)

Quan el volum de sol·licituds concurrents excedeix la capacitat:

# Add a second GPU node
apiVersion: v1
kind: Node
metadata:
  name: gx10-db4d-02
  labels:
    nvidia.com/gpu.deploy-gpu-feature: "true"
    ai-workload: "true"
  taints:
  - key: nvidia.com/gpu
    effect: NoSchedule
    value: present

Actualitzeu el GPU Operator per reconèixer el nou node — hauria d’autodescobrir la GPU i instal·lar el plugin de dispositius.

Escalat Automàtic amb KEDA

Escaleu LiteLLM en base a la cua de sol·licituds:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: litellm-autoscaler
  namespace: ia-services-payed
spec:
  scaleTargetRef:
    name: litellm-ha
    minReplicaCount: 2
    maxReplicaCount: 10
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus-monitoring.svc.cluster.local:9090
      query: |
        sum(rate(litellm_proxy_request_count{status!="200"}[2m]))
      threshold: "10"
  cooldownPeriod: 300

Llibre de Manual de Depuració

Síntoma: Pod en CrashLoopBackOff

# Step 1: Check events
kubectl describe pod <pod-name> -n ia-services-payed

# Step 2: Check logs
kubectl logs <pod-name> -n ia-services-payed --tail=50

# Step 3: Check resource usage
kubectl top pod <pod-name> -n ia-services-payed

# Step 4: If GPU-related, check GPU health
nvidia-smi

# Step 5: Check DCGM metrics
kubectl port-forward -n gpu-operator \
  pod/gpu-operator-dcgm-exporter 9400:9400
curl http://localhost:9400/metrics | grep XID

Síntoma: Servidat de Models Lent

# Step 1: Check GPU utilization
kubectl exec -n gpu-operator \
  pod/gpu-operator-dcgm-exporter -- \
  dcgm-exporter --help  # verify running

# Step 2: Check model server logs
kubectl logs -n ia-services-payed \
  -l app=vllm --tail=100 | grep -E "error|timeout|slow"

# Step 3: Check network latency between agents and gateway
kubectl run --rm -it --restart=Never --namespace=forgejo-runners \
  latency-test --image=busybox -- \
  time wget -qO- http://litellm.ia-services-payed.svc.cluster.local:4000/health

# Step 4: Check Prometheus metrics
# Query: litellm_proxy_latency_seconds

Síntoma: GPU No Detectada

# Step 1: Check GPU operator pods
kubectl get pods -n gpu-operator

# Step 2: Check device plugin
kubectl logs -n gpu-operator \
  $(kubectl get pod -n gpu-operator -l app.kubernetes.io/component=nvidia-device-plugin \
    -o name)

# Step 3: Verify GPU on the node
kubectl describe node gx10-db4d | grep -A 10 NVIDIA

# Step 4: Restart device plugin if needed
kubectl rollout restart deployment/nvidia-device-plugin-daemonset \
  -n gpu-operator

Panells de Monitoratge

Panells Crítics a Configurar

  1. Vista General de GPU: totes les mètriques de GPU en tots els nodes

    • Utilització de GPU, temperatura, memòria
    • Consum de potència
    • Errors XID
  2. Servidat de Models: rendiment de LiteLLM

    • Taxa de sol·licituds, latència, taxa d’errors
    • Ús de tokens per model
    • Estat de salut del model
  3. Salut del Cluster: estat del cluster K3s

    • Estat de nodes, salut de pod
    • Mida i salut d’etcd
    • Estat de política de xarxa
  4. Operacions d’Agents: mètriques de l’agent Hermes

    • Taxa d’èxit/fallida de feina cron
    • Temps de completament de tasas d’agent
    • Profunditat de cua de tasas

Regles d’Alerta

# prometheus-alerting-rules.yaml
groups:
- name: k3s-ai-alerts
  rules:
  - alert: GPUOverheating
    expr: DCGM_FI_DEV_TEMP_GPU > 85
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "GPU overheating on {{ $labels.device }}"

  - alert: GPUVramNearLimit
    expr: DCGM_FI_DEV_MEM_USED / DCGM_FI_DEV_MEM_TOTAL > 0.9
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "GPU memory near limit on {{ $labels.device }}"

  - alert: ModelServerErrorRate
    expr: >
      sum(rate(litellm_proxy_request_error_count[5m]))
      / sum(rate(litellm_proxy_request_count[5m]))
      > 0.05
    for: 3m
    labels:
      severity: critical
    annotations:
      summary: "Model server error rate > 5%"

  - alert: HighModelLatency
    expr: litellm_proxy_latency_seconds_p99 > 30
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "P99 model latency > 30 seconds"

  - alert: EtcdDatabaseLarge
    expr: etcd_server_db_size_bytes > 5e8
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "etcd database size > 500MB"

  - alert: PodCrashLooping
    expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "Pod {{ $labels.pod }} is crash looping"

Llista de Comprovació Operativa

Diària

  • Comprovar Grafana per a alertes de temperatura i memòria de GPU
  • Verificar l’estat de completament de CronJob
  • Revisar les taxes d’errors al gateway de LiteLLM
  • Comprovar la mida de la base de dades etcd

Setmanal

  • Revisar l’ús de models i el consum de tokens
  • Comprovar l’espai de disc a l’emmagatzematge de models
  • Verificar l’èxit de la còpia de seguretat
  • Revisar l’efectivitat de NetworkPolicy
  • Comprovar la utilització de recursos de pod

Mensual

  • Provar el procediment de recuperació de desastre
  • Revisar i actualitzar els llindals d’alerta
  • Auditar les regles de NetworkPolicy
  • Comprovar les actualitzacions del controlador de GPU
  • Revisar les versions de models i actualitzar si cal
  • Revisió de planificació de capacitat

Conclusió

La realitat operativa de les càrregues de treball IA a K3s es redueix a tres principis:

  1. Monitoratgeu-ho tot — mètriques de GPU, latència de sol·licitud, ús de tokens, salut d’etcd. Si no podeu mesurar-ho, no el podeu arreglar.
  2. Automatitzeu les còpies de seguretat — els snapshots d’etcd, el registre de models i la configuració haurien de fer-se còpia de seguretat automàticament amb polítiques de retenció.
  3. Documenteu-ho tot — les post-mortems d’incidències, els llibres de manual de depuració i les llistes de comperò operatives prevenen fallades repetides.

La lliçó operativa més gran: comenceu amb un monitoratge complet abans de necessitar-ho. Quan la vostra GPU està al 92% de memòria i les sol·licituds es tanquen, us desitjareu tenir aquests panells ja configurats.