Postgres-wtorek nr 5: „PostgreSQL i Kubernetes. CI/CD. Automatyzacja testowania”

Postgres-wtorek nr 5: „PostgreSQL i Kubernetes. CI/CD. Automatyzacja testowania”

Pod koniec ubiegłego roku odbyła się kolejna transmisja na żywo rosyjskiego społeczności PostgreSQL #RuPostgres, podczas której współzałożyciel, Nikolaj Samochwałow, rozmawiał z dyrektorem technicznym „Flanta” Dmitrijem Stoliarowem o tej bazie danych w kontekście Kubernetes.

Publikujemy transkrypcję głównej części tej dyskusji, a na kanale YouTube społeczności opublikowana została pełna nagranie wideo:

Odtwarzaj wideo

Bazy danych i Kubernetes

NS: Dziś nie będziemy rozmawiać o VACUUM i CHECKPOINT’ach. Chcemy porozmawiać o Kubernetes. Wiem, że masz już wiele lat doświadczenia. Oglądałem twoje filmy, a niektóre nawet oglądałem fragmentami… Zacznijmy od razu: dlaczego w ogóle Postgres lub MySQL w K8s?

DS: Nie ma jednoznacznej odpowiedzi na to pytanie i nie może być. Ale generalnie chodzi o prostotę i wygodę… potencjalnie. Każdy chce przecież usług zarządzanych.

NS: Aby jak RDS, tylko u siebie?

DS: Tak: żeby jak RDS, tylko wszędzie.

NS: „Gdziekolwiek” — to dobre spostrzeżenie. W dużych firmach wszystko jest rozmieszczone w różnych miejscach. A dlaczego więc, jeśli to duża firma, nie skorzystać z gotowego rozwiązania? Na przykład Nutanix ma swoje opracowania, inne firmy (VMware…) mają to samo „RDS, tylko u siebie”.

DS: Ale mówimy o konkretnej realizacji, która będzie działać tylko w określonych warunkach. A jeśli mówimy o Kubernetes, to mamy do czynienia z ogromnym zróżnicowaniem infrastruktury (która może być w K8s). W zasadzie to standard dla API do chmury…

NS: I to jeszcze za darmo!

DS: To nie jest takie ważne. Darmowość ma znaczenie dla niewielkiego segmentu rynku. Ważne jest co innego… Pewnie przypominasz sobie moją prezentację „Bazy danych i Kubernetes»?

NS: Tak.

DS: Zrozumiałem, że została ona odebrana bardzo różnie. Część ludzi pomyślała, że mówię: „Ludzie, jedźmy ze wszystkimi bazami danych w Kubernetes!”, a inni uznali, że to wszystko straszne rowery. A ja chciałem powiedzieć zupełnie co innego: „Zobaczcie, co się dzieje, jakie są problemy i jak można je rozwiązać. Czy teraz warto wprowadzać bazy danych do Kubernetes? W produkcji? No, tylko jeśli lubicie… zajmować się pewnymi sprawami. Ale w przypadku rozwoju mogę powiedzieć, że polecam. Dla rozwoju bardzo ważna jest dynamika tworzenia/usuwania środowisk”.

NS: Mówisz o wszystkich środowiskach, które nie są produkcyjne? Staging, QA…

DS: Jeśli mówimy o perf-standach, to chyba nie, bo wymagania są specyficzne. Jeśli mówimy o szczególnych przypadkach, gdzie na staging potrzebna jest bardzo duża baza danych, to też raczej nie... Jeśli to statyczne środowisko, które ma długą żywotność, to jaka korzyść z tego, że baza znajduje się w K8s?

NS: Żadna. Ale gdzie widzimy statyczne środowiska? Statyczne środowisko będzie już nieaktualne jutro.

DS: Staging może być statyczny. Mamy klientów…

NS: Tak, ja też mam. To duży problem, jeśli masz bazę o pojemności 10 TB, a staging — 200 GB…

DS: Mam bardzo fajny przypadek! Na staging znajduje się baza produkcyjna, w którą wprowadzane są zmiany. I jest przewidziany przycisk: „wdrożyć do produkcji”. Te zmiany — delty — są wgrane (chyba po API synchronizowane) do produkcji. To bardzo egzotyczna opcja.

