Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie

Coraz częściej pojawiają się takie prośby od klientów: „Chcemy jak Amazon RDS, ale taniej”; „Chcemy tego jak RDS, ale wszędzie, w dowolnej infrastrukturze”. Aby wdrożyć takie zarządzane rozwiązanie na Kubernetesie, przyjrzeliśmy się aktualnemu stanowi najpopularniejszych operatorów dla PostgreSQL (Stolon, operatory z Crunchy Data i Zalando) i dokonaliśmy wyboru.

Artykuł ten to nasze doświadczenia zarówno z punktu widzenia teoretycznego (przegląd rozwiązań), jak i praktycznego (co zostało wybrane i co z tego wyszło). Ale najpierw zdefiniujmy, jakie są ogólne wymagania dotyczące potencjalnego zamiennika RDS…

Co to jest RDS

Z naszego doświadczenia wynika, że ​​kiedy ludzie mówią o RDS, mają na myśli zarządzaną usługę DBMS, która:

  1. łatwy w konfiguracji;
  2. ma możliwość pracy z migawkami i odzyskiwania z nich (najlepiej z obsługą PITR);
  3. umożliwia tworzenie topologii master-slave;
  4. posiada bogatą listę rozszerzeń;
  5. zapewnia audyt i zarządzanie użytkownikami/dostępem.

Generalnie podejścia do realizacji zadania mogą być bardzo różne, jednak droga z warunkowym Ansiblem nie jest nam bliska. (Koledzy z 2GIS doszli do podobnego wniosku w wyniku jego próba utwórz „Narzędzie szybkiego wdrażania klastra pracy awaryjnej oparte na Postgres”.)

To właśnie operatorzy stanowią ogólnie przyjęte podejście do rozwiązywania tego typu problemów w ekosystemie Kubernetes. Szerzej o nich w odniesieniu do baz danych działających wewnątrz Kubernetesa opowiadał już dyrektor techniczny Flant, dysstolw jeden ze swoich raportów.

NB: Aby szybko tworzyć proste operatory, zalecamy zwrócenie uwagi na nasze narzędzie Open Source operator powłoki. Dzięki niemu możesz to zrobić bez znajomości Go, ale w sposób bardziej znany administratorom systemu: w Bash, Pythonie itp.

Istnieje kilka popularnych operatorów K8s dla PostgreSQL:

  • stolon;
  • Operator PostgreSQL Crunchy Data;
  • Operator Zalando Postgres.

Przyjrzyjmy się im bliżej.

Wybór operatora

Oprócz ważnych funkcji wspomnianych już powyżej, my – jako inżynierowie infrastruktury w Kubernetes – oczekiwaliśmy od operatorów również:

  • wdrożyć z Git i za pomocą Zasoby niestandardowe;
  • wsparcie antypowinowactwa podów;
  • instalowanie powinowactwa węzła lub selektora węzła;
  • ustawianie tolerancji;
  • dostępność opcji strojenia;
  • zrozumiałe technologie, a nawet polecenia.

Nie wchodząc w szczegóły dotyczące każdego z punktów (zapytaj w komentarzach, czy po przeczytaniu całego artykułu nadal masz pytania na ich temat), zaznaczę ogólnie, że parametry te są potrzebne do bardziej subtelnego opisu specjalizacji węzłów klastrów w w celu zamówienia ich do konkretnych zastosowań. W ten sposób możemy osiągnąć optymalną równowagę pomiędzy wydajnością i kosztami.

Teraz - do samych operatorów PostgreSQL.

1. Stolon

Stołoń od włoskiej firmy Sorint.lab in wspomniany już raport był uważany za swego rodzaju standard wśród operatorów SZBD. To dość stary projekt: jego pierwsze publiczne wydanie miało miejsce w listopadzie 2015 roku (!), a repozytorium GitHub może pochwalić się prawie 3000 gwiazdami i ponad 40 współtwórcami.

