Migracja do chmury i rosnąca popularność kontenerów, w tym Kubernetes, stawiają przed administratorami baz danych nowe wyzwania. Choć technologie te obiecują elastyczność i skalowalność, pojawiają się również obawy, szczególnie w kontekście systemów zarządzania bazami danych, jak PostgreSQL. Jedną z kluczowych kwestii jest trwałość danych. Jak zapewnić, by cenne informacje nie zostały utracone w dynamicznym środowisku kontenerowym? Równie ważna jest wydajność – czy uruchomienie PostgreSQL w kontenerze nie wpłynie negatywnie na jego szybkość? Wreszcie pojawia się obawa o złożoność wdrożenia. Warto podkreślić, że omawiane rozwiązania nie są optymalne dla pojedynczych instancji PostgreSQL. Ich prawdziwa wartość ujawnia się w zarządzaniu wieloma klastrami. W tym artykule przedstawimy rozwiązanie CloudNativePG, wyjaśniając, czym jest i jakie oferuje funkcjonalności. Skupimy się także na praktyce, demonstrując, jak postawić pierwszy klaster PostgreSQL w kontenerach oraz omawiając jego składowe przedstawione w pliku YAML.
W kontekście zarządzania bazami danych PostgreSQL w Kubernetes CloudNativePG jest operatorem PostgreSQL typu open source, zaprojektowanym z myślą o środowiskach wysokiej dostępności (HA). Nie jest to jedynie PostgreSQL uruchomiony w kontenerze, lecz kompleksowe narzędzie, które w pełni wykorzystuje możliwości Kubernetes do automatyzacji, orkiestracji i zarządzania klastrami PostgreSQL.
Warto podkreślić, że CloudNativePG celuje w dostarczenie możliwości z najwyższego poziomu – Poziomu V (Auto Pilot) – w systemie klasyfikacji funkcji zarządzania operatorów, bazującym na Operator SDK Capability Levels framework. Poziomy te określają zakres funkcji, które udostępnia operator – od podstawowej instalacji (Poziom I) po pełną automatyzację i samoadaptację (Poziom V). Choć CloudNativePG dąży do maksymalnej automatyzacji i autonomii w zarządzaniu klastrami, jego dokumentacja zaznacza, że użytkownik może spodziewać się części funkcjonalności przypisanych do Poziomu V. Więcej na ten temat znajdziesz w sekcji Operator Capability Levels w oficjalnej dokumentacji.
Głównym celem CloudNativePG jest uproszczenie wdrażania i zarządzania PostgreSQL w Kubernetes, eliminując wiele ręcznych zadań, które tradycyjnie są związane z utrzymaniem baz danych. Zamiast martwić się o replikację, przełączanie awaryjne (failover), tworzenie kopii zapasowych czy skalowanie, CloudNativePG automatyzuje te procesy, integrując się z mechanizmami Kubernetes.
Spis treści:
- Jakie kluczowe funkcjonalności oferuje CloudNativePG?
- Praktyczne wdrożenie – Twój pierwszy klaster PostgreSQL z CloudNativePG
- Podsumowanie i dalsze kroki
Jakie kluczowe funkcjonalności oferuje CloudNativePG?
- Zapewnienie wysokiej dostępności i odporności na awarie – operator automatycznie zarządza replikacją strumieniową PostgreSQL i zapewnia automatyczne przełączanie awaryjne w przypadku awarii węzła lub instancji, minimalizując przestoje.
- Łatwe skalowanie – operator umożliwia proste zwiększanie lub zmniejszanie liczby replik, co pozwala dostosować wydajność odczytów do bieżących potrzeb.
- Tworzenie kopii zapasowych i odzyskiwanie danych – CloudNativePG integruje się z popularnymi rozwiązaniami do przechowywania danych w chmurze z interfejsem S3, umożliwiając łatwe tworzenie kopii zapasowych, archiwizację plików WAL oraz odzyskiwanie danych.
- Monitorowanie i observability – operator udostępnia metryki Prometheus, co pozwala na monitorowanie stanu i wydajności baz danych w Kubernetes.
- Zarządzanie cyklem życia klastra – od początkowego wdrożenia, przez aktualizacje, po usuwanie klastra – CloudNativePG zarządza całym cyklem życia bazy danych.
- Bezpieczeństwo – oferuje funkcje, takie jak integracja z systemami zarządzania certyfikatami Kubernetes, co ułatwia bezpieczną komunikację.
Dzięki tym funkcjonalnościom CloudNativePG staje się potężnym narzędziem dla administratorów i deweloperów, którzy chcą uruchamiać PostgreSQL w sposób niezawodny, skalowalny i efektywny w środowisku Kubernetes.
W tym kontekście warto wspomnieć o Lekkiej Platformie Konteneryzacji (LPK) – stworzonym przez nas rozwiązaniu, które ułatwia integrację i zarządzanie narzędziami do monitorowania oraz zabezpieczenia Kubernetes. LPK została stworzona po to, by organizacje mogły szybko wdrożyć spersonalizowaną, bezpieczną platformę konteneryzacji z modułów, w skład których wchodzą komponenty takie jak Prometheus, Istio, Kibana Elastic, Jaeger, Kyverno, Kubewarden, Sealed Secret, NeuVector, Conjur (CyberArk) czy HashiCorp Vault – bez potrzeby ręcznego konfigurowania każdego elementu.
Modułowa budowa Lekkiej Platformy Konteneryzacji pozwala dobierać tylko te komponenty, które są niezbędne, co znacząco upraszcza wdrożenie i późniejsze utrzymanie. Dowiedz się więcej na temat LPK: https://linuxpolska.com/pl/rozwiazania/lekka-platforma-konteneryzacji/.
Praktyczne wdrożenie – Twój pierwszy klaster PostgreSQL z CloudNativePG
Mając już podstawową wiedzę o CloudNativePG i jego możliwościach, przejdźmy do praktyki. Poniżej opisujemy dwa kroki niezbędne do uruchomienia klastra z trzema instancjami. Zaznaczyć tutaj musimy, że krok drugi jest w wersji A i B. Kolejno wersja podstawowa i bardziej rozbudowana. Czytelnik może wybrać, której użyje.
Krok 1. Instalacja Operatora CloudNativePG
Pierwszym i najważniejszym krokiem do uruchomienia PostgreSQL w Kubernetes za pomocą CloudNativePG jest instalacja samego operatora. Użyjemy do tego wersji v1.26.1, wydanej 25 lipca 2025 roku, której dokumentację można znaleźć pod adresem: https://cloudnative-pg.io/documentation/1.26/.
Warto zaznaczyć, że społeczność CloudNativePG działa niezwykle prężnie. Zaledwie kilka dni później, 29 lipca, pojawiła się wersja v1.27.0-rc1. Nowsza wersja wprowadza bardzo użyteczną funkcjonalność, której brakowało w poprzednich architekturach PostgreSQL – mianowicie synchronizację i migrację slotów używanych do replikacji logicznej. To znacząco ułatwia zarządzanie i utrzymanie baz danych w dynamicznym środowisku kontenerowym.
Instalacja operatora z użyciem manifestu:
kubectl apply --server-side -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.26/releas es/cnpg-1.26.1.yaml
Weryfikację poprawności instalacji przeprowadzamy za pomocą poniższej komendy:
kubectl rollout status deployment \
-n cnpg-system cnpg-controller-manager
deployment "cnpg-controller-manager" successfully rolled out
➜ ~ kubectl get deployments -n cnpg-system
NAME READY UP-TO-DATE AVAILABLE AGE cnpg-controller-manager 1/1 1 1 20d
Dla bardziej dociekliwych, szczegółowy opis deploymentu cnpg-controller-manager jest dostępny po wpisaniu komendy:
kubectl describe deploy -n cnpg-system cnpg-controller-manager
Krok 2A. Deklaratywny deployment klastra PostgreSQL – prosta konfiguracja
Jedynie osiem wierszy (nie wliczając pustej linii) jest potrzebnych do utworzenia klastra z trzema węzłami, który w znakomity sposób chroniony jest mechanizmami HA przez CloudNativePG.