NS: Widziałem startupy w Dolinie, które korzystają z RDS-a lub nawet Heroku jeszcze — to historie sprzed 2-3 lat — i pobierają dump na swoje laptopy. Bo baza ma tylko 80 GB, a na laptopie jest miejsce. Potem kupują dyski dla każdego, aby mieć po 3 bazy do różnych prac rozwojowych. Taki przypadek też się zdarza. Widziałem również, że nie boją się kopiować produkcji na staging — to bardzo zależy od firmy. Ale widziałem także, że boją się tego i że często brakuje czasu i rąk. Ale zanim przejdziemy do tego tematu, chciałbym usłyszeć o Kubernetesie. Dobrze rozumiem, że w produkcji jeszcze nikt tego nie ma?

DS: Mamy małe bazy w produkcji. Mowa o pojemnościach sięgających dziesiątek gigabajtów i niekrytycznych usługach, dla których nie było sensu robić replik (nie było też takiej potrzeby). I pod warunkiem, że pod Kubernetesem jest odpowiednie przechowywanie. Ta baza działała na maszynie wirtualnej — powiedzmy w VMware, ponad SAN. Umieściliśmy ją w PV i teraz możemy przenosić ją z maszyny na maszynę.

NS: Bazy o takiej wielkości, do 100 GB, na dobrych dyskach i przy dobrej sieci można rozgrzać w kilka minut, prawda? Prędkość 1 GB na sekundę — to już nie jest egzotyka.

DS: Tak, dla liniowej operacji to nie problem.

NS: OK, o produkcji musimy tylko myśleć. A jeśli rozważamy Kubernetes dla środowisk nieprodukcyjnych — jak to robić? Widzę, że w Zalando tworzą operatora, w Crunchy tworzą, są jeszcze jakieś inne opcje. I jest OnGres — to nasz dobry znajomy Alvaro z Hiszpanii: oni robią właściwie nie tylko operatora, ale cały dystrybucyjny zestaw (StackGres), w którym poza samym Postgres'em postanowiono również umieścić kopię zapasową, proxy Envoy...

DS: Envoy do czego? Do równoważenia ruchu Postgresa?

NS: Tak. To znaczy, widzą to tak: jeśli weźmiemy dystrybucję Linuksa i jądro, to zwykły PostgreSQL to jądro, a oni chcą stworzyć dystrybucję, która będzie przyjazna dla chmur i działała w Kubernetes. Łączą komponenty (kopie zapasowe itp.) i optymalizują, aby działały dobrze.

DS: Bardzo fajnie! W zasadzie to oprogramowanie, aby stworzyć własny zarządzany Postgres.

NS: Z dystrybucjami Linuksa zawsze są problemy: jak robić sterowniki, aby wspierały cały sprzęt. A ich pomysł polega na tym, że będą działać w Kubernetes. Wiem, że w operatorze Zalando niedawno widzieliśmy powiązanie z AWS i to już nie jest najlepsze. Nie powinno być związania z konkretną infrastrukturą — jaki w tym sens?

DS: Nie wiem, w jakiej sytuacji konkretnie Zalando się związało, ale w Kubernetes teraz storage zrobione jest tak, że nie można w sposób ogólny wykonać kopii zapasowej dysku. Niedawno w standardzie — w ostatniej wersji specyfikacji CSI — wprowadzono możliwość zrzutów, ale gdzie to jest wdrożone? Szczerze, wciąż jest to tak niegotowe… Próbujemy CSI na AWS, GCE, Azure, vSphere, ale jak tylko zaczynasz używać, widać, że to jeszcze nie jest gotowe.

NS: Dlatego czasami trzeba się wiązać z infrastrukturą. Myślę, że to nadal wczesny etap — problemy z wzrostem. Pytanie: co byś doradził nowicjuszom, którzy chcą spróbować PgSQL w K8s? Jaki operator, może?