Rzeczywiście Stolon jest doskonałym przykładem przemyślanej architektury:

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie
Urządzenie tego operatora można znaleźć szczegółowo w raporcie lub dokumentacja projektu. Ogólnie rzecz biorąc, wystarczy powiedzieć, że może zrobić wszystko, co opisano: przełączanie awaryjne, proxy dla przezroczystego dostępu klienta, kopie zapasowe… Co więcej, proxy zapewniają dostęp przez jedną usługę punktu końcowego - w przeciwieństwie do dwóch pozostałych rozwiązań omówionych poniżej (posiadają dwie usługi dostępu baza).

Jednak Stolon brak zasobów niestandardowych, dlatego nie można go wdrożyć w taki sposób, aby łatwo i szybko – „jak ciepłe bułeczki” – można było stworzyć instancje DBMS w Kubernetesie. Zarządzanie odbywa się za pośrednictwem narzędzia stolonctl, wdrożenie - poprzez Helm-chart, a niestandardowe są zdefiniowane w ConfigMap.

Z jednej strony okazuje się, że operator tak naprawdę nie jest operatorem (bo nie korzysta z CRD). Ale z drugiej strony jest to elastyczny system, który pozwala konfigurować zasoby w K8s tak, jak chcesz.

Podsumowując, dla nas osobiście nie wydawało się to najlepszym sposobem na rozpoczęcie osobnego wykresu dla każdej bazy danych. Zaczęliśmy więc szukać alternatyw.

2. Operator PostgreSQL Crunchy Data

Operator z Crunchy Data, młody amerykański startup, wydawał się logiczną alternatywą. Jego publiczna historia zaczyna się od pierwszego wydania w marcu 2017 r. i od tego czasu repozytorium GitHub otrzymało prawie 1300 gwiazdek i ponad 50 współpracowników. Najnowsza wersja z września została przetestowana pod kątem współpracy z Kubernetes 1.15-1.18, OpenShift 3.11+ i 4.4+, GKE i VMware Enterprise PKS 1.3+.

Architektura operatora Crunchy Data PostgreSQL spełnia również podane wymagania:

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie

Zarządzanie odbywa się poprzez narzędzie pgojednak z kolei generuje zasoby niestandardowe dla Kubernetes. Dlatego operator zadowolił nas jako potencjalnych użytkowników:

  • istnieje kontrola poprzez CRD;
  • wygodne zarządzanie użytkownikami (również poprzez CRD);
  • integrację z innymi komponentami Pakiet Crunchy Data Container Suite - wyspecjalizowana kolekcja obrazów kontenerów dla PostgreSQL i narzędzi do pracy z nim (m.in. pgBackRest, pgAudit, rozszerzenia z contrib itp.).

Jednak próby rozpoczęcia korzystania z operatora z Crunchy Data ujawniły kilka problemów:

  • Nie było możliwości tolerancji - dostępny jest tylko nodeSelector.
  • Utworzone pody były częścią wdrożenia, mimo że wdrażaliśmy aplikację stanową. W przeciwieństwie do StatefulSets, wdrożenia nie mogą tworzyć dysków.

Ostatnia wada prowadzi do zabawnych momentów: na środowisku testowym udało nam się uruchomić 3 repliki na jednym dysku Lokalny magazyn, w wyniku czego operator zgłosił, że działają 3 repliki (choć tak nie było).

Kolejną cechą tego napędu jest jego gotowa integracja z różnymi systemami pomocniczymi. Na przykład łatwo jest zainstalować pgAdmin i pgBounce oraz w dokumentacja brane są pod uwagę wstępnie skonfigurowane Grafana i Prometheus. W niedawnym wydanie 4.5.0-beta1 odrębnie zauważono lepszą integrację z projektem pgMonitor, dzięki czemu operator oferuje wizualną wizualizację metryk PgSQL od razu po wyjęciu z pudełka.

