{"id":55467,"date":"2020-01-21T00:00:00","date_gmt":"2020-01-20T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya"},"modified":"2020-02-18T14:03:35","modified_gmt":"2020-02-18T11:03:35","slug":"postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","title":{"rendered":"Postgres-wtorek nr 5: \u201ePostgreSQL i Kubernetes. CI\/CD. Automatyzacja testowania\u201d","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Postgres-wtorek nr 5: \u201ePostgreSQL i Kubernetes. CI\/CD. Automatyzacja testowania\u201d\" src=\"\/wp-content\/uploads\/2020\/01\/5eb8dd2afa4cab58a7359b305814d77f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPod koniec ubieg\u0142ego roku odby\u0142a si\u0119 kolejna transmisja na \u017cywo rosyjskiego spo\u0142eczno\u015bci PostgreSQL <noindex><a rel=\"nofollow\" href=\"https:\/\/www.meetup.com\/postgresqlrussia\/\">#RuPostgres<\/a><\/noindex>, podczas kt\u00f3rej wsp\u00f3\u0142za\u0142o\u017cyciel, Nikolaj Samochwa\u0142ow, rozmawia\u0142 z dyrektorem technicznym \u201eFlanta\u201d Dmitrijem Stoliarowem o tej bazie danych w kontek\u015bcie Kubernetes.<\/p>\n<p>Publikujemy transkrypcj\u0119 g\u0142\u00f3wnej cz\u0119\u015bci tej dyskusji, a na <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/channel\/UC0SBGSNmBLrTZIkbN-lJHnw\">kanale YouTube spo\u0142eczno\u015bci<\/a><\/noindex> opublikowana zosta\u0142a pe\u0142na nagranie wideo:<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"qXc9VTr4TFc\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/qXc9VTr4TFc\/hqdefault.jpg\" alt=\"Odtwarzaj wideo\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<h2>Bazy danych i Kubernetes<\/h2>\n<p>\n<i><b>NS<\/b>: Nie b\u0119dziemy dzisiaj rozmawia\u0107 o VACUUM i CHECKPOINTach. Chcemy porozmawia\u0107 o Kubernetes. Wiem, \u017ce masz ju\u017c wiele lat do\u015bwiadczenia. Ogl\u0105da\u0142em twoje filmy i niekt\u00f3re nawet przegl\u0105da\u0142em w kawa\u0142kach\u2026 Zr\u00f3bmy to od razu: po co w og\u00f3le Postgres lub MySQL w K8s?<\/i><\/p>\n<p><b>DS<\/b>: Nie ma jednoznacznej odpowiedzi na to pytanie i nie mo\u017ce by\u0107. Ale generalnie chodzi o prostot\u0119 i wygod\u0119\u2026 potencjalnie. Ka\u017cdy chce przecie\u017c us\u0142ug zarz\u0105dzanych.<\/p>\n<p><i><b>NS<\/b>: Aby jak <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/rds\/\">RDS<\/a><\/noindex>, tylko u siebie?<\/i><\/p>\n<p><b>DS<\/b>: Tak: \u017ceby jak RDS, tylko wsz\u0119dzie.<\/p>\n<p><i><b>NS<\/b>: \u201eGdziekolwiek\u201d \u2014 to dobre spostrze\u017cenie. W du\u017cych firmach wszystko jest rozmieszczone w r\u00f3\u017cnych miejscach. A dlaczego wi\u0119c, je\u015bli to du\u017ca firma, nie skorzysta\u0107 z gotowego rozwi\u0105zania? Na przyk\u0142ad Nutanix ma swoje opracowania, inne firmy (VMware\u2026) maj\u0105 to samo \u201eRDS, tylko u siebie\u201d.<\/i><\/p>\n<p><b>DS<\/b>: Ale m\u00f3wimy o konkretnej realizacji, kt\u00f3ra b\u0119dzie dzia\u0142a\u0107 tylko w okre\u015blonych warunkach. A je\u015bli m\u00f3wimy o Kubernetes, to mamy do czynienia z ogromnym zr\u00f3\u017cnicowaniem infrastruktury (kt\u00f3ra mo\u017ce by\u0107 w K8s). W zasadzie to standard dla API do chmury\u2026<\/p>\n<p><i><b>NS<\/b>: I to jeszcze za darmo!<\/i><\/p>\n<p><b>DS<\/b>: To nie jest takie wa\u017cne. Darmowo\u015b\u0107 ma znaczenie dla niewielkiego segmentu rynku. Wa\u017cne jest co innego\u2026 Pewnie przypominasz sobie moj\u0105 prezentacj\u0119 \u201e<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Bazy danych i Kubernetes<\/a><\/noindex>\u00bb?<\/p>\n<p><i><b>NS<\/b>: Tak.<\/i><\/p>\n<p><b>DS<\/b>: Zrozumia\u0142em, \u017ce zosta\u0142o to odebrane bardzo r\u00f3\u017cnorodnie. Cz\u0119\u015b\u0107 ludzi pomy\u015bla\u0142a, \u017ce m\u00f3wi\u0119: \u201eDobra, jed\u017amy z wszystkim DB w Kubernetes!\u201d, a inni uznali, \u017ce to wszystko s\u0105 straszne rowery. A ja chcia\u0142em powiedzie\u0107 ca\u0142kiem co\u015b innego: \u201ePatrzcie, co si\u0119 dzieje, jakie s\u0105 problemy i jak mo\u017cna je rozwi\u0105za\u0107. Czy trzeba uruchamia\u0107 bazy w Kubernetes? Produkcja? No, tylko je\u015bli lubisz\u2026 zajmowa\u0107 si\u0119 pewnymi rzeczami. A dla dev'a \u2014 mog\u0119 powiedzie\u0107, \u017ce polecam. Dla dev'a bardzo wa\u017cna jest dynamika tworzenia\/usuwania \u015brodowisk.<\/p>\n<p><i>NS: M\u00f3wisz o dev'ie, masz na my\u015bli wszystkie \u015brodowiska, kt\u00f3re nie s\u0105 prod? Staging, QA\u2026<\/i><\/p>\n<p><b>DS<\/b>: Je\u015bli m\u00f3wimy o perf-standach, to chyba nie, bo wymagania s\u0105 specyficzne. Je\u015bli m\u00f3wimy o szczeg\u00f3lnych przypadkach, gdzie na staging potrzebna jest bardzo du\u017ca baza danych, to te\u017c raczej nie... Je\u015bli to statyczne \u015brodowisko, kt\u00f3re ma d\u0142ug\u0105 \u017cywotno\u015b\u0107, to jaka korzy\u015b\u0107 z tego, \u017ce baza znajduje si\u0119 w K8s?<\/p>\n<p><i><b>NS<\/b>: \u017badna. Ale gdzie widzimy statyczne \u015brodowiska? Statyczne \u015brodowisko b\u0119dzie ju\u017c nieaktualne jutro.<\/i><\/p>\n<p><b>DS<\/b>: Staging mo\u017ce by\u0107 statyczny. Mamy klient\u00f3w\u2026<\/p>\n<p><i><b>NS<\/b>: Tak, ja te\u017c mam. To du\u017cy problem, je\u015bli masz baz\u0119 o pojemno\u015bci 10 TB, a staging \u2014 200 GB\u2026<\/i><\/p>\n<p><b>DS<\/b>: Mam bardzo fajny przypadek! Na staging znajduje si\u0119 baza produkcyjna, w kt\u00f3r\u0105 wprowadzane s\u0105 zmiany. I przewidziano przycisk: \u201ewykonaj w produkcji\u201d. Te zmiany \u2014 delty \u2014 s\u0105 zasilane (wydaje mi si\u0119, \u017ce po prostu synchronizowane przez API) do produkcji. To bardzo egzotyczna opcja.<\/p>\n<p><i><b>NS<\/b>: Widzia\u0142em startupy w Dolinie, kt\u00f3re siedz\u0105 w RDS lub nawet w Heroku jeszcze \u2014 to historie sprzed 2-3 lat \u2014 i \u015bci\u0105gaj\u0105 sobie dump na laptopa. Bo baza ma tylko 80 GB, a na laptopie jest miejsce. Potem kupuj\u0105 dyski dla ka\u017cdego, aby mie\u0107 po 3 bazy do r\u00f3\u017cnych prac rozwojowych. Tak te\u017c bywa. Widzia\u0142em r\u00f3wnie\u017c, \u017ce nie boj\u0105 si\u0119 kopiowa\u0107 prod do staging \u2014 to bardzo mocno zale\u017cy od firmy. Ale widzia\u0142em te\u017c, \u017ce boj\u0105 si\u0119 bardzo i cz\u0119sto brakuje czasu i r\u0105k. Ale zanim przejdziemy do tego tematu, chcia\u0142bym us\u0142ysze\u0107 o Kubernetes. Dobrze rozumiem, \u017ce w prodzie na razie nigdzie?<\/i><\/p>\n<p><b>DS<\/b>: Mamy ma\u0142e bazy w prodzie. Chodzi o wolumeny w dziesi\u0105tkach gigabajt\u00f3w i niekrytyczne serwisy, dla kt\u00f3rych nie chcia\u0142o si\u0119 robi\u0107 replik (i nie ma takiej potrzeby). I pod warunkiem, \u017ce pod Kubernetesem jest normalne przechowywanie. Ta baza pracowa\u0142a w maszynie wirtualnej \u2014 warunkowo w VMware, nad macierz\u0105 dyskow\u0105. Umie\u015bcili\u015bmy j\u0105 w <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\">PV<\/a><\/noindex> i teraz mo\u017cemy przenosi\u0107 j\u0105 z maszyny na maszyn\u0119.<\/p>\n<p><i><b>NS<\/b>: Bazy o takiej wielko\u015bci, do 100 GB, na dobrych dyskach i przy dobrej sieci mo\u017cna rozgrza\u0107 w kilka minut, prawda? Pr\u0119dko\u015b\u0107 1 GB na sekund\u0119 \u2014 to ju\u017c nie jest egzotyka.<\/i><\/p>\n<p><b>DS<\/b>: Tak, dla liniowej operacji to nie problem.<\/p>\n<p><i><b>NS<\/b>: OK, o produkcji musimy tylko my\u015ble\u0107. A je\u015bli rozwa\u017camy Kubernetes dla \u015brodowisk nieprodukcyjnych \u2014 jak to robi\u0107? Widz\u0119, \u017ce w Zalando <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">tworz\u0105 operatora<\/a><\/noindex>, w Crunchy <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\">tworz\u0105<\/a><\/noindex>, s\u0105 jeszcze jakie\u015b inne opcje. I jest <noindex><a rel=\"nofollow\" href=\"https:\/\/ongres.com\/\">OnGres<\/a><\/noindex> \u2014 to nasz dobry znajomy Alvaro z Hiszpanii: oni robi\u0105 w\u0142a\u015bciwie nie tylko <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/326414\/\">operatora<\/a><\/noindex>, ale ca\u0142y dystrybucyjny zestaw (<noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/ongresinc\/stackgres\">StackGres<\/a><\/noindex>), w kt\u00f3ry poza samym Postgres'em postanowili\u015bmy r\u00f3wnie\u017c wpisa\u0107 backup, proxy Envoy\u2026<\/i><\/p>\n<p><b>DS<\/b>: Envoy do czego? Do r\u00f3wnowa\u017cenia ruchu Postgresa?<\/p>\n<p><i><b>NS<\/b>: Tak. To znaczy, widz\u0105 to tak: je\u015bli we\u017amiemy dystrybucj\u0119 Linuksa i j\u0105dro, to zwyk\u0142y PostgreSQL to j\u0105dro, a oni chc\u0105 stworzy\u0107 dystrybucj\u0119, kt\u00f3ra b\u0119dzie przyjazna dla chmur i dzia\u0142a\u0142a w Kubernetes. \u0141\u0105cz\u0105 komponenty (kopie zapasowe itp.) i optymalizuj\u0105, aby dzia\u0142a\u0142y dobrze.<\/i><\/p>\n<p><b>DS<\/b>: Bardzo fajnie! W zasadzie to oprogramowanie, aby stworzy\u0107 w\u0142asny zarz\u0105dzany Postgres.<\/p>\n<p><i><b>NS<\/b>: Z dystrybucjami Linuksa zawsze s\u0105 problemy: jak robi\u0107 sterowniki, aby wspiera\u0142y ca\u0142y sprz\u0119t. A ich pomys\u0142 polega na tym, \u017ce b\u0119d\u0105 dzia\u0142a\u0107 w Kubernetes. Wiem, \u017ce w operatorze Zalando niedawno widzieli\u015bmy powi\u0105zanie z AWS i to ju\u017c nie jest najlepsze. Nie powinno by\u0107 zwi\u0105zania z konkretn\u0105 infrastruktur\u0105 \u2014 jaki w tym sens?<\/i><\/p>\n<p><b>DS<\/b>: Nie wiem, w jakiej sytuacji konkretnie Zalando si\u0119 zwi\u0105za\u0142o, ale w Kubernetes teraz storage zrobione jest tak, \u017ce nie mo\u017cna w spos\u00f3b og\u00f3lny wykona\u0107 kopii zapasowej dysku. Niedawno w standardzie \u2014 w ostatniej wersji <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465417\/\">specyfikacji CSI<\/a><\/noindex> \u2014 wprowadzono mo\u017cliwo\u015b\u0107 zrzut\u00f3w, ale gdzie to jest wdro\u017cone? Szczerze, wci\u0105\u017c jest to tak niegotowe\u2026 Pr\u00f3bujemy CSI na AWS, GCE, Azure, vSphere, ale jak tylko zaczynasz u\u017cywa\u0107, wida\u0107, \u017ce to jeszcze nie jest gotowe.<\/p>\n<p><i><b>NS<\/b>: Dlatego czasami trzeba si\u0119 wi\u0105za\u0107 z infrastruktur\u0105. My\u015bl\u0119, \u017ce to nadal wczesny etap \u2014 problemy z wzrostem. Pytanie: co by\u015b doradzi\u0142 nowicjuszom, kt\u00f3rzy chc\u0105 spr\u00f3bowa\u0107 PgSQL w K8s? Jaki operator, mo\u017ce?<\/i><\/p>\n<p><b>DS<\/b>: Problem polega na tym, \u017ce Postgres to dla nas tylko 3%. Mamy jeszcze bardzo d\u0142ug\u0105 list\u0119 r\u00f3\u017cnych program\u00f3w w Kubernetes, nawet nie b\u0119d\u0119 wszystkiego wymienia\u0107. Na przyk\u0142ad, Elasticsearch. Operator\u00f3w jest sporo: niekt\u00f3re rozwijaj\u0105 si\u0119 intensywnie, inne - nie. Ustalili\u015bmy dla siebie wymagania, co musi by\u0107 w operatorze, \u017ceby\u015bmy traktowali go powa\u017cnie. W operatorze przeznaczonym dok\u0142adnie dla Kubernetes - nie w \u201eoperatorze, kt\u00f3ry ma robi\u0107 co\u015b w warunkach Amazona\u201d\u2026 W praktyce do\u015b\u0107 powszechnie (prawie u wszystkich klient\u00f3w) u\u017cywamy jednego operatora - <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spotahome\/redis-operator\">dla Redis<\/a><\/noindex> <i>(wkr\u00f3tce opublikujemy o nim artyku\u0142)<\/i>.<\/p>\n<p><i><b>NS<\/b>: A dla MySQL te\u017c nie ma? Wiem, \u017ce Percona\u2026 poniewa\u017c teraz zajmuj\u0105 si\u0119 zar\u00f3wno MySQL, jak i MongoDB, i Postgres, musz\u0105 stworzy\u0107 jaki\u015b uniwersalny: dla wszystkich baz, dla wszystkich dostawc\u00f3w chmurowych.<\/i><\/p>\n<p><b>DS<\/b>: Nie zd\u0105\u017cyli\u015bmy przyjrze\u0107 si\u0119 operatorom dla MySQL. Nie jest to nasz g\u0142\u00f3wny fokus. MySQL dzia\u0142a dobrze w trybie standalone. Po co operator, skoro mo\u017cna po prostu uruchomi\u0107 baz\u0119 danych... Mo\u017cna uruchomi\u0107 kontener Docker z Postrges, albo mo\u017cna to zrobi\u0107 w prostszy spos\u00f3b.<\/p>\n<p><i><b>NS<\/b>: By\u0142 r\u00f3wnie\u017c taki temat. Ca\u0142kowicie bez operatora?<\/i><\/p>\n<p><b>DS<\/b>: Tak, w 100% mamy PostgreSQL uruchomiony bez operatora. Na razie tak jest. Aktywnie u\u017cywamy operatora dla Prometheus i Redis. Planujemy znale\u017a\u0107 operatora dla Elasticsearch \u2014 to jest najbardziej \u201epal\u0105ce\u201d, poniewa\u017c chcemy go wdro\u017cy\u0107 w Kubernetes w 100% przypadk\u00f3w. Podobnie jak chcemy, aby MongoDB zawsze by\u0142o uruchamiane w Kubernetes. Pojawiaj\u0105 si\u0119 pewne wymagania \u2014 czujemy, \u017ce w takich przypadkach mo\u017cna co\u015b zrobi\u0107. A do Postgresa nawet nie spojrzeli\u015bmy. Oczywi\u015bcie, wiemy o istnieniu r\u00f3\u017cnych opcji, ale faktycznie mamy standalone.<\/p>\n<h2>Baza danych do test\u00f3w w Kubernetes<\/h2>\n<p>\n<i><b>NS<\/b>: Przejd\u017amy do tematu testowania. Jak wdra\u017ca\u0107 zmiany w bazie \u2014 z punktu widzenia perspektywy DevOps. S\u0105 mikroserwisy, wiele baz, ca\u0142y czas co\u015b si\u0119 zmienia. Jak zapewni\u0107 normalne CI\/CD, \u017ceby z perspektywy DB wszystko by\u0142o w porz\u0105dku. Jakie jest Twoje podej\u015bcie?<\/i><\/p>\n<p><b>DS<\/b>: Nie ma jednej odpowiedzi. Jest kilka parametr\u00f3w. Pierwszy to rozmiar bazy, kt\u00f3r\u0105 chcemy wdro\u017cy\u0107. Sam wspomnia\u0142e\u015b, \u017ce w firmach r\u00f3\u017cnie podchodz\u0105 do konieczno\u015bci posiadania kopii prod-bazy w dev i stage.<\/p>\n<p><i><b>NS<\/b>: A w warunkach GDPR, my\u015bl\u0119, \u017ce podchodz\u0105 do tego coraz bardziej ostro\u017cnie... Mog\u0119 powiedzie\u0107, \u017ce w Europie ju\u017c zacz\u0119li nak\u0142ada\u0107 kary.<\/i><\/p>\n<p><b>DS<\/b>: Ale cz\u0119sto mo\u017cna napisa\u0107 oprogramowanie, kt\u00f3re robi dump z produkcji i go obfuskowane. Powstaj\u0105 dane produkcyjne (snapshota, dump, binarna kopia\u2026), ale s\u0105 one zanonimizowane. Zamiast tego mog\u0105 by\u0107 te\u017c skrypty generuj\u0105ce: mog\u0105 to by\u0107 fixture\u2019y lub po prostu skrypt, kt\u00f3ry generuje du\u017c\u0105 baz\u0119. Jaki jest problem: ile czasu zajmuje stworzenie podstawowego obrazu? I ile czasu potrzebne jest, aby go uruchomi\u0107 w odpowiednim \u015brodowisku?<\/p>\n<p>Doszli\u015bmy do schematu: je\u015bli klient ma zbi\u00f3r danych oak-instancjonowanych (minimalna wersja bazy), to domy\u015blnie je wykorzystujemy. Je\u015bli m\u00f3wimy o \u015brodowiskach review, kiedy stworzyli\u015bmy branch, uruchamiamy instancj\u0119 aplikacji \u2014 wdra\u017camy tam ma\u0142\u0105 baz\u0119. Ale to te\u017c wysz\u0142o dobrze. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/417509\/\">wariant<\/a><\/noindex>, kiedy z produkcji raz dziennie (noc\u0105) wykonujemy dump i na jego podstawie tworzymy kontener Docker z PostgreSQL i MySQL z tymi za\u0142adowanymi danymi. Je\u015bli z tego obrazu trzeba 50 razy uruchomi\u0107 baz\u0119, to robi si\u0119 to do\u015b\u0107 \u0142atwo i szybko.<\/p>\n<p><i><b>NS<\/b>: Prosto przez skopiowanie?<\/i><\/p>\n<p><b>DS<\/b>: Dane s\u0105 przechowywane bezpo\u015brednio w obrazie Docker. Tzn. mamy gotowy obraz, powiedzmy 100 GB. Dzi\u0119ki warstwom w Docker mo\u017cemy szybko rozwija\u0107 ten obraz potrzebn\u0105 ilo\u015b\u0107 razy. Metoda prosta, ale dzia\u0142a ca\u0142kiem nie\u017ale.<\/p>\n<p><i><b>NS<\/b>: Nast\u0119pnie, kiedy testujesz, to zmienia si\u0119 bezpo\u015brednio w Dockerze, prawda? Copy-on-write wewn\u0105trz Dockera - wyrzucamy i zaczynamy od nowa, wszystko dzia\u0142a dobrze. \u015awietnie! A wy ju\u017c to na ca\u0142ego stosujecie?<\/i><\/p>\n<p><b>DS<\/b>: Od dawna.<\/p>\n<p><i><b>NS<\/b>: Zajmujemy si\u0119 bardzo podobnymi rzeczami. Tylko my nie u\u017cywamy dockerowskiego copy-on-write, tylko co\u015b innego.<\/i><\/p>\n<p><b>DS<\/b>: On nie jest uniwersalny. A dockerowski dzia\u0142a wsz\u0119dzie.<\/p>\n<p><i><b>NS<\/b>: Teoretycznie tak. Ale mamy tam te\u017c modu\u0142y, mo\u017cna zrobi\u0107 r\u00f3\u017cne modu\u0142y i pracowa\u0107 z r\u00f3\u017cnymi systemami plik\u00f3w. Chodzi o to, \u017ce z perspektywy Postgresa na wszystko to spogl\u0105damy inaczej. Teraz spojrza\u0142em z perspektywy Dockera i zobaczy\u0142em, \u017ce u was wszystko dzia\u0142a. Ale je\u015bli baza jest ogromna, na przyk\u0142ad 1 TB, to ju\u017c wszystko trwa d\u0142ugo: operacje w nocy, wpychanie wszystkiego do Dockera\u2026 A je\u015bli 5 TB wpycha\u0107 do Dockera\u2026 Czy wszystko jest w porz\u0105dku?<\/i><\/p>\n<p><b>DS<\/b>: Jaka r\u00f3\u017cnica: to s\u0105 tylko blob'y, po prostu bity i bajty.<\/p>\n<p><i><b>NS<\/b>: R\u00f3\u017cnica jest taka: robicie to przez dump i restore?<\/i><\/p>\n<p><b>DS<\/b>: Wcale nie musi by\u0107. Sposoby generowania tego obrazu mog\u0105 by\u0107 r\u00f3\u017cne.<\/p>\n<p><i><b>NS<\/b>: Dla niekt\u00f3rych klient\u00f3w zrobili\u015bmy tak, \u017ce zamiast regularnej generacji podstawowego obrazu, ci\u0105gle utrzymujemy go w aktualnym stanie. W zasadzie jest to replika, ale dane otrzymuje nie z mastera bezpo\u015brednio, lecz przez archiwum. To binarne archiwum, do kt\u00f3rego WAL-e s\u0105 nak\u0142adane ka\u017cdego dnia, tam r\u00f3wnie\u017c wykonywane s\u0105 kopie zapasowe\u2026 Te WAL-e potem przylatuj\u0105 \u2014 z niewielkim op\u00f3\u017anieniem (dos\u0142ownie 1-2 sekundy) \u2014 do podstawowego obrazu. Z niego klonujemy w dowolny spos\u00f3b \u2014 teraz domy\u015blnie mamy ZFS.<\/i><\/p>\n<p><b>DS<\/b>: Ale z ZFS jeste\u015b ograniczony do jednego w\u0119z\u0142a.<\/p>\n<p><i><b>NS<\/b>: Tak. Ale ZFS ma jeszcze magiczny <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/cd\/E18752_01\/html\/819-5461\/gbchx.html\">send<\/a><\/noindex>: z nim mo\u017cna wys\u0142a\u0107 migawk\u0119 i nawet (jeszcze tego nie testowa\u0142em, ale\u2026) mo\u017cna przesy\u0142a\u0107 r\u00f3\u017cnice mi\u0119dzy dwoma <code>PGDATA<\/code>. Tak naprawd\u0119 mamy jeszcze jedno narz\u0119dzie, kt\u00f3re niezbyt dok\u0142adnie rozwa\u017cali\u015bmy do takich zada\u0144. W PostgreSQL jest <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/app-pgrewind.html\">pg_rewind<\/a><\/noindex>, dzia\u0142aj\u0105cy jak \u00abinteligentny\u00bb rsync, pomijaj\u0105cy wiele rzeczy, na kt\u00f3re nie trzeba zwraca\u0107 uwagi, poniewa\u017c nic si\u0119 nie zmieni\u0142o. Mo\u017cemy szybko zsynchronizowa\u0107 mi\u0119dzy dwoma serwerami i cofn\u0105\u0107 si\u0119 dok\u0142adnie tak samo.<\/i><\/p>\n<p><i>Tak wi\u0119c staramy si\u0119 z tej, bardziej DBA-owej strony stworzy\u0107 narz\u0119dzie, kt\u00f3re pozwoli zrobi\u0107 to samo, o czym wspomnia\u0142e\u015b: mamy jedn\u0105 baz\u0119, ale chcemy co\u015b przetestowa\u0107 50 razy, niemal r\u00f3wnocze\u015bnie.<\/i><\/p>\n<p><b>DS<\/b>: 50 razy oznacza, \u017ce musisz zam\u00f3wi\u0107 50 instancji Spot.<\/p>\n<p><i><b>NS<\/b>: Nie, robimy to na jednej maszynie.<\/i><\/p>\n<p><b>DS<\/b>: Ale jak uruchomisz 50 razy, je\u015bli ta jedna baza ma na przyk\u0142ad terabajt? Prawdopodobnie potrzebuje oko\u0142o 256 GB RAM?<\/p>\n<p><i><b>NS<\/b>: Tak, czasami pami\u0119ci potrzeba du\u017co \u2014 to normalne. Ale taki przyk\u0142ad z \u017cycia. Na maszynie produkcyjnej 96 rdzeni i 600 GB. W przypadku bazy danych u\u017cywane jest 32 rdzenie (nawet 16 rdzeni teraz czasami) i pami\u0119\u0107 100-120 GB.<\/i><\/p>\n<p><b>DS<\/b>: I wchodzi tam 50 kopii?<\/p>\n<p><i><b>NS<\/b>: Tak, kopia jest jedna, dalej dzia\u0142a copy-on-write (ZFS-owy)\u2026 Opowiem wi\u0119cej.<\/i><\/p>\n<p><i>U nas, na przyk\u0142ad, baza ma 10 TB. Zrobili\u015bmy dysk dla niej, ZFS jeszcze zmniejszy\u0142 jej rozmiar o 30-40%. Poniewa\u017c nie przeprowadzamy test\u00f3w obci\u0105\u017ceniowych, nie zale\u017cy nam na dok\u0142adnym czasie odpowiedzi: mo\u017ce by\u0107 do 2 razy wolniej \u2014 to w porz\u0105dku.<\/i><\/p>\n<p><i>Dajemy mo\u017cliwo\u015b\u0107 programistom, QA, DBA itd. wykonanie test\u00f3w w 1-2 w\u0105tkach. Na przyk\u0142ad mog\u0105 uruchomi\u0107 jak\u0105\u015b migracj\u0119. Nie wymaga to od razu 10 rdzeni \u2014 potrzebny jest 1 backend Postgresa, 1 rdze\u0144. Migracja si\u0119 uruchomi \u2014 mo\u017ce, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/routine-vacuuming.html#AUTOVACUUM\">autovacuum<\/a><\/noindex> jeszcze si\u0119 uruchomi, wtedy zaanga\u017cowane zostanie drugie rdze\u0144. Mamy przydzielone 16-32 rdzenie, wi\u0119c 10 os\u00f3b mo\u017ce pracowa\u0107 jednocze\u015bnie, nie ma \u017cadnych problem\u00f3w.<\/i><\/p>\n<p><i>Poniewa\u017c fizycznie <code>PGDATA<\/code> wychodzi na to, \u017ce oszukujemy Postgresa. Na czym polega trik: uruchamiane s\u0105 na przyk\u0142ad 10 Postgres\u00f3w jednocze\u015bnie. Jaki jest zwykle problem? Instaluj\u0105 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-resource.html\">shared_buffers<\/a><\/noindex>, powiedzmy, na 25%. Odpowiednio, to 200 GB. Wi\u0119cej ni\u017c trzy takie ju\u017c nie uruchomisz, bo pami\u0119\u0107 si\u0119 sko\u0144czy.<\/i><\/p>\n<p><i>Ale w pewnym momencie zrozumieli\u015bmy, \u017ce to nie jest konieczne: ustawiamy shared_buffers na 2 GB. PostgreSQL ma <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE\">effective_cache_size<\/a><\/noindex>, i w rzeczywisto\u015bci tylko on wp\u0142ywa na <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Query_plan\">plany<\/a><\/noindex>. To ustawiamy na 0,5 TB. I nawet nie wa\u017cne, \u017ce ich w rzeczywisto\u015bci nie ma: buduje plany, jakby one by\u0142y.<\/i><\/p>\n<p><i>Odpowiednio, gdy testujemy jak\u0105\u015b migracj\u0119, mo\u017cemy zebra\u0107 wszystkie plany \u2014 zobaczymy, jak to si\u0119 b\u0119dzie odbywa\u0107 na produkcji. Czas b\u0119dzie inny (wolniejszy), ale dane, kt\u00f3re rzeczywi\u015bcie odczytujemy, i same plany (jakie\u015b JOIN-y itd.) b\u0119d\u0105 dok\u0142adnie takie same jak na produkcji. I r\u00f3wnocze\u015bnie mo\u017cna uruchamia\u0107 wiele takich sprawdze\u0144 na jednej maszynie.<\/i><\/p>\n<p><b>DS<\/b>: Nie uwa\u017casz, \u017ce s\u0105 tutaj pewne problemy? Po pierwsze, to rozwi\u0105zanie, kt\u00f3re dzia\u0142a tylko na PostgreSQL. Takie podej\u015bcie jest bardzo specyficzne, nie jest og\u00f3lne. Po drugie, Kubernetes (i wszystko, w co obecnie zmierzaj\u0105 technologie chmurowe) zak\u0142ada wiele w\u0119z\u0142\u00f3w, a te w\u0119z\u0142y s\u0105 efemeryczne. A w twoim przypadku to jest stateful, trwa\u0142y w\u0119ze\u0142. Te rzeczy budz\u0105 moje w\u0105tpliwo\u015bci.<\/p>\n<p><i><b>NS<\/b>: Po pierwsze \u2014 zgadzam si\u0119, to czysta historia zwi\u0105zana z Postgresem. My\u015bl\u0119, \u017ce je\u015bli mamy jaki\u015b direct IO i bufor pami\u0119ci prawie pod ca\u0142\u0105 pami\u0119\u0107, takie podej\u015bcie si\u0119 nie sprawdzi \u2014 plany b\u0119d\u0105 inne. Ale na razie pracujemy tylko z Postgresem, o innych nie my\u015blimy.<\/i><\/p>\n<p><i>O Kubernetes. Sam przecie\u017c wsz\u0119dzie m\u00f3wisz, \u017ce nasza baza jest trwa\u0142a. Je\u015bli instancja upadnie, najwa\u017cniejsze jest, aby zachowa\u0107 dysk. Nasza ca\u0142a platforma jest te\u017c w Kubernetes, a komponent z Postgres jest osobno (chocia\u017c i on tam kiedy\u015b b\u0119dzie). Dlatego to tak: instancja upad\u0142a, ale zachowali\u015bmy jej PV i po prostu pod\u0142\u0105czyli\u015bmy do innej (nowej) instancji, jakby nic si\u0119 nie sta\u0142o.<\/i><\/p>\n<p><b>DS<\/b>: Z mojego punktu widzenia tworzymy pody w Kubernetes. K8s \u2014 elastyczny: w\u0119z\u0142y zamawiane s\u0105 same w miar\u0119 potrzeby. Zadanie polega po prostu na stworzeniu poda i powiedzeniu, \u017ce potrzebuje X zasob\u00f3w, a dalej K8s sam si\u0119 tym zajmie. Ale wsparcie dla przechowywania w Kubernetes nadal jest niestabilne: w <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/467477\/\">1.16<\/a><\/noindex>, w <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476998\/\">1.17<\/a><\/noindex> (ta wydania wysz\u0142a <i>tygodnie<\/i> temu) te funkcje staj\u0105 si\u0119 dopiero beta.<\/p>\n<p>Minie p\u00f3\u0142 roku do roku \u2014 stanie si\u0119 to mniej wi\u0119cej stabilne, lub przynajmniej tak og\u0142oszone. Wtedy mo\u017cliwo\u015b\u0107 tworzenia kopii zapasowych (snapshot\u00f3w) i zmiany rozmiaru rozwi\u0105zuje tw\u00f3j problem ca\u0142kowicie. Bo masz baz\u0119. Tak, mo\u017ce nie jest najszybsza, ale pr\u0119dko\u015b\u0107 zale\u017cy od tego, co jest \u00abpod mask\u0105\u00bb, poniewa\u017c niekt\u00f3re realizacje obs\u0142uguj\u0105 kopiowanie i copy-on-write na poziomie subsystemu dyskowego.<\/p>\n<p><i><b>NS<\/b>: Tu trzeba jeszcze, aby wszystkie silniki (Amazon, Google\u2026) zd\u0105\u017cy\u0142y zacz\u0105\u0107 wspiera\u0107 t\u0119 wersj\u0119 \u2014 to te\u017c zajmuje czas.<\/i><\/p>\n<p><b>DS<\/b>: Na razie ich nie u\u017cywamy. U\u017cywamy swojego.<\/p>\n<h2>Lokalny rozw\u00f3j pod Kubernetes<\/h2>\n<p>\n<i><b>NS<\/b>: Spotka\u0142e\u015b si\u0119 z tak\u0105 potrzeb\u0105, \u017ceby na jednej maszynie uruchomi\u0107 wszystkie pod&#8217;y i wykona\u0107 ma\u0142e testy. Aby szybko uzyska\u0107 dow\u00f3d koncepcji, zobaczy\u0107, \u017ce aplikacja dzia\u0142a w Kubernetes, nie przydzielaj\u0105c do tego wielu maszyn. Jest Minikube, prawda?<\/i><\/p>\n<p><b>DS<\/b>: Wydaje mi si\u0119, \u017ce ten przypadek \u2014 uruchomienie na jednym w\u0119\u017ale \u2014 dotyczy wy\u0142\u0105cznie lokalnego rozwoju. Albo jakich\u015b przejaw\u00f3w tego wzorca. Jest <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/333470\/\">Minikube<\/a><\/noindex>, jest <noindex><a rel=\"nofollow\" href=\"https:\/\/k3s.io\/\">k3s<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes-sigs\/kind\">KIND<\/a><\/noindex>. Zbli\u017camy si\u0119 do tego, aby u\u017cywa\u0107 Kubernetes IN Docker. Ju\u017c zacz\u0119li\u015bmy nad tym pracowa\u0107 do test\u00f3w.<\/p>\n<p><i><b>NS<\/b>: Kiedy\u015b my\u015bla\u0142em, \u017ce to pr\u00f3ba zapakowania wszystkich pod&#8217;\u00f3w w jeden obraz Docker. Ale okaza\u0142o si\u0119, \u017ce chodzi o co\u015b zupe\u0142nie innego. I tak s\u0105 tam oddzielne kontenery, oddzielne pod&#8217;y \u2014 po prostu w Dockerze.<\/i><\/p>\n<p><b>DS<\/b>: Tak. I jest tam ca\u0142kiem zabawna imitacja, ale sens jest taki\u2026 Mamy narz\u0119dzie do wdra\u017cania \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>. Chcemy w nim doda\u0107 tryb \u2014 nazwijmy go <code>werf up<\/code>: \u201eUruchom mi lokalny Kubernetes\u201d. A nast\u0119pnie uruchomi\u0107 tam warunkowy <code>werf follow<\/code>. Wtedy programista b\u0119dzie m\u00f3g\u0142 edytowa\u0107 w IDE, a w systemie b\u0119dzie uruchomiony proces, kt\u00f3ry widzi zmiany i przebudowuje obrazy, wdra\u017ca je w lokalnym K8s. W ten spos\u00f3b chcemy spr\u00f3bowa\u0107 rozwi\u0105za\u0107 problem lokalnego rozwoju.<\/p>\n<h2>Migawki i klonowanie baz danych w realiach K8s<\/h2>\n<p>\n<i><b>NS<\/b>: Je\u015bli wr\u00f3cimy do copy-on-write. Zauwa\u017cy\u0142em, \u017ce chmury r\u00f3wnie\u017c maj\u0105 snapshoty. Dzia\u0142aj\u0105 w r\u00f3\u017cny spos\u00f3b. Na przyk\u0142ad w GCP: na wschodnim wybrze\u017cu USA masz wieloteraowy instancj\u0119. Regularnie robisz snapshoty. Podnosisz z snapshotu kopi\u0119 dysku na zachodnim wybrze\u017cu \u2014 po kilku minutach wszystko jest gotowe, dzia\u0142a bardzo szybko, tylko pami\u0119\u0107 podr\u0119czna musi by\u0107 wype\u0142niona w pami\u0119ci. Ale te klony (snapshoty) \u2014 s\u0105 do tego, aby za&#8217;provision&#8217;owa\u0107 nowy wolumin. To \u015bwietne, gdy trzeba stworzy\u0107 wiele instancji.<\/i><\/p>\n<p><i>A je\u015bli chodzi o testy, my\u015bl\u0119, \u017ce snapshoty, o kt\u00f3rych m\u00f3wisz w Dockerze, lub ja m\u00f3wi\u0119 w ZFS, btrfs, a nawet LVM\u2026 \u2014 pozwalaj\u0105 na jednej maszynie nie tworzy\u0107 naprawd\u0119 nowych danych. W chmurze b\u0119dziesz jeszcze musia\u0142 za nie p\u0142aci\u0107 za ka\u017cdym razem i nie czeka\u0107 sekundy, ale minuty (a w przypadku <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/about-aws\/whats-new\/2019\/11\/amazon-ebs-fast-snapshot-restore-eliminates-need-for-prewarming-data-into-volumes-created-snapshots\/\">lazy load&#8217;u<\/a><\/noindex>, by\u0107 mo\u017ce, i godzin).<\/i><\/p>\n<p><i>Zamiast tego mo\u017cesz uzyska\u0107 te dane w sekund\u0119 lub dwie, uruchomi\u0107 test i wyrzuci\u0107. Te migawki rozwi\u0105zuj\u0105 r\u00f3\u017cne zadania. W pierwszym przypadku \u2014 aby si\u0119 skalowa\u0107 i zyska\u0107 nowe repliki, a w drugim \u2014 do test\u00f3w.<\/i><\/p>\n<p><b>DS<\/b>: Nie zgadzam si\u0119. Prawid\u0142owe klonowanie wolumin\u00f3w to zadanie dla chmury. Nie ogl\u0105da\u0142em ich implementacji, ale wiem, jak to robimy na sprz\u0119cie. Mamy Ceph, w kt\u00f3rym mo\u017cna ka\u017cdemu fizycznemu woluminowi (<noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ceph.com\/docs\/master\/rbd\/\">RBD<\/a><\/noindex>) powiedzie\u0107 <i>clone<\/i> i otrzyma\u0107 w ci\u0105gu kilku milisekund drugi wolumin o takich samych parametrach, <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/IOPS\">IOPS<\/a><\/noindex>&#8216;\u00f3w itd. Trzeba rozumie\u0107, \u017ce tam wewn\u0105trz jest sprytny copy-on-write. Dlaczego chmura nie mo\u017ce tego robi\u0107 tak samo? Jestem pewien, \u017ce w taki czy inny spos\u00f3b staraj\u0105 si\u0119 to zrobi\u0107.<\/p>\n<p><i><b>NS<\/b>: Ale i tak b\u0119d\u0105 potrzebowa\u0107 sekund, dziesi\u0105tk\u00f3w sekund, \u017ceby uruchomi\u0107 instancj\u0119, wprowadzi\u0107 Dockera itp.<\/i><\/p>\n<p><b>DS<\/b>: Dlaczego trzeba koniecznie uruchamia\u0107 ca\u0142\u0105 instancj\u0119? Mamy przecie\u017c instancj\u0119 na 32 rdzenie, na 16\u2026 i mie\u015bci si\u0119 w niej pewna liczba \u2014 na przyk\u0142ad cztery. Kiedy zamawiamy pi\u0105t\u0105, ju\u017c zostanie uruchomiona instancja, a potem zostanie usuni\u0119ta.<\/p>\n<p><i><b>NS<\/b>: Tak, interesuj\u0105ce, 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\u0119cej ni\u017c dwie sekundy.<\/i><\/p>\n<p><b>DS<\/b>: To \u015bwietnie. Ale m\u00f3j pierwotny pomys\u0142 to, \u017ce to nie jest rozwi\u0105zanie og\u00f3lne. Tak, jest fajne, ale nadaje si\u0119 tylko dla Postgres i tylko na jednym w\u0119\u017ale.<\/p>\n<p><i><b>NS<\/b>: Nadaje si\u0119 nie tylko dla Postgres: to plany, jak opisa\u0142em, b\u0119d\u0105 tak dzia\u0142a\u0107 tylko w nim. Ale je\u015bli nie przejmowa\u0107 si\u0119 planami, a potrzebujemy tylko wszystkich danych do testowania funkcjonalnego, to wtedy nadaje si\u0119 do ka\u017cdej bazy danych.<\/i><\/p>\n<p><b>DS<\/b>: Wiele lat temu robili\u015bmy co\u015b podobnego na zrzutach LVM. To klasyka. Tego typu podej\u015bcie by\u0142o bardzo aktywnie stosowane. Po prostu stateful-w\u0119z\u0142y to b\u00f3l. Poniewa\u017c trzeba o nich pami\u0119ta\u0107, nie mog\u0105 si\u0119 wy\u0142\u0105cza\u0107...<\/p>\n<p><i><b>NS<\/b>: Czy nie widzisz tutaj jakiej\u015b mo\u017cliwo\u015bci hybrydy? Powiedzmy, \u017ce stateful to jaki\u015b pod, dzia\u0142a na kilku ludziach (wielu tester\u00f3w). Wolumin mamy jeden, ale dzi\u0119ki systemowi plik\u00f3w klony s\u0105 lokalne. Je\u015bli pod upadnie, dysk zostanie \u2014 podniesiemy pod, odczyta informacje o wszystkich klonach, wszystko podniesie z powrotem i powie: \u201eOto wasze klony uruchomione na tych portach, pracujcie z nimi dalej\u201d.<\/i><\/p>\n<p><b>DS<\/b>: Technicznie oznacza to, \u017ce w ramach Kubernetes to jeden pod, w kt\u00f3rym uruchamiamy wiele Postgres&#8217;\u00f3w.<\/p>\n<p><i><b>NS<\/b>: Tak. Ma ograniczenie: powiedzmy, \u017ce jednocze\u015bnie pracuje z nim nie wi\u0119cej ni\u017c 10 os\u00f3b. Je\u015bli potrzebujemy 20 \u2014 uruchomimy drugi taki pod. Ca\u0142kowicie realistycznie sklonujemy go, otrzymuj\u0105c drugi pe\u0142ny wolumin, na kt\u00f3rym b\u0119d\u0105 takie same 10 \u201ecienkich\u201d klon\u00f3w. Nie widzisz takiej mo\u017cliwo\u015bci?<\/i><\/p>\n<p><b>DS<\/b>: Nale\u017cy tutaj doda\u0107 pytania dotycz\u0105ce bezpiecze\u0144stwa. Taki spos\u00f3b organizacji zak\u0142ada, \u017ce dany pod ma wysokie przywileje (capabilities), poniewa\u017c mo\u017ce wykonywa\u0107 niestandardowe operacje na systemie plik\u00f3w\u2026 Ale powt\u00f3rz\u0119: uwa\u017cam, \u017ce w \u015brednim okresie czasu Kubernetes naprawi storage, w chmurach naprawi ca\u0142\u0105 histori\u0119 z wolumenami \u2014 wszystko b\u0119dzie \u201epo prostu dzia\u0142a\u0107\u201d. B\u0119dzie resize, klonowanie\u2026 Jest wolumen \u2014 m\u00f3wimy: \u201eUtw\u00f3rz nowy na podstawie tego\u201d, i po p\u00f3\u0142torej sekundy otrzymujemy to, czego potrzebujemy.<\/p>\n<p><i><b>NS<\/b>: Nie wierz\u0119 w p\u00f3\u0142torej sekundy dla wielu terabajt\u00f3w. W Ceph robisz to sam, a m\u00f3wisz o chmurach. Id\u017a do chmury, na EC2 sklonuj wolumen EBS wielu terabajt\u00f3w i zobacz, jaka b\u0119dzie wydajno\u015b\u0107. To nie potrwa kilku sekund. Bardzo mnie ciekawi, kiedy osi\u0105gn\u0105 taki wska\u017anik. Rozumiem, o czym m\u00f3wisz, ale pozwol\u0119 sobie si\u0119 nie zgodzi\u0107.<\/i><\/p>\n<p><b>DS<\/b>: Ok, ale powiedzia\u0142em, \u017ce w \u015brednioterminowej perspektywie, nie kr\u00f3tkoterminowej. W ci\u0105gu kilku lat.<\/p>\n<h2>O operatorze dla PostgreSQL od Zalando<\/h2>\n<p>\nW po\u0142owie tego spotkania do\u0142\u0105czy\u0142 do niej r\u00f3wnie\u017c Aleksiej Kliukin, by\u0142y programista z firmy Zalando, kt\u00f3ry opowiedzia\u0142 o historii operatora PostgreSQL:<\/p>\n<blockquote><p>\u015awietnie, \u017ce w og\u00f3le poruszono ten temat: zar\u00f3wno Postgres, jak i Kubernetes. Kiedy zaczynali\u015bmy go robi\u0107 w Zalando w 2017 roku, to by\u0142 temat, kt\u00f3rym wszyscy chcieli si\u0119 zaj\u0105\u0107, ale nikt go nie realizowa\u0142. Wszyscy ju\u017c mieli Kubernetes, ale kiedy pytano, jak by\u0107 z bazami danych, nawet tacy ludzie jak <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kelseyhightower\">Kelsey Hightower<\/a><\/noindex>, g\u0142osz\u0105cy K8s, m\u00f3wili mniej wi\u0119cej tak:<\/p>\n<p><i>\u201eId\u017acie w managed-services i korzystajcie z nich, nie uruchamiajcie DB w Kubernetes. W przeciwnym razie wasz K8s postanowi, na przyk\u0142ad, przeprowadzi\u0107 aktualizacj\u0119, wy\u0142\u0105czy wszystkie w\u0119z\u0142y, a wasze dane odlec\u0105 bardzo daleko.\u201d<\/i><\/p>\n<p>Postanowili\u015bmy stworzy\u0107 operatora, kt\u00f3ry, wbrew tej radzie, uruchomi baz\u0119 danych Postgres w Kubernetes. I mieli\u015bmy dobre podstawy \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\">Patroni<\/a><\/noindex>. To automatyczny failover dla PostgreSQL, zrealizowany prawid\u0142owo, tzn. wykorzystuj\u0105cy etcd, consul lub ZooKeeper jako magazyn informacji o klastrze. Taki magazyn, kt\u00f3ry b\u0119dzie dostarcza\u0142 wszystkim pytaj\u0105cym, na przyk\u0142ad, kto teraz jest liderem, t\u0119 sam\u0105 informacj\u0119 \u2014 mimo \u017ce wszystko jest rozproszone \u2014 aby unikn\u0105\u0107 split brain\u2019a. Dodatkowo, mieli\u015bmy <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\/tree\/master\/docker\">obraz Dockera<\/a><\/noindex> dla niego.<\/p>\n<p>W rzeczy samej, potrzeba auto failoveru w firmie pojawi\u0142a si\u0119 po migracji z wewn\u0119trznego centrum danych do chmury. Chmura by\u0142a oparta na w\u0142asnym rozwi\u0105zaniu PaaS (Platform-as-a-Service). By\u0142o to rozwi\u0105zanie Open Source, ale aby je uruchomi\u0107, trzeba by\u0142o si\u0119 mocno napracowa\u0107. Nazywa\u0142o si\u0119 <noindex><a rel=\"nofollow\" href=\"https:\/\/stups.io\/\">STUPS<\/a><\/noindex>.<\/p>\n<p>Pocz\u0105tkowo nie by\u0142o \u017cadnego Kubernetes\u2019a. A dok\u0142adniej, gdy wdra\u017cano w\u0142asne rozwi\u0105zanie, K8s ju\u017c istnia\u0142, ale by\u0142 na tyle niedojrza\u0142y, \u017ce nie nadawa\u0142 si\u0119 do produkcji. To by\u0142, moim zdaniem, 2015 lub 2016 rok. Do 2017 roku Kubernetes sta\u0142 si\u0119 mniej wi\u0119cej dojrza\u0142y \u2014 pojawi\u0142a si\u0119 potrzeba migracji tam.<\/p>\n<p>I mieli\u015bmy ju\u017c kontener Docker. Istnia\u0142a PaaS, kt\u00f3ra korzysta\u0142a z Dockera. Dlaczego nie spr\u00f3bowa\u0107 K8s? Czemu nie napisa\u0107 w\u0142asnego operatora? Murat Kabilov, kt\u00f3ry do nas przyszed\u0142 z Avito, zacz\u0105\u0142 to jako projekt z w\u0142asnej inicjatywy \u2013 \u00abpobawi\u0107 si\u0119\u00bb \u2013 i projekt \u00abwystartowa\u0142\u00bb.<\/p>\n<p>Ale w og\u00f3le chcia\u0142em opowiedzie\u0107 o AWS. Dlaczego tam historycznie by\u0142 kod zwi\u0105zany z AWS\u2026<\/p>\n<p>Kiedy uruchamiasz cokolwiek w Kubernetes, musisz zrozumie\u0107, \u017ce K8s to tak naprawd\u0119 work in progress. On ci\u0105gle si\u0119 rozwija, poprawia i czasami nawet psuje. Nale\u017cy uwa\u017cnie \u015bledzi\u0107 wszystkie zmiany w Kubernetesie, by\u0107 gotowym w razie potrzeby zag\u0142\u0119bi\u0107 si\u0119 w to i pozna\u0107, jak to dzia\u0142a w szczeg\u00f3\u0142ach \u2013 by\u0107 mo\u017ce bardziej, ni\u017c by\u015b chcia\u0142. To dotyczy ka\u017cdej platformy, na kt\u00f3rej uruchamiasz swoje bazy danych\u2026<\/p>\n<p>Zatem, kiedy tworzyli\u015bmy operatora, mieli\u015bmy Postgresa, kt\u00f3ry dzia\u0142a\u0142 z zewn\u0119trznym woluminem (w tym przypadku EBS, poniewa\u017c pracowali\u015bmy w AWS). Baza danych ros\u0142a, w pewnym momencie trzeba by\u0142o zrobi\u0107 resize: na przyk\u0142ad pocz\u0105tkowy rozmiar EBS wynosi\u0142 100 TB, baza osi\u0105gn\u0119\u0142a ten rozmiar i teraz chcemy zwi\u0119kszy\u0107 EBS do 200 TB. Jak? Za\u0142\u00f3\u017cmy, \u017ce mo\u017cna zrobi\u0107 zrzut\/odtworzenie na nowym instancie, ale to zajmuje du\u017co czasu i wi\u0105\u017ce si\u0119 z przestojem.<\/p>\n<p>Dlatego chcieli\u015bmy takiego resize, kt\u00f3ry zwi\u0119kszy partycj\u0119 EBS\u2019a i potem powie systemowi plik\u00f3w, aby u\u017cywa\u0142 nowej przestrzeni. I zrobili\u015bmy to, ale w\u00f3wczas Kubernetes nie mia\u0142 \u017cadnego API do operacji resize\u2019u. Poniewa\u017c pracowali\u015bmy na AWS, napisali\u015bmy kod dla jego API.<\/p>\n<p>Nikt nie przeszkadza, aby zrobi\u0107 to samo dla innych platform. W operatorze nie ma powi\u0105zania, \u017ce mo\u017cna go uruchomi\u0107 tylko na AWS, a na wszystkim innym nie b\u0119dzie dzia\u0142a\u0142. Og\u00f3lnie rzecz bior\u0105c, to projekt Open Source: je\u015bli ktokolwiek chce przyspieszy\u0107 wdro\u017cenie nowego API \u2013 zapraszam. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">GitHub<\/a><\/noindex>,pull-requesty \u2014 zesp\u00f3\u0142 Zalando stara si\u0119 na nie do\u015b\u0107 szybko reagowa\u0107 i promowa\u0107 operatora. Z tego co wiem, projekt <noindex><a rel=\"nofollow\" href=\"https:\/\/summerofcode.withgoogle.com\/archive\/2019\/organizations\/6187982082539520\/\">bra\u0142 udzia\u0142<\/a><\/noindex> w Google Summer of Code oraz innych podobnych inicjatywach. Zalando bardzo aktywnie nad nim pracuje.\n<\/p><\/blockquote>\n<p><\/p>\n<h2>P.S. Bonus!<\/h2>\n<p>\nJe\u015bli interesuje Was temat PostgreSQL i Kubernetes, zwracamy r\u00f3wnie\u017c uwag\u0119, \u017ce w zesz\u0142ym tygodniu odby\u0142 si\u0119 kolejny Postgres-wtorek, gdzie z Niko\u0142ajem rozmawia\u0142 <b>Aleksander Kuku\u015bkin z Zalando<\/b>. Wideo z tego jest dost\u0119pne <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=FE0xi7SBqsg\">tutaj<\/a><\/noindex>.<\/p>\n<h2>P.P.S.<\/h2>\n<p>\nPrzeczytaj tak\u017ce na naszym blogu:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Bazy danych i Kubernetes (przegl\u0105d i wideo wyst\u0105pienia)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/475036\/\">Migracja Cassandry w Kubernetes: cechy i rozwi\u0105zania<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/461149\/\">Niezwyk\u0142a migracja MongoDB do Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/450662\/\">K\u0142opotliwa migracja RabbitMQ do Kubernetes<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/479438\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043c\u0438\u043d\u0443\u0432\u0448\u0435\u0433\u043e \u0433\u043e\u0434\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0441\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u043f\u0440\u044f\u043c\u043e\u0439 \u044d\u0444\u0438\u0440 \u0440\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0433\u043e PostgreSQL-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 #RuPostgres, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0435\u0433\u043e \u0441\u043e\u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u041d\u0438\u043a\u043e\u043b\u0430\u0439 \u0421\u0430\u043c\u043e\u0445\u0432\u0430\u043b\u043e\u0432 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0441 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u043e\u043c \u00ab\u0424\u043b\u0430\u043d\u0442\u0430\u00bb \u0414\u043c\u0438\u0442\u0440\u0438\u0435\u043c \u0421\u0442\u043e\u043b\u044f\u0440\u043e\u0432\u044b\u043c \u043f\u0440\u043e \u044d\u0442\u0443 \u0421\u0423\u0411\u0414 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 Kubernetes. \u041c\u044b \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0441\u0442\u0435\u043d\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u044d\u0442\u043e\u0439 \u0434\u0438\u0441\u043a\u0443\u0441\u0441\u0438\u0438, \u0430 \u043d\u0430 YouTube-\u043a\u0430\u043d\u0430\u043b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u0432\u0438\u0434\u0435\u043e\u0437\u0430\u043f\u0438\u0441\u044c: \u0411\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 Kubernetes \u041d\u0421: \u041c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u0440\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":55468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-55467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Postgres-\u0432\u0442\u043e\u0440\u043d\u0438\u043a \u21165: \u00abPostgreSQL \u0438 Kubernetes. CI\/CD. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u00bb | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-01-20T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:03:35+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Postgres-wtorek nr 5: \u201ePostgreSQL i Kubernetes. CI\/CD. Automatyzacja testowania\u201d | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Postgres-\u0432\u0442\u043e\u0440\u043d\u0438\u043a \u21165: \u00abPostgreSQL \u0438 Kubernetes. CI\/CD. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u00bb | ProHoster","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-01-20T21:00:00+00:00","article:modified_time":"2020-02-18T11:03:35+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55467","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:43:31","updated":"2022-10-06 02:34:09","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/55467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=55467"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/55467\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/55468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=55467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=55467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=55467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}