DS: Problem polega na tym, że Postgres to dla nas 3%. Mamy też bardzo długą listę różnych programów w Kubernetes, nawet nie będę wszystkiego wymieniać. Na przykład Elasticsearch. Operatorów jest mnóstwo: niektóre rozwijają się intensywnie, inne — nie. Dla siebie ustaliliśmy wymagania, co powinno być w operatorze, żebyśmy traktowali go poważnie. Operator jest właśnie dla Kubernetes — a nie w „operatorze, żeby robić coś w warunkach Amazona”… W praktyce dość powszechnie (= prawie wszyscy klienci) używamy jednego operatora — dla Redis (wkrótce opublikujemy o nim artykuł).

NS: A dla MySQL też nie ma? Wiem, że Percona… ponieważ teraz zajmują się zarówno MySQL, jak i MongoDB, i Postgres, muszą stworzyć jakiś uniwersalny: dla wszystkich baz, dla wszystkich dostawców chmurowych.

DS: Nie zdążyliśmy przyjrzeć się operatorom dla MySQL. Nie jest to nasz główny fokus. MySQL działa dobrze w trybie standalone. Po co operator, skoro można po prostu uruchomić bazę danych... Można uruchomić kontener Docker z Postrges, albo można to zrobić w prostszy sposób.

NS: Był również taki temat. Całkowicie bez operatora?

DS: Tak, w 100% mamy PostgreSQL uruchomiony bez operatora. Na razie tak jest. Aktywnie używamy operatora dla Prometheus i Redis. Planujemy znaleźć operatora dla Elasticsearch — to jest najbardziej „palące”, ponieważ chcemy go wdrożyć w Kubernetes w 100% przypadków. Podobnie jak chcemy, aby MongoDB zawsze było uruchamiane w Kubernetes. Pojawiają się pewne wymagania — czujemy, że w takich przypadkach można coś zrobić. A do Postgresa nawet nie spojrzeliśmy. Oczywiście, wiemy o istnieniu różnych opcji, ale faktycznie mamy standalone.

Baza danych do testów w Kubernetes

NS: Przejdźmy do tematu testowania. Jak wdrażać zmiany w bazie — z punktu widzenia perspektywy DevOps. Są mikroserwisy, wiele baz, cały czas coś się zmienia. Jak zapewnić normalne CI/CD, żeby z perspektywy DB wszystko było w porządku. Jakie jest Twoje podejście?

DS: Nie ma jednej odpowiedzi. Jest kilka parametrów. Pierwszy to rozmiar bazy, którą chcemy wdrożyć. Sam wspomniałeś, że w firmach różnie podchodzą do konieczności posiadania kopii prod-bazy w dev i stage.

NS: A w warunkach GDPR, myślę, że podchodzą do tego coraz bardziej ostrożnie... Mogę powiedzieć, że w Europie już zaczęli nakładać kary.

DS: Ale często można napisać oprogramowanie, które robi zrzuty z produkcji i je obfuskować. Powstają dane produkcyjne (snapshot, dump, kopia binarna...), ale są one anonimizowane. Zamiast tego mogą być skrypty generujące: mogą to być fixture lub po prostu skrypt, który generuje dużą bazę. Jakie jest pytanie: ile czasu zajmuje stworzenie bazowego obrazu? I ile czasu zajmuje jego wdrożenie w odpowiednim środowisku?

Doszliśmy do schematu: jeśli klient ma zbiór danych oak-instancjonowanych (minimalna wersja bazy), to domyślnie je wykorzystujemy. Jeśli mówimy o środowiskach review, kiedy stworzyliśmy branch, uruchamiamy instancję aplikacji — wdrażamy tam małą bazę. Ale to też wyszło dobrze. wariant, kiedy z produkcji raz na dobę (w nocy) tworzymy zrzut i na jego podstawie tworzymy kontener Docker z PostgreSQL i MySQL z tymi załadowanymi danymi. Jeśli z tego obrazu trzeba rozwinąć bazę 50 razy, to odbywa się to dość prosto i szybko.

NS: Prosto przez skopiowanie?

DS: Dane są przechowywane bezpośrednio w obrazie Docker. Tzn. mamy gotowy obraz, powiedzmy 100 GB. Dzięki warstwom w Docker możemy szybko rozwijać ten obraz potrzebną ilość razy. Metoda prosta, ale działa całkiem nieźle.