Jednak dziwny wybór zasobów generowanych przez Kubernetes doprowadził nas do znalezienia innego rozwiązania.

3. Operator Zalando Postgres

Produkty Zalando są nam znane od dawna: mamy doświadczenie w stosowaniu Zalenium i oczywiście próbowaliśmy Patroni to ich popularne rozwiązanie HA dla PostgreSQL. O podejściu firmy do tworzenia Operator PostgreSQL powiedział na antenie jeden z jego autorów – Aleksiej Klyukin Postgres – wtorek nr 5i podobało nam się to.

To najmłodsze rozwiązanie omawiane w artykule: pierwsza premiera miała miejsce w sierpniu 2018 roku. Jednak pomimo niewielkiej liczby oficjalnych wydań projekt przeszedł długą drogę, wyprzedzając już popularność rozwiązania Crunchy Data z ponad 1300 gwiazdkami na GitHubie i maksymalną liczbą współpracowników (70+).

„Pod maską” tego operatora stosowane są sprawdzone rozwiązania:

Oto jak prezentuje się architektura operatorów od Zalando:

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie

Operator jest w pełni zarządzany za pomocą zasobów niestandardowych, automatycznie tworzy zestaw stanowy z kontenerów, który można następnie dostosować, dodając do kapsuły różne wózki boczne. Wszystko to stanowi znaczący plus w porównaniu z operatorem z Crunchy Data.

Ponieważ spośród 3 rozważanych opcji wybraliśmy rozwiązanie firmy Zalando, poniżej od razu przedstawimy dalszy opis jego możliwości wraz z praktyką stosowania.

Ćwicz z Operatorem Postgres od Zalando

Wdrożenie operatora jest bardzo proste: wystarczy pobrać najnowszą wersję z GitHub i zastosować pliki YAML z katalogu manifestuje się. Alternatywnie możesz również użyć centrum operatora.

Po instalacji należy zadbać o ustawienia przechowywanie logów i kopii zapasowych. Odbywa się to poprzez ConfigMap postgres-operator w przestrzeni nazw, w której ustawiasz operator. Po skonfigurowaniu repozytoriów możesz wdrożyć swój pierwszy klaster PostgreSQL.

Na przykład nasze standardowe wdrożenie wygląda następująco:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

Ten manifest wdraża klaster 3 wystąpień z wózkiem bocznym formularza postgres_exporter, z którego zbieramy metryki aplikacji. Jak widać, wszystko jest bardzo proste, a jeśli chcesz, możesz stworzyć dosłownie nieograniczoną liczbę klastrów.

Warto na to zwrócić uwagę panel WWW dla administratora - postgres-operator-UI. Jest dostarczany z operatorem i umożliwia tworzenie i usuwanie klastrów, a także pracę z kopiami zapasowymi tworzonymi przez operatora.

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie
Lista klastrów PostgreSQL

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie
Zarządzanie kopiami zapasowymi

Kolejną interesującą funkcją jest wsparcie Interfejs API zespołów. Mechanizm ten tworzy się automatycznie role w PostgreSQL, w oparciu o wynikową listę nazw użytkowników. Następnie API umożliwia zwrócenie listy użytkowników, dla których automatycznie tworzone są role.

Problemy i rozwiązania

Jednak użycie operatora wkrótce ujawniło kilka istotnych wad:

  1. brak obsługi nodeSelector;
  2. brak możliwości wyłączenia kopii zapasowych;
  3. podczas korzystania z funkcji tworzenia baz domyślne uprawnienia nie pojawiają się;
  4. okresowo nie ma wystarczającej ilości dokumentacji lub jest ona nieaktualna.

Na szczęście wiele z nich można rozwiązać. Zacznijmy od końca – problemy z dokumentacja.

