23 - remotedialer i naprawa Grafany¶
Data: 2026-09-12
Środowisko: 3× HP T630, k3s v1.34.4+k3s1, Flux v2.8.1, Cilium v1.19.1, kube-prometheus-stack 82.10.1, Grafana 12.4.0
Cel sesji¶
- Ponownie sprawdzić błąd tunelu remotedialer po uruchomieniu klastra.
- Potwierdzić bezpieczne, doraźne odtworzenie brakującego tunelu.
- Znaleźć przyczynę błędu
An error occurred within the pluginw Grafanie. - Utrwalić konfigurację Grafany i Loki w repozytorium Flux.
- Usunąć błędy sidecarów Grafany podczas uruchamiania Poda.
1. Ponowne odtworzenie błędu remotedialera¶
Klaster uruchomiono dotychczasowym playbookiem Power On, bez zmiany kolejności i odstępów Wake-on-LAN. Usługi K3s, lokalne API i etcd osiągnęły gotowość, ale test połączeń API server → kubelet nie przeszedł:
Komunikat K3s:
Na worker2 brakowało połączenia do API servera na worker1:
EndpointSlice Service kubernetes był poprawny:
Problem nie wynikał więc z braku noda w EndpointSlice. Lokalny proces K3s na worker2 nie zestawił jednego z wymaganych tuneli mimo poprawnego docelowego stanu API.
2. Doraźny resync remotedialera¶
Zmiana adnotacji EndpointSlice wymusiła nowe zdarzenie obserwowane przez K3s:
kubectl annotate endpointslice kubernetes \
--namespace default \
diagnostics.kcn333.com/remotedialer-resync="$(date -u +%s)" \
--overwrite
Na worker2 pojawiła się pełna sekwencja synchronizacji:
Syncing apiserver addresses from tunnel watch
Settled apiserver addresses sync
Sync apiserver addresses - connecting: [192.168.55.11:6443]
Started tunnel to 192.168.55.11:6443
Remotedialer connected to proxy
Po resyncu test zakończył się wynikiem ok:
ssh worker1 '
sudo k3s kubectl \
--request-timeout=5s \
get --raw \
/api/v1/nodes/worker2/proxy/healthz
'
Adnotację diagnostyczną następnie usunięto:
kubectl annotate endpointslice kubernetes \
--namespace default \
diagnostics.kcn333.com/remotedialer-resync-
Stan problemu¶
Przyczyna pozostaje nierozstrzygnięta. Potwierdzono jedynie, że:
- błąd może wystąpić po równoczesnym uruchomieniu nodów;
- EndpointSlice może już zawierać wszystkie trzy poprawne adresy;
- jeden klient remotedialera może mimo to nie posiadać tunelu do jednego API servera;
- ponowne zdarzenie na EndpointSlice uruchamia synchronizację i odtwarza brakujący tunel;
- nie jest wymagany restart noda ani usługi K3s.
Playbook Power On pozostawiono bez sztucznego opóźnienia między nodami. Resync EndpointSlice jest obejściem, nie wyjaśnieniem przyczyny.
3. Objaw awarii Grafany¶
Dashboardy Grafany wyświetlały:
Log Grafany wskazał rzeczywisty błąd:
Adres 10.43.68.211:9090 należał do Service Prometheusa. Prometheus działał z hostNetwork: true na worker1, dlatego jego backendem był adres noda:
Test lokalny na worker1 działał zarówno przez loopback, jak i adres noda:
Połączenie z worker2 kończyło się timeoutem. tcpdump na worker1 pokazał przychodzące pakiety SYN z 192.168.55.12, ale brak odpowiedzi SYN-ACK. Potwierdziło to blokadę na hoście docelowym, a nie awarię Prometheusa, Service albo DNS.
4. Przyczyna i naprawa połączenia Grafana → Prometheus¶
UFW na nodach nie zezwalał na ruch klastra do portu 9090/tcp, na którym Prometheus nasłuchiwał przez hostNetwork.
Regułę najpierw sprawdzono na worker1:
Po jej dodaniu:
worker2otrzymał odpowiedźPrometheus Server is Ready;- Grafana zaczęła łączyć się z Prometheusem przez nazwę Service;
- dashboardy natychmiast zaczęły wyświetlać dane;
- w logach Grafany przestały pojawiać się timeouty do Prometheusa.
Regułę utrwalono następnie w playbooku UFW repozytorium Ansible:
Pierwsze uruchomienie dodało po jednej regule na każdym nodzie. Drugie uruchomienie było idempotentne:
Nie otwarto portu 9090 dla całej sieci LAN ani Internetu.
5. Utrwalenie konfiguracji Grafany przez Flux¶
Grafana używała emptyDir dla /var/lib/grafana. Ręcznie utworzone obiekty mogły więc zniknąć po wymianie Poda.
Przed rolloutem wyeksportowano dashboard aplikacji:
W repozytorium Flux dodano:
grafana-dashboard-clients-api.yaml— ConfigMap z etykietągrafana_dashboard: "1";grafana-datasource-loki.yaml— ConfigMap z etykietągrafana_datasource: "1";- oba zasoby do
infrastructure/operators/monitoring/kustomization.yaml.
Datasource Loki zachował dotychczasową tożsamość i adres:
Po reconciliacji Flux API Grafany potwierdziło:
Dashboard i datasource nie zależą już od efemerycznej bazy Grafany.
6. Konflikt portów sidecarów Grafany¶
Pod Grafany zawiera dwa sidecary kiwigrid/k8s-sidecar:
grafana-sc-dashboard;grafana-sc-datasources.
Oba próbowały uruchomić endpoint zdrowia na domyślnym porcie 8080 we wspólnej przestrzeni sieciowej Poda. Jeden z nich zgłaszał:
W HelmRelease ustawiono oddzielne porty:
Po rolloutcie oba kontenery działały równocześnie, a Pod osiągnął 3/3 Running bez restartów.
7. Wyścig podczas uruchamiania Grafany¶
Po usunięciu konfliktu portów oba sidecary zgłosiły jednorazowy błąd połączenia z:
Pomiar czasów wykazał:
11:12:53.706 Starting Grafana
11:13:13.2 sidecary wyczerpały domyślne próby
11:14:20.996 HTTP Server Listen :3000
Grafana potrzebowała około 87 sekund na utworzenie świeżej bazy SQLite, migracje, provisionowanie i instalację pluginów. Domyślne REQ_RETRY_TOTAL=5 zakończyło się około 68 sekund przed uruchomieniem HTTP.
Dla obu sidecarów ustawiono:
Nie zmieniono REQ_RETRY_CONNECT, ponieważ jego wartość domyślna wynosi 10.
Po końcowym rolloutcie:
Dashboardy Grafany wyświetlały dane. Temat Grafany został zamknięty.
8. Końcowy stan¶
Grafana — naprawiona¶
- komunikacja Grafana → Prometheus działa;
- UFW deklaratywnie dopuszcza
9090/tcpwyłącznie z sieci nodów; - dashboard aplikacji jest provisionowany przez Flux;
- datasource Loki jest provisionowany przez Flux;
- sidecary używają oddzielnych portów zdrowia;
- retry sidecarów obejmuje rzeczywisty czas startu Grafany;
- Pod działa jako
3/3 Runningbez restartów; - dashboardy pokazują dane.
Remotedialer — problem otwarty¶
- błąd został ponownie odtworzony;
- zachowano logi debug z niepoprawnego startu;
- resync przez zmianę adnotacji EndpointSlice skutecznie naprawia tunel;
- właściwa przyczyna utraty pojedynczej sesji nadal wymaga ustalenia.
Najważniejsze wnioski¶
hostNetwork: trueoznacza, że dostęp do portu workloadu zależy również od firewalla noda.- Działający lokalnie Prometheus nie gwarantuje dostępu z innego noda.
- SYN bez SYN-ACK na hoście docelowym wskazuje na filtrację albo brak odpowiedzi po stronie tego hosta.
- Ręcznie utworzone obiekty Grafany nie powinny pozostawać wyłącznie w bazie przechowywanej w
emptyDir. - Dashboardy i datasources można provisionować przez etykietowane ConfigMapy obserwowane przez sidecary.
- Kontenery w jednym Podzie współdzielą przestrzeń sieciową, więc nie mogą nasłuchiwać na tym samym adresie i porcie.
- Retry sidecara musi uwzględniać rzeczywisty czas startu aplikacji, do której wysyła żądanie reload.
- Poprawny EndpointSlice nie gwarantuje, że lokalny stan tuneli remotedialera został zsynchronizowany.
- Doraźny resync naprawia stan, ale nie zastępuje ustalenia przyczyny.
Następna sesja¶
Diagnostyka Hubble. Problem remotedialera pozostaje zapisany jako osobny, nierozstrzygnięty wątek do porównania podczas kolejnych uruchomień klastra.