Elke vendor pitch deck heeft op dit moment dezelfde slide. “Autonomous cluster management.” Een AI bewaakt je Kubernetes cluster, ziet problemen, diagnosticeert ze, en fixt ze terwijl jij slaapt. Platform engineers stoppen met brandjes blussen en het cluster geneest zichzelf.
Ik draai een homelab juist omdat ik wil begrijpen wat er echt gebeurt, in plaats van een black box te vertrouwen. Dus als ik zo’n claim zie, is mijn eerste reflex om het zelf te testen in plaats van de slide te geloven.
Het addertje bij de meeste van deze tools is dat “AI” betekent dat je cluster metadata naar OpenAI wordt gestuurd. Voor mij is dat een no-go. Ik self-host mijn infrastructuur precies zodat mijn data op mijn netwerk blijft. Als het AIOps verhaal alleen werkt wanneer je je pod names, labels en error messages aan een derde partij geeft, sluit het op niets aan wat ik belangrijk vind.
Dus dit is de versie die ik wilde proberen: K8sGPT gericht op een Llama 3.3 70B model dat lokaal draait op Apple Silicon. Geen cloud APIs. Geen data die het netwerk verlaat. De vraag die ik echt beantwoord wil hebben is of een lokaal model goed genoeg is om nuttig te zijn voor cluster diagnose, of dat sovereignty hier meer kost dan het waard is.
Disclaimer: Dit is een homelab experiment. Ik beschrijf wat ik heb getest en wat ik heb gevonden. Lees het als een “draai dit niet in productie” writeup, want de security analyse hieronder maakt die case in detail.
Hardware en software stack
De hardware
- Mac Studio M3 Ultra met 512GB unified memory
- De M3 Ultra heeft 80 GPU cores die je kunt gebruiken voor inference
- Unified memory betekent geen kopiëren tussen CPU en GPU RAM
Met ~€10.000 is dit een dure bak. Ik doe niet alsof dat anders is. Maar het is zo’n beetje de enige consumer hardware die een 70B model in Q8 quantization kan draaien op snelheden die je nog tolereert. Unified memory is de hele truc: je betaalt niet de copy tax tussen CPU en GPU RAM die je op een normale PC met een losse kaart de das om doet.
De software stack
| Component | Versie | Rol |
|---|---|---|
| vLLM | 0.6.x | Inference server met Metal backend |
| Llama 3.3 70B | Q8_0 | Het taalmodel (~75GB) |
| K8sGPT Operator | 0.1.x | Kubernetes operator voor diagnose |
| k3s | 1.29.x | Lokaal Kubernetes cluster |
Installatie: vLLM met Metal backend
vLLM heeft experimentele Metal support voor Apple Silicon. Installatie:
# Maak een dedicated conda environment
conda create -n vllm python=3.11
conda activate vllm
# Installeer vLLM met Metal support
pip install vllm
# Verifieer Metal backend
python -c "import vllm; print(vllm.__version__)"
Let op: Op moment van schrijven is Metal support in vLLM nog experimenteel, en dat merk je. llama.cpp met de Metal backend is de stabielere optie, maar K8sGPT wil een OpenAI-compatible API en vLLM geeft me die out of the box. Dus ik nam de ruigere route om geen shim te hoeven schrijven.
Model download
# Download het model (Q8 quantization, ~75GB)
huggingface-cli download meta-llama/Llama-3.3-70B-Instruct \
--local-dir ./models/llama-3.3-70b-instruct
Je hebt een Hugging Face account nodig en moet de Llama license accepteren.
vLLM server starten
# Start de inference server
vllm serve ./models/llama-3.3-70b-instruct \
--host 0.0.0.0 \
--port 8000 \
--dtype float16 \
--max-model-len 8192 \
--device mps
De --device mps flag forceert Metal Performance Shaders. Zonder deze flag valt vLLM terug op CPU.
Verifieer dat de server draait:
curl http://localhost:8000/v1/models
K8sGPT operator deployment
Installeer de K8sGPT operator in je cluster:
# Voeg de Helm repo toe
helm repo add k8sgpt https://charts.k8sgpt.ai/
helm repo update
# Installeer de operator
helm install k8sgpt-operator k8sgpt/k8sgpt-operator \
-n k8sgpt-operator-system \
--create-namespace
Configureer een custom backend die naar je lokale vLLM server wijst:
# k8sgpt-config.yaml
apiVersion: core.k8sgpt.ai/v1alpha1
kind: K8sGPT
metadata:
name: k8sgpt-local
namespace: k8sgpt-operator-system
spec:
ai:
enabled: true
model: llama-3.3-70b-instruct
backend: localai
baseUrl: http://192.168.1.100:8000/v1 # IP van je Mac Studio
noCache: false
version: v0.3.40
analyzers:
- Pod
- Deployment
- Service
- ReplicaSet
- PersistentVolumeClaim
- Ingress
- StatefulSet
- CronJob
kubectl apply -f k8sgpt-config.yaml
Test scenario’s
De setup draait. Nu het deel dat telt: is het daadwerkelijk nuttig, of is het een heel dure manier om met overtuiging een fout antwoord te krijgen? Ik gooide drie bewust kapotte dingen ervoor en gaf de output een cijfer zoals ik dat bij de eerste poging van een junior engineer zou doen.
Scenario A: CrashLoopBackOff diagnose
Ik introduceer een deployment met een ontbrekende ConfigMap:
# broken-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: broken-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: broken-app
template:
metadata:
labels:
app: broken-app
spec:
containers:
- name: app
image: nginx:1.25
envFrom:
- configMapRef:
name: app-config # Deze ConfigMap bestaat niet
kubectl apply -f broken-deployment.yaml
Na een minuut is de pod in CrashLoopBackOff. K8sGPT analyse:
kubectl get results -n k8sgpt-operator-system -o yaml
Output (geparafraseerd):
Analysis: Pod broken-app-xxxx is in CreateContainerConfigError state.
The pod is referencing a ConfigMap 'app-config' that does not exist
in the namespace.
Suggested remediation:
1. Create the missing ConfigMap:
kubectl create configmap app-config --from-literal=KEY=value
2. Or remove the configMapRef from the deployment spec
3. Verify the ConfigMap name spelling matches exactly
Score: Bruikbaar
De diagnose is correct en de suggesties zijn praktisch. Een junior engineer kan hiermee uit de voeten zonder op een dwaalspoor te raken. Het enige dat het miste: het suggereert nooit om te checken of de ConfigMap in een andere namespace staat, en dat is de fout die ik ongeveer eens per maand maak.
Scenario B: resource recommendations
Een deployment zonder resource limits:
# no-limits.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: no-limits-app
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: no-limits
template:
metadata:
labels:
app: no-limits
spec:
containers:
- name: app
image: nginx:1.25
# Geen resources gedefinieerd
K8sGPT analyse:
Analysis: Deployment no-limits-app has containers without resource
requests or limits defined.
Issues identified:
- Container 'app' has no CPU requests/limits
- Container 'app' has no memory requests/limits
Suggested remediation:
Add resource specifications to ensure predictable scheduling and
prevent resource starvation:
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
Score: Deels bruikbaar
Het probleem ziet het prima. De getallen die het je geeft zijn verzonnen. Ze zijn nergens op gebaseerd, want het model heeft geen enkele metric gezien. Een ervaren engineer haalt eerst echte data op met kubectl top pods of Prometheus, en rightsized van daaruit. De LLM gokt, en het vertelt je niet dat het gokt.
Wat mist:
- Geen suggestie om VPA (Vertical Pod Autoscaler) te gebruiken
- Geen waarschuwing dat limits zonder requests problematisch kunnen zijn
- De ratio requests:limits (1:2) is willekeurig
Scenario C: security audit
Een pod met slechte security practices:
# insecure-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: insecure-pod
namespace: default
spec:
hostNetwork: true
containers:
- name: app
image: nginx:1.25
securityContext:
privileged: true
runAsRoot: true
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
K8sGPT analyse met Trivy integratie:
Analysis: Pod insecure-pod has multiple security issues:
Critical:
- Container running in privileged mode (privileged: true)
- Container has access to host network (hostNetwork: true)
- Container mounts host root filesystem
High:
- No securityContext.readOnlyRootFilesystem
- No securityContext.allowPrivilegeEscalation: false
Suggested remediation:
1. Remove privileged: true unless absolutely necessary
2. Use a dedicated network namespace (remove hostNetwork: true)
3. Avoid mounting host paths, especially root filesystem
4. Add security hardening:
securityContext:
privileged: false
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
runAsNonRoot: true
capabilities:
drop:
- ALL
Score: Bruikbaar
Deze verraste me. De issues zijn correct geïdentificeerd en de remediation leest als wat een security engineer je echt zou vertellen. De Trivy integratie verdient hier zijn plek door ook image vulnerabilities te flaggen, zodat je de misconfiguratie en het CVE verhaal in één pass krijgt.
Wat mist:
- Geen suggestie voor Pod Security Standards (restricted profile)
- Geen warning over Kyverno/OPA policies die dit zouden moeten blokkeren
Performance metrics
Inference snelheid
| Metric | Waarde |
|---|---|
| Tokens/seconde (prompt) | ~180 t/s |
| Tokens/seconde (generation) | ~25 t/s |
| Eerste token latency | ~2.5s |
| Typische analyse (500 tokens out) | ~22s |
End-to-end latency
Van issue detectie tot rapport in K8sGPT:
| Fase | Tijd |
|---|---|
| Issue detectie (polling) | 30s (configurabel) |
| Context gathering | ~2s |
| LLM inference | ~20-30s |
| Result storage | <1s |
| Totaal | ~55s |
Resource gebruik
Tijdens inference:
| Resource | Gebruik |
|---|---|
| GPU Memory (Metal) | ~78GB |
| CPU | ~15% (data preprocessing) |
| System Memory | ~12GB (naast model) |
| Power draw | ~180W |
Vergelijking met OpenAI API
| Metric | Lokaal (70B) | OpenAI GPT-4 |
|---|---|---|
| Latency | ~25s | ~5s |
| Kwaliteit | Goed | Zeer goed |
| Kosten | €0 (na hardware) | ~€0.03/query |
| Privacy | Volledig lokaal | Data naar OpenAI |
De OpenAI API is sneller en de output is marginaal beter. De prijs is dat je cluster metadata je netwerk verlaat. Voor mij is die ruil de hele kern van de oefening: ik wacht met plezier 25 seconden in plaats van 5 om de data thuis te houden. Of je dezelfde keuze maakt hangt af van wat er in je pod labels staat.
Air-gapped deployment
Kan dit draaien zonder enige internetverbinding? Ja, met wat voorbereiding vooraf. Hier betaalt de lokale-model aanpak zich uit, want de air-gap case is onmogelijk zodra je afhankelijk bent van een cloud API.
Wat je vooraf moet downloaden
# 1. Model weights (~75GB)
huggingface-cli download meta-llama/Llama-3.3-70B-Instruct \
--local-dir ./airgap-bundle/models/
# 2. vLLM Python packages
pip download vllm -d ./airgap-bundle/packages/
# 3. K8sGPT container images
docker pull ghcr.io/k8sgpt-ai/k8sgpt-operator:latest
docker save ghcr.io/k8sgpt-ai/k8sgpt-operator:latest > ./airgap-bundle/images/k8sgpt-operator.tar
# 4. Helm charts
helm pull k8sgpt/k8sgpt-operator --destination ./airgap-bundle/charts/
Transport en installatie
# Op de air-gapped machine:
# 1. Installeer Python packages offline
pip install --no-index --find-links=./airgap-bundle/packages/ vllm
# 2. Laad container images
docker load < ./airgap-bundle/images/k8sgpt-operator.tar
# Of push naar je lokale registry
# 3. Installeer Helm chart
helm install k8sgpt-operator ./airgap-bundle/charts/k8sgpt-operator-*.tgz \
--set image.repository=your-local-registry/k8sgpt-operator
Air-gap friendly components
| Component | Air-Gap Ready | Notes |
|---|---|---|
| vLLM | Ja | Geen phone-home |
| Llama model | Ja | Eenmalige download |
| K8sGPT Operator | Ja | Geen telemetry |
| Trivy DB | Nee | Vereist periodieke updates |
Let op: De Trivy vulnerability database moet je apart updaten en transporteren. Zonder recente DB mist K8sGPT nieuwe CVEs.
Security analyse en threat model
Hier wordt eerlijkheid belangrijk. Een lokaal model geeft je data sovereignty, maar het maakt de setup niet magisch veilig. Een Mac Studio die op je netwerk staat als inference server brengt zijn eigen stapel problemen mee, en de LLM brengt een tweede stapel die specifiek voor het model geldt.
Platform security issues
Een Mac Studio als inference server heeft fundamentele beperkingen:
| Issue | Impact |
|---|---|
| Geen TPM | Geen hardware attestation, geen measured boot |
| macOS is general-purpose | Niet hardened zoals RHEL/Ubuntu met CIS benchmarks |
| Geen Secure Boot chain | Boot process is niet cryptografisch geverifieerd |
| Updates vereisen internet | Of handmatige interventie in air-gapped scenario |
| Single-user focus | macOS is niet ontworpen voor multi-tenant security |
Conclusie: Een Mac Studio is ongeschikt voor omgevingen met strikte compliance eisen (ISO27001 Annex A, NIS2, SOC2). Voor homelab en development is het acceptabel.
LLM-specifieke risico’s
| Risico | Beschrijving |
|---|---|
| Non-determinisme | Dezelfde input kan verschillende outputs geven |
| Prompt injection | Malicious pod names/labels kunnen de LLM manipuleren |
| Hallucinations | Model kan schadelijke remediatie suggereren |
| Context leakage | Info uit eerdere queries kan in responses verschijnen |
| Supply chain | Model weights kunnen backdoored zijn |
Threat model
| Threat | Likelihood | Impact | Mitigatie |
|---|---|---|---|
| Prompt injection via pod metadata | Medium | High | Input sanitization, output validation |
| Hallucinated destructive commands | Medium | Critical | Human-in-the-loop, geen auto-remediation |
| Model weights tampering | Low | Critical | Checksum verificatie, trusted source |
| Context window data leakage | Medium | Medium | Korte context, geen persistent memory |
| Unauthorized access to inference API | Medium | High | Network segmentation, auth |
| Resource exhaustion (DoS) | Low | Medium | Rate limiting, resource quotas |
Conclusies en aanbevelingen
Is een lokale LLM bruikbaar voor Kubernetes diagnose?
Ja, onder voorwaarden.
Het kan:
- Standaard issues correct identificeren
- Bruikbare remediatie suggesties geven
- Security problemen detecteren
- Dit alles zonder data je netwerk te verlaten
Het kan niet:
- Complexe, multi-component issues debuggen
- Betrouwbaar auto-remediation doen
- De context van je specifieke setup begrijpen
- Garanties geven over correctheid
Aanbevelingen per use case
Homelab / learning
Aanbeveling: Ga ervoor.
Dit is een uitstekende manier om te leren over:
- LLM inference infrastructure
- Kubernetes troubleshooting patterns
- De grenzen van AI-assisted operations
Risico’s zijn acceptabel omdat de impact beperkt is.
Development / staging
Aanbeveling: Bruikbaar met guardrails.
Implementeer:
- Output review voordat suggesties worden toegepast
- Logging van alle LLM interacties
- Geen auto-remediation, alleen diagnose
Productie (niet air-gapped)
Aanbeveling: Gebruik cloud APIs.
Waarom:
- Betere modellen (GPT-4, Claude)
- Lagere latency
- Geen hardware investering
- Professionele SLAs
De privacy trade-off is voor de meeste organisaties acceptabel als je geen PII in cluster metadata hebt.
Productie (air-gapped / sovereign)
Aanbeveling: Alleen als laatste optie.
Als je écht geen data naar buiten mag sturen:
- Overweeg kleinere, dedicated models
- Implementeer defense-in-depth voor de inference server
- Treat alle LLM output als untrusted
- Zorg voor extensive logging en audit trails
- Gebruik dit als assistentie, nooit als autoriteit
De staat van autonomous cluster management
Terug naar de slide waar dit mee begon. “Autonomous cluster management” met LLMs is vandaag marketing, niet iets dat je kunt draaien. Wat ik echt getest heb is assisted diagnose: een model dat naar problemen wijst en suggesties biedt. De human-in-the-loop blijft in de loop. Dat is een vereiste, geen instelling die je uitzet zodra je het genoeg vertrouwt.
En de technologie is oprecht indrukwekkend. Een 70B model dat op hardware in mijn eigen kantoor draait produceerde analyses die ik van een collega zou accepteren. Het gat tussen “goed genoeg om te lezen” en “goed genoeg om naar te handelen op een productie cluster zonder mij” is nog breed, en het werd elke keer breder als het model met overtuiging een resource limit verzon.
Ik heb het antwoord dat ik kwam halen. Een lokaal model is goed genoeg om een nuttige diagnostische assistent te zijn, en lokaal draaien betekent dat ik nooit hoefde te kiezen tussen AIOps en mijn data thuishouden. Behandel de output zoals je advies zou behandelen van een scherpe collega die je cluster nog nooit gezien heeft: het luisteren waard, nooit het laatste woord.
Gerelateerde posts:
- Sovereign Infrastructure - Waarom ik alles self-host
- Why Privacy Matters - De context voor lokale LLMs