Najprawdopodobniej spotkasz się z faktem, że nie zawsze jest jasne, jak zarejestrować kopię zapasową i jak podłączyć wiadro kopii zapasowej do interfejsu operatora. Jest to wspomniane mimochodem w dokumentacji, ale prawdziwy opis znajduje się w dokumencie PR:

  1. musisz zrobić sekret;
  2. przekazać go operatorowi jako parametr pod_environment_secret_name w CRD z ustawieniami operatora lub w ConfigMap (w zależności od sposobu instalacji operatora).

Jak się jednak okazało, na chwilę obecną nie jest to możliwe. Dlatego zebraliśmy Twoja wersja operatora z dodatkowymi rozwiązaniami stron trzecich. Więcej na ten temat – patrz poniżej.

Jeśli przekażesz operatorowi parametry w celu wykonania kopii zapasowej, a mianowicie - wal_s3_bucket i klucze dostępu w AWS S3, a następnie to wykona kopię zapasową wszystkiego: nie tylko bazy produkcyjne, ale także postojowe. Nam to nie odpowiadało.

W opisie parametrów do Spilo, czyli podstawowego wrappera Dockera dla PgSQL przy użyciu operatora, okazało się: można przekazać parametr WAL_S3_BUCKET pusty, wyłączając w ten sposób tworzenie kopii zapasowych. Co więcej, ku wielkiej radości, znalazłem gotowy PR, które natychmiast przyjęliśmy na nasz widelec. Teraz można to łatwo dodać enableWALArchiving: false do zasobu klastra PostgreSQL.

Tak, można było to zrobić inaczej, uruchamiając 2 operatorów: jednego do testowania (bez kopii zapasowych), drugiego do produkcji. Ale z jednym udało nam się obejść.

Ok, nauczyliśmy się jak przenieść dostęp dla S3 do baz danych i kopie zapasowe zaczęły trafiać do magazynu. Jak sprawić, by strony kopii zapasowych działały w interfejsie operatora?

Krótki przegląd instrukcji PostgreSQL dla Kubernetes, nasze wybory i doświadczenie

Będziesz musiał dodać 3 zmienne do interfejsu operatora:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Następnie udostępnione zostanie zarządzanie kopiami zapasowymi, co w naszym przypadku uprości pracę ze stagingiem, pozwalając na dostarczanie tam wycinków z produkcji bez dodatkowych skryptów.

Jako kolejny plus wymieniono pracę z Teams API oraz szerokie możliwości tworzenia baz danych i ról z wykorzystaniem narzędzi operatora. Jednak powstające role domyślnie nie mają uprawnień. W związku z tym użytkownik z uprawnieniami do odczytu nie mógł czytać nowych tabel.

Dlaczego? Chociaż w kodzie jest niezbędny GRANTnie zawsze są one stosowane. Istnieją 2 metody: syncPreparedDatabases и syncDatabases, syncPreparedDatabases - pomimo tego, że w pkt preparedDatabases jest jest warunek defaultRoles и defaultUsers do tworzenia ról, uprawnienia domyślne nie są stosowane. Jesteśmy w trakcie przygotowywania łatki, która umożliwi automatyczne zastosowanie tych praw.

I ostatni moment na istotne dla nas ulepszenia - łatkaA, który dodaje powinowactwo węzła do wygenerowanego zestawu stanowego. Nasi klienci często wolą ciąć koszty, korzystając z instancji spot, które zdecydowanie nie są warte hostingu usług bazodanowych. Ten problem można rozwiązać poprzez tolerancje, ale obecność powinowactwa węzłów daje większą pewność.

Co się stało?

W wyniku rozwiązania powyższych problemów rozwidliliśmy Operatora Postgres z Zalando Twoje repozytoriumdokąd to zmierza z tak przydatnymi poprawkami. A dla większej wygody zebraliśmy również Obraz Dockera.

Lista PR zaakceptowanych w forku:

Będzie wspaniale, jeśli społeczność wesprze te PR, aby mogły one dostać się do następnej wersji operatora (1.6).

Premia! Historia sukcesu migracji produkcyjnej