Krok 2B. Deklaratywny deployment klastra PostgreSQL – rozbudowana konfiguracja

Do konfiguracji, jaką wykonamy, dołożymy „kilka” dodatkowych, które pozwolą zachować porządek w naszych obiektach Kubernetesa oraz umożliwią nam bezpieczny dostęp do bazy danych.
PORZĄDEK: w pierwszej kolejności zadbajmy o to, aby nasze obiekty były rozłożone w zorganizowany sposób. Do tego celu służą przestrzenie nazw (namespace). Możemy to wykonać na dwa sposoby:
- kubectl create namespace lp
- konfiguracja w pliku YAML ( wiersz [1:4] )
BEZPIECZEŃSTWO: tworzymy użytkownika usrlp w namespace, gdzie będzie działał klaster cluster-linuxpolska ( wiersz[8:16] ). W sekcji bootstrap ( wiersz[29:34] ) uczynimy go właścicielem bazy danych db_app. Zakodowane ciągi znaków odpowiadające kolejno username i password kodujemy przy użyciu base 64. Ponieważ nazwa użytkownika i hasło są identyczne, zakodowane ciągi znaków są takie same. Zgodnie z konwencją przyjętą w K8s, tworzony obiekt będzie typu Secret.
➜ cluster-linuxpolska echo -n "usrlp" | base64
dXNybHA=
DOSTĘP: w celu umożliwienia dostępu musimy wykonać dwie czynności.
Pierwszą z nich odpowiednie ustawienie Host Base Access (wiersz[36:39]). Klasycznie wszystkie ustawienia konfigurowaliśmy w pliku pg_hba.conf. W naszym klastrze CNPG robi się to bardzo podobnie, a mianowicie poprzez deklarację w pliku YAML, co na dalszym etapie przepisywane jest do pliku pg_hba.conf w kontenerach. Nie zapominajmy, że w Kubernetes w dużym uproszczeniu znajduje się PostgreSQL, który zawiera tak samo zbudowany katalog PGDATA. Tam nadal znajdują się pliki postgresql.conf, pg_hba.conf oraz reszta wraz ze standardowymi katalogami. Poniżej output komendy ls -la zawartości katalogu w jednym z kontenerów.
➜ cluster-linuxpolska kubectl exec -it -n lp cluster-linuxpolska-1 -- bash
Defaulted container "postgres" out of: postgres, bootstrap-controller (init)
postgres@cluster-linuxpolska-1:/$ ls -la /var/lib/postgresql/data/pgdata
total 144
drwx------. 19 postgres tape 4096 Aug 1 12:16 .
drwxrwsr-x. 4 root tape 4096 Aug 1 12:11 ..
drwxrws---. 7 postgres tape 4096 Aug 1 12:12 base
-rw-------. 1 postgres tape 36 Aug 1 12:16 current_logfiles
-rw-r--r--. 1 postgres tape 1197 Aug 1 12:11 custom.conf
drwxrws---. 2 postgres tape 4096 Aug 1 12:15 global
-rw-rw----. 1 postgres tape 448 Aug 1 12:11 override.conf
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_commit_ts
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_dynshmem
-rw-r--r--. 1 postgres tape 438 Aug 1 12:16 pg_hba.conf
-rw-r--r--. 1 postgres tape 112 Aug 1 12:11 pg_ident.conf
drwxrws---. 4 postgres tape 4096 Aug 1 12:17 pg_logical
drwxrws---. 4 postgres tape 4096 Aug 1 12:11 pg_multixact
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_notify
drwxrws---. 4 postgres tape 4096 Aug 1 12:12 pg_replslot
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_serial
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_snapshots
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_stat
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_stat_tmp
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_subtrans
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_tblspc
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_twophase
-rw-rw----. 1 postgres tape 3 Aug 1 12:11 PG_VERSION
drwxrws---. 4 postgres tape 4096 Aug 1 12:17 pg_wal
drwxrws---. 2 postgres tape 4096 Aug 1 12:11 pg_xact
-rw-rw----. 1 postgres tape 88 Aug 1 12:11 postgresql.auto.conf
-rw-rw----. 1 postgres tape 30921 Aug 1 12:11 postgresql.conf
-rw-rw----. 1 postgres tape 75 Aug 1 12:11 postmaster.opts
-rw-------. 1 postgres tape 98 Aug 1 12:11 postmaster.pid
Drugą czynnością jest „wystawienie” naszego klastra na zewnątrz. Tutaj mam na myśli uruchomienie interfejsu, po którym użytkownicy będą mogli się łączyć z bazą danych. W konfiguracji dodamy kilka linii, dzięki którym nasza baza będzie widoczna pod adresem IP (wiersz[43:50]). Można to wykonać na kilka sposobów, a mianowicie plik YAML lub też edycja utworzonego interfejsu i zmiana z typu ClusterIP na LoadBalancer. Chcąc uzyskać na koniec naszych prac jeden plik YAML, zdecydujemy się wpisać w niego konfigurację.
To koniec deklaratywnej konfiguracji naszego klastra. W pliku cluster-linuxpolska.yaml zapisaliśmy nasze wymagania, które możemy następnie zlecić do utworzenia. Pamiętajmy, że większość parametrów PostgreSQL może być nadal przez nas zmieniana, tak, jak to było z bazami na bare metal czy VM. Odbywa się to jednak inaczej, a mianowicie przez deklarację w pliku YAML i ponowne wykonanie komendy kubectl apply -f. Trzeba jednak być ostrożnym i świadomym ich działania. Na przykład parametr instances możemy skalować w górę i w dół, natomiast raz zwiększone miejsce storage nie pozwoli na operację shrinkowania tzn. zmniejszenia.
Poniżej komendy i output listujący komponenty utworzonego klastra:
➜ cluster-linuxpolska kubectl -n lp get pods
NAME READY STATUS RESTARTS AGE
cluster-linuxpolska-1 1/1 Running 0 115m
cluster-linuxpolska-2 1/1 Running 0 114m
cluster-linuxpolska-3 1/1 Running 0 114m
➜ cluster-linuxpolska kubectl -n lp get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
cluster-linuxpolska-1 Bound pvc-398d33f9-3768-4166-b815-341254fe24f5 1Gi RWO vsphere-csi-sc <unset> 115m
cluster-linuxpolska-2 Bound pvc-480d1bff-3fc1-46ae-94ca-1d7fccf11765 1Gi RWO vsphere-csi-sc <unset> 115m
cluster-linuxpolska-3 Bound pvc-c3157404-aa72-472b-af05-49075debe177 1Gi RWO vsphere-csi-sc <unset> 114m
➜ cluster-linuxpolska kubectl -n lp get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-linuxpolska-r ClusterIP 10.43.179.100 <none> 5432/TCP 115m
cluster-linuxpolska-ro ClusterIP 10.43.96.177 <none> 5432/TCP 115m
cluster-linuxpolska-rw ClusterIP 10.43.157.206 <none> 5432/TCP 115m
cluster-linuxpolska-rw-lb LoadBalancer 10.43.247.116 10.10.12.165 5432:32199/TCP 115m
Podsumowanie i dalsze kroki
CloudNativePG to bardzo obszerny temat, a rozwiązanie to już teraz ma mnóstwo do zaoferowania. Może stać się następcą tradycyjnych rozwiązań bare metal oraz maszyn wirtualnych. W trakcie czytania artykułu z pewnością mogło nasunąć się kilka pytań. Na wszystkie można znaleźć odpowiedzi, jednak nie sposób omówić ich w jednym tekście. Dlatego tym artykułem rozpoczynamy serię poświęconą CloudNativePG.
Wdrożenie klastra PostgreSQL w Kubernetes jest teraz zaskakująco proste. Prawdziwa moc CloudNativePG tkwi jednak w jego zaawansowanych funkcjonalnościach, które automatyzują operacje i zapewniają wysoką dostępność, bezpieczeństwo oraz skalowalność. Poniżej kluczowe zalety CloudNativePG, które czynią to rozwiązanie liderem w swojej klasie:
- High Availability (HA): zapewnia automatyczne przełączanie awaryjne oraz planowane przełączanie (switchover), minimalizując przestoje;
- deklaratywne zarządzanie konfiguracją: zgodnie z filozofią „immutable infrastructure” możemy zarządzać konfiguracją PostgreSQL wprost z pliku YAML;
- kompleksowe backupy i odzyskiwanie (DR): dzięki integracji z magazynami obiektów (np. S3) i wsparciu dla Point-In-Time Recovery (PITR), ciągły backup i odzyskiwanie danych są niezawodne;
- zaawansowane topologie dystrybucyjne: możliwość tworzenia klastrów replik rozciągających się na wiele środowisk gwarantuje maksymalną odporność;
- skalowalność i elastyczność: możliwość skalowania w górę i w dół liczby instancji oraz integracja z PgBouncer pozwalają optymalizować wydajność;
- bezproblemowe aktualizacje: dzięki rolling updates i aktualizacjom in-place, aktualizacje operatora i wersji PostgreSQL są płynne i minimalizują przestoje;
- observability: pełna integracja z Prometheus i Grafana zapewnia dogłębne monitorowanie Twojego klastra.
Sprawdź, w czym możemy Ci pomóc w temacie konteneryzacji: https://linuxpolska.com/pl/oferta/konteneryzacja/.
