34 - aktualizacja stosu obserwowalności i baz danych¶
Data: 2026-10-01
Środowisko końcowe: 3× HP T630, K3s v1.36.4+k3s1, Cilium 1.20.2, Longhorn 1.12.1, kube-prometheus-stack 91.8.2, Prometheus 3.15.0, Alertmanager 0.34.1, Grafana 13.2.3, CloudNativePG 1.30.1, PostgreSQL 17.11, Alloy 1.20.0, Loki 3.7.8
Cel sesji¶
- Sprawdzić stan klastra po ponownym uruchomieniu.
- Zaktualizować kube-prometheus-stack w obrębie wersji
91.x. - Zaktualizować operator CloudNativePG.
- Wykonać zabezpieczoną aktualizację PostgreSQL
17.4 → 17.11, najpierw na stagingu, a następnie na produkcji. - Zaktualizować Alloy i potwierdzić dalsze wysyłanie logów.
- Zaktualizować Loki w obrębie wersji głównej chartu
18.x. - Ocenić możliwość aktualizacji Longhorna bez wykonywania ryzykownej zmiany.
1. Kontrola klastra po starcie¶
Prometheus po starcie klastra osiągnął stan:
Pod: prometheus-kube-prometheus-stack-prometheus-0
Ready: 2/2
Status: Running
Restarts: 0
Node: master
Custom Resource Prometheusa miał:
Wolumen Prometheusa:
PVC: prometheus-kube-prometheus-stack-prometheus-db-prometheus-kube-prometheus-stack-prometheus-0
Longhorn: attached, healthy
Node: master
Replicas: 2
Scheduled: True
Restore: niewymagany
Obie repliki Longhorna działały na worker1 i worker2, bez błędów ani prób przebudowy.
Prometheus ocenił wszystkie reguły poprawnie:
Grafana nie zgłaszała nowych timeoutów, blokad SQLite ani błędów HTTP 5xx.
Uwaga dotycząca powłoki¶
Pierwsza próba uruchomienia kubectl port-forward zakończyła się lokalnym błędem:
Przyczyną było aktywne noclobber, a nie awaria klastra. Do kontrolowanego nadpisania pliku użyto operatora:
2. Aktualizacja kube-prometheus-stack¶
Stan początkowy:
W repozytorium Helm dostępna była wersja:
Porównanie renderów 91.8.1 i 91.8.2 wykazało zmianę wyłącznie w podcharcie Grafany:
Pozostałe obrazy nie zmieniły wersji.
Po aktualizacji Flux zgłosił:
Grafana po rollout:
image: docker.io/grafana/grafana:13.2.3-distroless
Ready: true,true,true
Restarts: 0,0,0
database: ok
Zachowano wcześniej dobrane parametry:
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 500m
memory: 1280Mi
env:
GOMEMLIMIT: 900MiB
grafana.ini:
plugins:
preinstall_disabled: true
Bezpośrednio po starcie wystąpiła pojedyncza krótka blokada SQLite:
Ponowne sprawdzenie ostatniej minuty logów nie wykazało dalszych blokad ani błędów. Dashboardy i API Grafany działały prawidłowo.
3. Aktualizacja operatora CloudNativePG¶
Przed zmianą oba klastry PostgreSQL były zdrowe:
| Namespace | Cluster | Instancje | Ready | Primary |
|---|---|---|---|---|
clients |
clients-db |
2 | 2 | clients-db-2 |
clients-staging |
clients-db-staging |
2 | 2 | clients-db-staging-1 |
Stan początkowy operatora:
Wersja docelowa:
Porównanie renderów wykazało:
- aktualizację obrazu operatora
1.30.0 → 1.30.1; - zmianę checksum konfiguracji i RBAC;
- brak zmian wersji i trybu przechowywania CRD;
- brak zmian w zasobach i konfiguracji operatora ustawionych w HelmRelease.
Po aktualizacji:
- operator działał w wersji
1.30.1; - init container każdej instancji PostgreSQL używał
cloudnative-pg:1.30.1; - oba klastry pozostały
2/2 Ready; - role primary/replica były prawidłowe;
- usługi
-rw,-roi-rwskazywały właściwe endpointy; - logi operatora po ustabilizowaniu nie zawierały błędów.
4. Backup logiczny przed aktualizacją PostgreSQL¶
Przed zmianą obrazu PostgreSQL wykonano lokalny backup logiczny obu klastrów.
Katalog backupu:
Katalog utworzono z prawami 0700, a pliki z prawami 0600.
Dla każdego klastra wykonano:
pg_dumpall --globals-only;- listę baz użytkownika;
pg_dump --format custom --createkażdej bazy;- weryfikację każdego pliku przez
pg_restore --list; - zapis i sprawdzenie sum
SHA256SUMS.
Zabezpieczone bazy:
Weryfikacja dumpów aplikacyjnych wykazała po 12 obiektów i po 3 sekcje TABLE DATA. Wszystkie sumy SHA-256 były poprawne.
Istotne ograniczenie: klastry CloudNativePG nadal nie mają skonfigurowanych zasobów Backup ani ScheduledBackup. Lokalny backup logiczny zabezpieczał tę aktualizację, ale nie zastępuje docelowej polityki regularnych backupów.
5. Kontrole zgodności PostgreSQL¶
Przed aktualizacją potwierdzono:
- bieżącą wersję PostgreSQL
17.4; - system kolacji
Cdla baz aplikacyjnych ipostgres; - brak dodatkowych rozszerzeń poza
plpgsql; - brak indeksów BRIN;
- brak samoodwołujących kluczy obcych na tabelach partycjonowanych;
- wyłącznie fizyczne sloty replikacji CloudNativePG;
- mały rozmiar baz, około
8 MiBdla każdej bazy aplikacyjnej; - brak konieczności wykonania
pg_upgrade, ponieważ była to aktualizacja patch w obrębie PostgreSQL 17.
Wybrany obraz:
Obraz przypięto również do digestu:
Wybór wariantu standard-bookworm zachował bazę Debian 12 i nie wprowadzał jednoczesnej migracji systemu bazowego do Trixie.
6. Aktualizacja PostgreSQL na stagingu¶
Najpierw zmieniono manifest na branchu staging:
Render Kustomize potwierdził:
Server-side dry-run zakończył się powodzeniem przed zastosowaniem zmiany przez GitOps.
Po rollout:
Cluster: clients-db-staging
Ready: 2/2
Primary: clients-db-staging-1
PostgreSQL: 17.11
OS: Debian 12
Restarts: 0
Primary zwracał pg_is_in_recovery() = false, a replika true.
Dane aplikacyjne po aktualizacji:
Endpoint aplikacji staging zwracał:
W czasie restartu instancji pojawiły się spodziewane ostrzeżenia HikariCP dotyczące zamkniętych połączeń oraz chwilowy błąd operatora podczas startu PostgreSQL. Po minucie aplikacja i operator miały czyste logi.
7. Aktualizacja PostgreSQL na produkcji¶
Po pozytywnym teście stagingu zmieniono:
Przed aktualizacją zapisano stan tabel produkcyjnych. Manifest przeszedł:
- render Kustomize;
git diff --check;- server-side dry-run API Kubernetes.
Po rollout:
Obie instancje używały dokładnie tego samego digestu obrazu. Porównanie statystyk tabel przed i po zmianie nie wykazało różnic.
API produkcyjne zwracało:
Podczas przełączania instancji aplikacja rejestrowała krótkotrwałe ostrzeżenia HikariCP o zamkniętych połączeniach. Po 90 sekundach oba Pody aplikacji oraz operator miały czyste logi.
Endpoint clients-db-rw wskazywał wyłącznie gotowy Pod primary:
8. Aktualizacja Alloy¶
Alloy został zaktualizowany przez Flux:
Stan DaemonSetu po rollout:
Na każdym nodzie działał jeden Pod Alloy. Wszystkie kontenery były gotowe i miały 0 restartów.
Logi Alloy i config-reloadera nie zawierały błędów, odpowiedzi HTTP 429/5xx ani problemów z autoryzacją.
Kontrolne zapytanie Loki:
zwróciło 1750 linii. Potwierdziło to dalsze zbieranie logów po aktualizacji kolektora.
9. Przygotowanie aktualizacji Loki¶
Bieżące źródło chartu:
Repozytorium zostało również dodane lokalnie do klienta Helm w celu poprawnego renderowania chartu.
Stan początkowy:
Wersja docelowa:
Nie była to ponowna duża migracja Loki. Migrację przez kolejne wersje główne chartu, zmianę repozytorium oraz przejście do jawnego trybu Monolithic wykonano wcześniej. Dzisiejsza zmiana pozostała w obrębie wersji głównej chartu 18.x.
Porównanie renderów potwierdziło:
- jeden StatefulSet
loki; - jedną replikę;
- niezmieniony
config.yaml; - niezmienione volumes i volume mounts;
- niezmieniony claim
storageo wielkości10Gi; - brak zmiany sposobu użycia Garage S3;
- zmianę wyłącznie obrazów Loki i sidecara.
Zabezpieczenie PVC nadal było aktywne:
Istniejący PVC przed zmianą:
PVC: storage-loki-0
Status: Bound
PV: pvc-54bdf342-b185-48d4-a829-c90c4cd93f07
StorageClass: longhorn
Capacity: 10Gi
AccessMode: ReadWriteOnce
10. Aktualizacja Loki¶
HelmRelease został zaktualizowany:
Flux zakończył operację:
StatefulSet wykonał poprawny rollout. Stan końcowy Poda:
Obrazy:
Pod zachował claim:
Longhorn poprawnie przepiął wolumen na worker2:
API buildinfo zwróciło:
Kontrolne zapytanie z ostatnich pięciu minut zwróciło 1853 linie z kolektora Alloy.
11. Przejściowe komunikaty memberlist Loki¶
Podczas startu pojedynczego Poda ponownie wystąpiły komunikaty:
failed to resolve loki-memberlist.loki.svc.cluster.local
empty ring
failed to fast-join the memberlist cluster
Przyczyną była kolejność startu:
- Pod Loki nie był jeszcze gotowy.
- Headless Service nie miał gotowego endpointu.
- CoreDNS chwilowo zwracał
no such host. - Loki automatycznie utworzył jednoelementowy ring.
- Po uzyskaniu readiness EndpointSlice opublikował adres Poda.
Stan po ustabilizowaniu:
Log Loki potwierdził:
Nie był to trwały błąd DNS ani regresja po aktualizacji.
12. Stan końcowy¶
Monitoring¶
kube-prometheus-stack: 91.8.2
Prometheus: 3.15.0
Alertmanager: 0.34.1
Grafana: 13.2.3-distroless
Grafana database: ok
Prometheus rules: 229 ok, 0 problematycznych
PostgreSQL¶
CloudNativePG chart: 0.29.1
CloudNativePG operator: 1.30.1
PostgreSQL: 17.11, Debian 12
clients-db: 2/2 Ready
clients-db-staging: 2/2 Ready
Logi¶
Alloy chart: 1.13.0
Alloy: 1.20.0
Alloy DS: 3/3 Ready
Loki chart: 18.13.7
Loki: 3.7.8
Loki Pod: 2/2 Ready, 0 restartów
Storage¶
Longhorn: 1.12.1
Nodes: 3/3 Ready i Schedulable
Volumes: 6/6 attached i healthy
Failed replicas: 0
Upgrade do 1.13.0: odłożony
14. Wnioski¶
- PVC nie jest samym wolumenem. Jest żądaniem storage, które Kubernetes wiąże z PV; Longhorn dostarcza implementację storage, repliki, attach/detach, odbudowę i kontrolę zdrowia.
- Aktualizacje operatora i zarządzanego przez niego operand muszą być rozdzielone. Najpierw zaktualizowano CloudNativePG, później PostgreSQL.
- Aktualizację bazy należy rozpocząć od stagingu i przejść na produkcję dopiero po sprawdzeniu danych, replikacji, endpointów oraz aplikacji.
- Backup logiczny należy nie tylko utworzyć, lecz także zweryfikować przez
pg_restore --listi sumy kontrolne. - Przypięcie obrazu do digestu gwarantuje identyczny artefakt na wszystkich instancjach.
- Przy aktualizacji PostgreSQL krótkie ostrzeżenia puli połączeń są spodziewane, jeśli znikają po zakończeniu restartów, a health check wraca do
UP. - Pusty diff konfiguracji Loki oraz identyczny szablon PVC ograniczyły zakres aktualizacji do wymiany obrazów.
- Przejściowy błąd memberlist podczas startu jednej repliki Loki nie oznacza awarii, jeśli później EndpointSlice jest gotowy, ring się łączy, a nowe logi są zapisywane.
- Poprawny stan bieżącej wersji jest ważniejszy niż samo posiadanie najnowszego wydania. Longhorn
1.13.0świadomie odłożono ze względu na świeżość i znaczenie warstwy storage. - Aktualizacje były wykonywane przez GitOps i kontrolowane za pomocą renderów Helm/Kustomize, dry-runów, rollout status, logów, endpointów oraz testów aplikacyjnych.
15. Następna sesja¶
- Skonfigurować regularny backup klastrów CloudNativePG zamiast polegać wyłącznie na ręcznych dumpach.
- Zinwentaryzować Data Engine wszystkich wolumenów Longhorna.
- Sprawdzić możliwość wykonania Longhorn System Backup i backupów danych przed przyszłą aktualizacją.
- Poczekać na ustabilizowanie linii
1.13.x, preferencyjnie co najmniej1.13.1, przed aktualizacją krytycznej warstwy storage. - Osobno rozważyć ServiceMonitor i reguły Prometheus dla komponentów, które nadal nie eksportują metryk do bieżącego stosu monitoringu.