NS: Następnie, kiedy testujesz, zmienia się to bezpośrednio wewnątrz Docker’a, tak? Copy-on-write wewnątrz Docker’a — wyrzucamy i wracamy, wszystko dobrze. Super! I już do tego w pełni się przyzwyczailiście?

DS: Od dawna.

NS: Zajmujemy się podobnymi rzeczami. Tylko nie używamy Docker’owego copy-on-write, lecz coś innego.

DS: To nie jest ogólne. A Docker’owy działa wszędzie.

NS: Teoretycznie tak. Ale mamy też moduły, można tworzyć różne moduły i pracować z różnymi systemami plików. Jest tutaj jeden moment. Z perspektywy Postgresa patrzymy na to zupełnie inaczej. Teraz spojrzałem z perspektywy Docker’a i widzę, że wszystko u Was działa. Ale jeśli baza jest ogromna, na przykład 1 TB, to już wszystko trwa długo: zarówno operacje nocne, jak i pakowanie wszystkiego do Docker… A jeśli 5 TB wkładać do Docker… Czy wszystko w porządku?

DS: Jaka różnica: to są tylko blob'y, po prostu bity i bajty.

NS: Różnica jest taka: robicie to przez dump i restore?

DS: Wcale nie musi być. Sposoby generowania tego obrazu mogą być różne.

NS: Dla niektórych klientów zrobiliśmy tak, że zamiast regularnego generowania bazowego obrazu, stale go utrzymujemy w aktualnym stanie. W zasadzie jest repliką, ale dane nie pochodzą bezpośrednio z mastera, lecz poprzez archiwum. Binarne archiwum, do którego każda doba nakłada WAL… Te WAL później docierają — z niewielkim opóźnieniem (dosłownie 1-2 sekundy) — do bazowego obrazu. Z niego klonujemy w dowolny sposób — obecnie domyślnie używamy ZFS.

DS: Ale z ZFS jesteś ograniczony do jednego węzła.

NS: Tak. Ale ZFS ma jeszcze magiczny send: z nim można wysłać migawkę i nawet (jeszcze tego nie testowałem, ale…) można przesyłać różnice między dwoma PGDATA. Tak naprawdę mamy jeszcze jedno narzędzie, które niezbyt dokładnie rozważaliśmy do takich zadań. W PostgreSQL jest pg_rewind, działający jak «inteligentny» rsync, pomijający wiele rzeczy, na które nie trzeba zwracać uwagi, ponieważ nic się nie zmieniło. Możemy szybko zsynchronizować między dwoma serwerami i cofnąć się dokładnie tak samo.

Więc staramy się z tej bardziej DBA'owej strony stworzyć narzędzie, które pozwala zrobić to samo, o czym mówisz: mamy jedną bazę, ale chcemy przetestować coś 50 razy, niemal równocześnie.

DS: 50 razy oznacza, że musisz zamówić 50 instancji Spot.

NS: Nie, robimy to na jednej maszynie.

DS: Ale jak uruchomisz 50 razy, jeśli ta jedna baza ma na przykład terabajt? Prawdopodobnie potrzebuje około 256 GB RAM?

NS: Tak, czasami pamięci potrzeba dużo — to normalne. Ale taki przykład z życia. Na maszynie produkcyjnej 96 rdzeni i 600 GB. W przypadku bazy danych używane jest 32 rdzenie (nawet 16 rdzeni teraz czasami) i pamięć 100-120 GB.

DS: I wchodzi tam 50 kopii?

NS: A kopia jest tylko jedna, dalej działa copy-on-write (ZFS)... Opowiem więcej.

U nas, na przykład, baza ma 10 TB. Zrobiliśmy dysk dla niej, ZFS jeszcze zmniejszył jej rozmiar o 30-40%. Ponieważ nie przeprowadzamy testów obciążeniowych, nie zależy nam na dokładnym czasie odpowiedzi: może być do 2 razy wolniej — to w porządku.