Jeśli korzystasz z Patroni, produkcję na żywo można przenieść do operatora przy minimalnym przestoju.

Spilo umożliwia tworzenie klastrów rezerwowych za pośrednictwem pamięci masowej S3 krajkakiedy dziennik binarny PgSQL jest najpierw przechowywany w S3, a następnie wypompowywany przez replikę. Ale co jeśli masz nie używane przez Wal-E w starej infrastrukturze? Rozwiązanie tego problemu już jest to zostało zasugerowane na koncentratorze.

Na ratunek przychodzi replikacja logiczna PostgreSQL. Nie będziemy jednak wdawać się w szczegóły, jak tworzyć publikacje i prenumeraty, bo… nasz plan się nie powiódł.

Faktem jest, że baza danych miała kilka załadowanych tabel z milionami wierszy, które ponadto były stale uzupełniane i usuwane. Prosta subskrypcja с copy_data, kiedy nowa replika kopiuje całą zawartość z wzorca, po prostu nie nadąża za wzorcem. Kopiowanie treści działało przez tydzień, ale nigdy nie dogoniło mistrza. Ostatecznie pomogło rozwiązać problem artykuł koledzy z Avito: możesz przesyłać dane za pomocą pg_dump. Opiszę naszą (nieco zmodyfikowaną) wersję tego algorytmu.

Pomysł jest taki, że możesz powiązać wyłączoną subskrypcję z konkretnym slotem replikacji, a następnie naprawić numer transakcji. Były repliki do prac produkcyjnych. Jest to ważne, ponieważ replika pomoże utworzyć spójny zrzut i będzie nadal otrzymywać zmiany od repliki głównej.

W kolejnych poleceniach opisujących proces migracji hosty będą miały następującą notację:

  1. mistrz — serwer źródłowy;
  2. replika1 - replika strumieniowa na starej produkcji;
  3. replika2 - nowa replika logiczna.

Plan migracji

1. Utwórz subskrypcję wszystkich tabel w schemacie w kreatorze public baza dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. Utwórz miejsce replikacji na urządzeniu głównym:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. Zatrzymaj replikację na starej replice:

psql -h replica1 -c "select pg_wal_replay_pause();"

4. Uzyskaj numer transakcji od mastera:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. Zrzut ze starej repliki. Zrobimy to w kilku wątkach, co pomoże przyspieszyć proces:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. Prześlij zrzut na nowy serwer:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. Po pobraniu zrzutu możesz rozpocząć replikację na replice strumieniowej:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. Utwórz subskrypcję na nowej replice logicznej:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. Zdobądź oid subskrypcje:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. Powiedzmy, że został odebrany oid=1000. Zastosujmy numer transakcji do subskrypcji:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10. Rozpocznijmy replikację:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. Sprawdź status subskrypcji, replikacja powinna działać:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. Po rozpoczęciu replikacji i zsynchronizowaniu baz danych można dokonać przełączenia.

13. Po wyłączeniu replikacji należy naprawić sekwencje. Jest dobrze opisane w artykule na wiki.postgresql.org.

Dzięki temu planowi przejście odbyło się z minimalnymi opóźnieniami.

wniosek

Operatory Kubernetes pozwalają uprościć różne działania, redukując je do tworzenia zasobów K8s. Osiągnąwszy jednak z ich pomocą niezwykłą automatyzację, warto pamiętać, że może ona przynieść także szereg nieoczekiwanych niuansów, dlatego mądrze wybieraj swoich operatorów.

Po przejrzeniu trzech najpopularniejszych operatorów Kubernetes dla PostgreSQL wybraliśmy projekt od Zalando. Musieliśmy pokonać z tym pewne trudności, ale wynik był naprawdę zadowalający, więc planujemy rozszerzyć to doświadczenie na inne instalacje PgSQL. Jeśli masz doświadczenie w korzystaniu z podobnych rozwiązań, chętnie poznamy szczegóły w komentarzach!

PS

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz