Diagnozowanie problemów w Kubernetes potrafi być żmudne — zwłaszcza gdy klaster działa lokalnie, bez dostępu do komercyjnych usług AI czy zewnętrznych API. Pytanie, które mnie nurtowało, było całkiem praktyczne: czy zwykła stacja robocza z 16 GB RAM to wystarczające środowisko, żeby lokalny model językowy faktycznie pomagał w analizie problemów klastra, a nie tylko wyglądał imponująco w demonstracji?

HolmesGPT to narzędzie zaprojektowane właśnie do tego — łączy się z klastrem Kubernetes, zbiera kontekst z podów, eventów i logów, a następnie przekazuje go do modelu językowego, który formułuje diagnozę i sugestie naprawcze. Narzędzie wspiera zarówno modele chmurowe (OpenAI, Anthropic), jak i lokalne przez Ollama.

To drugie podejście szczególnie mnie zainteresowało: uruchomić wszystko na własnej maszynie, bez wysyłania danych diagnostycznych klastra do zewnętrznych serwisów, bez limitu tokenów i bez kosztów per-zapytanie. Poniżej opisuję, jak to wygląda w praktyce — które modele nadają się do tej roli, jak skonfigurować całe środowisko i na co zwrócić uwagę przy ograniczonej pamięci RAM.

Środowisko testowe Link to heading

Do testów postawiłem lokalny klaster Kubernetes za pomocą kind:

kind create cluster --config <(cat <<'EOF'
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: lab
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
)

Jako scenariusz testowy skorzystałem z repozytorium kubernetes-demos. Wybrałem prosty, ale realistyczny przypadek — pod z błędnie skonfigurowanym nodeSelector, który nigdy nie zostanie zaplanowany:

kubectl apply -f - <<'EOF'
  apiVersion: v1
  kind: Pod
  metadata:
    name: example
  spec:
    containers:
    - name: nginx
      image: nginx
    nodeSelector:
      label: someLabel
EOF

Modele Link to heading

Przetestowałem cztery modele serwowane i pobrane przez Ollama:

ollama serve
ollama pull gemma4:e4b
ollama pull llama3.1:8b
ollama pull qwen3.5:9b
ollama pull qwen2.5:7b

Konfiguracja HolmesGPT Link to heading

HolmesGPT konfiguruje się przez zmienne środowiskowe. Dwie podstawowe to wskazanie klastra i adres lokalnego serwera Ollamy:

export KUBECONFIG=~/.kube/config
export OLLAMA_API_BASE="http://localhost:11434"

Wybór modelu zmienia się przez MODEL — testowałem kolejno:

export MODEL="ollama_chat/gemma4:e4b"
export MODEL="ollama_chat/llama3.1:8b"
export MODEL="ollama_chat/qwen3.5:9b"
export MODEL="ollama_chat/qwen2.5:7b"

Cztery dodatkowe flagi okazały się konieczne przy lokalnych modelach, które nie implementują function calling tak rygorystycznie jak modele OpenAI:

export HOLMES_DISABLE_STRICT_TOOL_CALLS=true
export TOOL_SCHEMA_NO_PARAM_OBJECT_IF_NO_PARAMS=true
export TOOL_CALL_SAFEGUARDS_ENABLED=false
export HOLMES_TOOL_RESULT_STORAGE_ENABLED=false

HOLMES_DISABLE_STRICT_TOOL_CALLS i TOOL_CALL_SAFEGUARDS_ENABLED wyłączają walidację formatu wywołań narzędzi — bez tego HolmesGPT odrzucał odpowiedzi modeli, które nieznacznie odbiegały od oczekiwanego schematu JSON. TOOL_SCHEMA_NO_PARAM_OBJECT_IF_NO_PARAMS upraszcza schemat narzędzi przekazywany do modelu, co poprawia zgodność z mniejszymi modelami. HOLMES_TOOL_RESULT_STORAGE_ENABLED=false wyłącza zapis wyników narzędzi do pliku — część modeli z serii Gemma4 nie obsługuje tego mechanizmu i rzuca błąd bez tej flagi.

Samo zapytanie wysyłałem poleceniem:

holmes ask --max-steps 10 --fast-mode "use kubectl describe pod example in namespace default to find why the pod is in pending state" --no-interactive -v

--max-steps 10 ogranicza liczbę iteracji, żeby model nie chodził w kółko w nieskończoność. --fast-mode pomija wstępną fazę planowania (TodoWrite), która przy mniejszych modelach zamieniała się w pętlę aktualizacji listy zadań bez faktycznego wykonywania komend. --no-interactive wyłącza tryb interaktywny, -v włącza szczegółowe logowanie — przydatne, gdy trzeba zobaczyć, czy model rzeczywiście wywołuje narzędzia, czy tylko o nich pisze.

Wyniki testów Link to heading

gemma4:e4b Link to heading

Model opisywał polecenia kubectl jako tekst w odpowiedzi, ale nigdy ich nie wykonał. Zamiast wywołać narzędzie, generował plan słowny z przykładowymi komendami — brak rzeczywistej obsługi function calling.

llama3.1:8b Link to heading

Podobny problem: model tworzył plan w formacie JSON przypominający listę zadań (TodoList) i opisywał kroki diagnostyczne jako tekst. Żadne narzędzie nie zostało faktycznie wywołane.

qwen3.5:9b Link to heading

Modele z serii Qwen3 mają domyślnie włączony tryb myślenia (thinking mode), który dodaje wewnętrzne bloki <think> do odpowiedzi. Zakłóca to parsowanie wywołań narzędzi przez HolmesGPT — model stwierdził, że nie ma dostępu do narzędzi Kubernetes, mimo że załadowano 31 zestawów narzędzi.

qwen2.5:7b Link to heading

Jedyny model spośród testowanych, który faktycznie wywołuje narzędzia — jednak to nie oznacza, że problem został rozwiązany. Model wykonywał kolejne kroki diagnostyczne i zbierał dane z klastra, ale po ostatnim wywołaniu narzędzia procesor wskakiwał na 100% i odpowiedź po prostu nie przychodziła. Nie było błędu, nie było timeoutu — Ollama pracowała, ale wynik nigdy nie trafiał z powrotem do HolmesGPT.

Innymi słowy: model wiedział, jak pytać klaster, ale utykał przy formułowaniu wniosków.

Żeby dojść nawet do tego etapu, potrzebne było kilka obejść:

  • --fast-mode — pomija fazę planowania TodoWrite, w której mniejsze modele utykają w nieskończonej pętli aktualizacji listy zadań zamiast wykonywać komendy.
  • Precyzyjny prompt — ogólne pytanie (why is the pod pending?) powoduje pętlę między fetch_pod_logs a kubectl_run_image. Wskazanie konkretnego narzędzia (use kubectl describe pod example) kieruje model od razu we właściwe miejsce.

Czyszczenie Link to heading

Po zakończeniu testów warto odzyskać zajęte zasoby — modele językowe potrafią zająć kilka gigabajtów każdy. Usuwam je z lokalnego magazynu Ollamy:

ollama rm gemma4:e4b
ollama rm llama3.1:8b
ollama rm qwen3.5:9b
ollama rm qwen2.5:7b

Następnie usuwam klaster kind i zwalniam miejsce zajęte przez obrazy Dockera, które kind pobrał przy tworzeniu węzłów:

kind delete cluster --name lab

docker image prune --all --force
docker system prune --all --force

Wnioski Link to heading

Krótka odpowiedź na pytanie z wstępu: przy 16 GB RAM i lokalnych modelach przez Ollama — HolmesGPT nie działa użytecznie.

Żaden z czterech przetestowanych modeli nie dostarczył kompletnej diagnozy. Trzy z nich (gemma4:e4b, llama3.1:8b, qwen3.5:9b) nie wywołały narzędzi w ogóle — każdy z innego powodu: brak obsługi function calling, generowanie pseudo-planów zamiast akcji, zakłócenie parsowania przez tryb myślenia. Jedyny model, który rzeczywiście sięgnął po narzędzia (qwen2.5:7b), utykał na etapie syntezy wyników — procesor pracował na 100% bez końca, odpowiedź nigdy nie wracała.

Problemem nie jest sama idea — HolmesGPT jest dobrze zaprojektowanym narzędziem i integracja z Ollama jest technicznie możliwa. Problemem są modele dostępne w rozmiarach mieszczących się w 16 GB RAM. Function calling to dla nich wciąż trudne zadanie, a synteza zebranych danych w spójną diagnozę wymaga możliwości, których modele 7–9B w tej chwili po prostu nie mają.

Żeby to działało w praktyce, potrzeba albo większej maszyny (32+ GB RAM, żeby uruchomić modele 30B+), albo GPU z wystarczającą pamięcią VRAM, albo rezygnacji z lokalności i użycia modeli chmurowych — co nieco mija się z celem całego ćwiczenia.