Dajemy programistom, QA, DBA itd. możliwość przeprowadzania testów w 1-2 wątkach. Na przykład mogą uruchomić jakąś migrację. Nie wymaga od razu 10 rdzeni — potrzebny jest jeden backend Postgres'a, 1 rdzeń. Migracja się uruchomi — może, autovacuum jeszcze się uruchomi, wtedy zaangażowane zostanie drugie rdzeń. Mamy przydzielone 16-32 rdzenie, więc 10 osób może pracować jednocześnie, nie ma żadnych problemów.

Ponieważ fizycznie PGDATA są identyczne, okazuje się, że oszukujemy Postgres w rzeczywistości. W czym tkwi problem: uruchamia się na przykład 10 Postgresów jednocześnie. Jaka jest zazwyczaj problem? Ustawiają shared_buffers, powiedzmy, na 25%. Odpowiednio, to 200 GB. Więcej niż trzy takie już nie uruchomisz, bo pamięć się skończy.

Ale w pewnym momencie zrozumieliśmy, że to nie jest konieczne: ustawiamy shared_buffers na 2 GB. PostgreSQL ma effective_cache_size, i w rzeczywistości tylko on wpływa na plany. To ustawiamy na 0,5 TB. I nawet nie ważne, że ich w rzeczywistości nie ma: buduje plany, jakby one były.

W związku z tym, gdy testujemy jakąś migrację, można zebrać wszystkie plany — zobaczymy, jak to będzie wyglądać na produkcji. Czas w tym przypadku będzie inny (wolniejszy), ale dane, które naprawdę odczytujemy, oraz same plany (jakie są tam JOINy itp.) są dokładnie takie same jak na produkcji. Równocześnie można uruchomić wiele takich sprawdzeń na jednej maszynie.

DS: Nie uważasz, że są tutaj pewne problemy? Po pierwsze, to rozwiązanie, które działa tylko na PostgreSQL. Takie podejście jest bardzo specyficzne, nie jest ogólne. Po drugie, Kubernetes (i wszystko, w co obecnie zmierzają technologie chmurowe) zakłada wiele węzłów, a te węzły są efemeryczne. A w twoim przypadku to jest stateful, trwały węzeł. Te rzeczy budzą moje wątpliwości.

NS: Po pierwsze, zgadzam się, to czysto historia Postgresowa. Myślę, że jeśli mamy jakiś direct IO i bufor pamięci prawie pod całą pamięć, takie podejście nie zadziała — plany będą inne. Ale na razie pracujemy tylko z Postgres, nie myślimy o innych.

O Kubernetes. Sam przecież wszędzie mówisz, że nasza baza jest trwała. Jeśli instancja upadnie, najważniejsze jest, aby zachować dysk. Nasza cała platforma jest też w Kubernetes, a komponent z Postgres jest osobno (chociaż i on tam kiedyś będzie). Dlatego to tak: instancja upadła, ale zachowaliśmy jej PV i po prostu podłączyliśmy do innej (nowej) instancji, jakby nic się nie stało.

DS: Z mojego punktu widzenia tworzymy pod'y w Kubernetes. K8s jest elastyczny: węzły są zamawiane same w miarę potrzeby. Zadanie polega po prostu na stworzeniu poda i powiedzeniu, że potrzebuje X zasobów, a potem K8s sam sobie z tym poradzi. Ale wsparcie dla pamięci masowej w Kubernetes wciąż jest niestabilne: w 1.16, w 1.17 (ta wydania wyszła tygodnie temu) te funkcje stają się dopiero beta.

Minie pół roku, rok — stanie się to mniej więcej stabilne, lub przynajmniej będzie to ogłoszone. Wtedy możliwość robienia zrzutów i zmiany rozmiaru rozwiązuje całkowicie wasz problem. Ponieważ macie bazę. Tak, ona może nie być bardzo szybka, ale prędkość zależy od tego, co jest „pod maską”, ponieważ niektóre implementacje potrafią wykonywać kopiowanie i copy-on-write na poziomie systemu dyskowego.

NS: Tu trzeba jeszcze, aby wszystkie silniki (Amazon, Google…) zdążyły zacząć wspierać tę wersję — to też zajmuje czas.

DS: Na razie ich nie używamy. Używamy swojego.

Lokalny rozwój pod Kubernetes

NS: Czy zdarzyło Ci się mieć taką potrzebę, aby uruchomić wszystkie pod’y na jednej maszynie i przeprowadzić małe testy? Aby szybko uzyskać dowód koncepcji i sprawdzić, czy aplikacja działa w Kubernetes, nie wydając na to wielu maszyn. Jest Minikube, prawda?

DS: Wydaje mi się, że ten przypadek — uruchomienie na jednym węźle — dotyczy wyłącznie lokalnego rozwoju. Albo jakichś przejawów tego wzorca. Jest Minikube, jest k3s, KIND. Zbliżamy się do tego, aby używać Kubernetes IN Docker. Już zaczęliśmy nad tym pracować do testów.

NS: Kiedyś myślałem, że to próba spakowania wszystkich pod’ów w jeden obraz Docker. Ale okazało się, że to zupełnie coś innego. I tak mamy oddzielne kontenery, oddzielne pod’y — po prostu w Dockerze.

DS: Tak. I jest tam całkiem zabawna imitacja, ale sens jest taki… Mamy narzędzie do wdrażania — werf. Chcemy w nim dodać tryb — nazwijmy go werf up: „Uruchom mi lokalny Kubernetes”. A następnie uruchomić tam warunkowy werf follow. Wtedy programista będzie mógł edytować w IDE, a w systemie będzie uruchomiony proces, który widzi zmiany i przebudowuje obrazy, wdraża je w lokalnym K8s. W ten sposób chcemy spróbować rozwiązać problem lokalnego rozwoju.

Migawki i klonowanie baz danych w realiach K8s

NS: Jeśli wrócić do copy-on-write. Zauważyłem, że chmury również mają migawki. Działają różnie. Na przykład w GCP: masz na wschodnim wybrzeżu USA wieloterao­bytowy instanc. Robisz okresowo migawki. Podnosisz z migawki kopię dysku na zachodnim wybrzeżu — w ciągu kilku minut wszystko jest gotowe, działa bardzo szybko, tylko pamięć podręczna musi być wypełniona w pamięci. Ale te klony (migawki) — służą do 'provision’owania' nowego woluminu. To świetne, gdy potrzebujesz stworzyć wiele instancji.

A jeśli chodzi o testy, wydaje mi się, że migawki, o których mówisz w Dockerze, lub ja mówię w ZFS, btrfs, a nawet LVM… — one pozwalają nie tworzyć na jednej maszynie nowych danych. W chmurze musisz za nie płacić za każdym razem i trzeba czekać nie sekundy, a minuty (a w przypadku lazy load’a, być może, i godzin).

Zamiast tego możesz uzyskać te dane w sekundę lub dwie, uruchomić test i wyrzucić. Te migawki rozwiązują różne zadania. W pierwszym przypadku — aby się skalować i zyskać nowe repliki, a w drugim — do testów.

DS: Nie zgadzam się. Prawidłowe klonowanie woluminów to zadanie dla chmury. Nie oglądałem ich implementacji, ale wiem, jak to robimy na sprzęcie. Mamy Ceph, w którym można każdemu fizycznemu woluminowi (RBD) powiedzieć clone i otrzymać w ciągu kilku milisekund drugi wolumin o takich samych parametrach, IOPSi tym podobne. Trzeba zrozumieć, że tam wewnątrz jest sprytne copy-on-write. Dlaczego chmura nie ma robić tego samego? Jestem pewien, że w takim czy innym zakresie starają się to zrealizować.

NS: Ale i tak będą potrzebować sekund, dziesiątków sekund, żeby uruchomić instancję, wprowadzić Dockera itp.

DS: Dlaczego trzeba koniecznie uruchamiać całą instancję? Mamy przecież instancję na 32 rdzenie, na 16… i mieści się w niej pewna liczba — na przykład cztery. Kiedy zamawiamy piątą, już zostanie uruchomiona instancja, a potem zostanie usunięta.

NS: Tak, interesujące, w Kubernetes wychodzi inaczej. Nasza baza danych nie jest w K8s i to jedna instancja. Ale na sklonowanie wielotera bitej bazy danych zajmuje nie więcej niż dwie sekundy.

DS: To świetnie. Ale mój pierwotny pomysł to, że to nie jest rozwiązanie ogólne. Tak, jest fajne, ale nadaje się tylko dla Postgres i tylko na jednym węźle.

NS: Nadaje się nie tylko dla Postgres: to plany, jak opisałem, będą tak działać tylko w nim. Ale jeśli nie przejmować się planami, a potrzebujemy tylko wszystkich danych do testowania funkcjonalnego, to wtedy nadaje się do każdej bazy danych.

DS: Wiele lat temu robiliśmy coś podobnego na zrzutach LVM. To klasyka. Tego typu podejście było bardzo aktywnie stosowane. Po prostu stateful-węzły to ból. Ponieważ trzeba o nich pamiętać, nie mogą się wyłączać...

NS: Czy nie widzisz tutaj jakiejś możliwości hybrydy? Powiedzmy, że stateful to jakiś pod, działa na kilku ludziach (wielu testerów). Wolumin mamy jeden, ale dzięki systemowi plików klony są lokalne. Jeśli pod upadnie, dysk zostanie — podniesiemy pod, odczyta informacje o wszystkich klonach, wszystko podniesie z powrotem i powie: „Oto wasze klony uruchomione na tych portach, pracujcie z nimi dalej”.

DS: Technicznie oznacza to, że w ramach Kubernetes to jeden pod, w którym uruchamiamy wiele Postgresów.

NS: Tak. Ma ograniczenie: powiedzmy, że jednocześnie pracuje z nim nie więcej niż 10 osób. Jeśli potrzebujemy 20 — uruchomimy drugi taki pod. Całkowicie realistycznie sklonujemy go, otrzymując drugi pełny wolumin, na którym będą takie same 10 „cienkich” klonów. Nie widzisz takiej możliwości?

DS: Musimy dodać pytania dotyczące bezpieczeństwa. Taki sposób organizacji zakłada, że ten pod ma wysokie uprawnienia (capabilities), ponieważ może przeprowadzać niestandardowe operacje na systemie plików... Ale powtarzam: uważam, że w średnioterminowej perspektywie w Kubernetes naprawią przechowywanie, w chmurach naprawią całą historię z wolumenami — wszystko będzie „po prostu działać”. Będzie resize, klonowanie... Jest wolumen — mówimy: „Stwórz nowy na podstawie tego”, a po półtorej sekundy otrzymujemy to, czego potrzebujemy.

NS: Nie wierzę w półtorej sekundy dla wielu terabajtów. W Ceph robisz to sam, a mówisz o chmurach. Idź do chmury, na EC2 sklonuj wolumen EBS wielu terabajtów i zobacz, jaka będzie wydajność. To nie potrwa kilku sekund. Bardzo mnie ciekawi, kiedy osiągną taki wskaźnik. Rozumiem, o czym mówisz, ale pozwolę sobie się nie zgodzić.

DS: Ok, ale powiedziałem, że w średnioterminowej perspektywie, nie krótkoterminowej. W ciągu kilku lat.

O operatorze dla PostgreSQL od Zalando

W połowie tego spotkania dołączył do niej również Aleksiej Kliukin, były programista z firmy Zalando, który opowiedział o historii operatora PostgreSQL:

Świetnie, że w ogóle poruszono ten temat: zarówno Postgres, jak i Kubernetes. Kiedy zaczynaliśmy go robić w Zalando w 2017 roku, to był temat, którym wszyscy chcieli się zająć, ale nikt go nie realizował. Wszyscy już mieli Kubernetes, ale kiedy pytano, jak być z bazami danych, nawet tacy ludzie jak Kelsey Hightower, głoszący K8s, mówili mniej więcej tak:

„Idźcie w managed-services i korzystajcie z nich, nie uruchamiajcie DB w Kubernetes. W przeciwnym razie wasz K8s postanowi, na przykład, przeprowadzić aktualizację, wyłączy wszystkie węzły, a wasze dane odlecą bardzo daleko.”

Postanowiliśmy stworzyć operatora, który, wbrew tej radzie, uruchomi bazę danych Postgres w Kubernetes. I mieliśmy dobre podstawy — Patroni. To automatyczny failover dla PostgreSQL, zrobiony poprawnie, tj. wykorzystujący etcd, consul lub ZooKeeper jako magazyn informacji o klastrze. Tego rodzaju magazyn, który będzie podawać wszystkim, którzy pytają, na przykład, kto jest obecnie liderem, tę samą informację — pomimo że mamy wszystko rozproszone — aby nie było split brain’a. Poza tym mieliśmy obraz Dockera dla niego.

W rzeczywistości potrzeba auto failover w firmie pojawiła się po migracji z wewnętrznego centrum danych do chmury. Chmura opierała się na własnym rozwiązaniu PaaS (Platform-as-a-Service). Była to platforma Open Source, ale aby ją uruchomić, trzeba było się naprawdę nagimnastykować. Nazywała się STUPS.

Początkowo nie było żadnego Kubernetes. A dokładniej, kiedy uruchamiano własne rozwiązanie, K8s już istniał, ale był tak niedopracowany, że nie nadawał się do produkcji. To był, moim zdaniem, 2015 lub 2016 rok. Do 2017 roku Kubernetes stał się bardziej stabilny – pojawiła się konieczność migracji tam.

I mieliśmy już kontener Docker. Istniała PaaS, która korzystała z Dockera. Dlaczego nie spróbować K8s? Czemu nie napisać własnego operatora? Murat Kabilov, który do nas przyszedł z Avito, zaczął to jako projekt z własnej inicjatywy – «pobawić się» – i projekt «wystartował».

Ale w ogóle chciałem opowiedzieć o AWS. Dlaczego tam historycznie był kod związany z AWS…

Kiedy uruchamiasz cokolwiek w Kubernetes, musisz zrozumieć, że K8s to tak naprawdę work in progress. On ciągle się rozwija, poprawia i czasami nawet psuje. Należy uważnie śledzić wszystkie zmiany w Kubernetesie, być gotowym w razie potrzeby zagłębić się w to i poznać, jak to działa w szczegółach – być może bardziej, niż byś chciał. To dotyczy każdej platformy, na której uruchamiasz swoje bazy danych…

Zatem, kiedy tworzyliśmy operatora, mieliśmy Postgresa, który działał z zewnętrznym woluminem (w tym przypadku EBS, ponieważ pracowaliśmy w AWS). Baza danych rosła, w pewnym momencie trzeba było zrobić resize: na przykład początkowy rozmiar EBS wynosił 100 TB, baza osiągnęła ten rozmiar i teraz chcemy zwiększyć EBS do 200 TB. Jak? Załóżmy, że można zrobić zrzut/odtworzenie na nowym instancie, ale to zajmuje dużo czasu i wiąże się z przestojem.

Dlatego chcieliśmy przeprowadzić resize, który zwiększyłby partycję EBS i następnie powiedzieć systemowi plików, aby skorzystał z nowej przestrzeni. I zrealizowaliśmy to, ale w tamtym czasie Kubernetes nie miał żadnego API do operacji resize. Ponieważ pracowaliśmy na AWS, napisaliśmy kod dla jego API.

Nikt nie przeszkadza, aby zrobić to samo dla innych platform. W operatorze nie ma powiązania, że można go uruchomić tylko na AWS, a na wszystkim innym nie będzie działał. Ogólnie rzecz biorąc, to projekt Open Source: jeśli ktokolwiek chce przyspieszyć wdrożenie nowego API – zapraszam. GitHub,pull-requesty — zespół Zalando stara się na nie dość szybko reagować i promować operatora. Z tego co wiem, projekt brał udział w Google Summer of Code oraz innych podobnych inicjatywach. Zalando bardzo aktywnie nad nim pracuje.

P.S. Bonus!

Jeśli interesuje Was temat PostgreSQL i Kubernetes, zwracamy również uwagę, że w zeszłym tygodniu odbył się kolejny Postgres-wtorek, gdzie z Nikołajem rozmawiał Aleksander Kukuśkin z Zalando. Wideo z tego jest dostępne tutaj.

P.P.S.

Przeczytaj także na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster