{"id":95322,"date":"2020-09-28T07:42:39","date_gmt":"2020-09-28T05:42:39","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt"},"modified":"2020-09-28T07:42:39","modified_gmt":"2020-09-28T05:42:39","slug":"kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt","title":{"rendered":"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/23b2db49941fa5bd5000358c8ffb991b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDin ce \u00een ce mai des, clien\u021bii ne cer: \u201eVrem ceva ca Amazon RDS, dar mai ieftin\u201d; \u201eVrem ceva ca RDS, dar peste tot, \u00een orice infrastructur\u0103\u201d. Pentru a realiza o astfel de solu\u021bie gestionat\u0103 pe Kubernetes, am analizat starea actual\u0103 a celor mai populare operatori pentru PostgreSQL (Stolon, operatorii de la Crunchy Data \u0219i Zalando) \u0219i am f\u0103cut alegerea noastr\u0103.<\/p>\n<p>Acest articol reflect\u0103 experien\u021ba noastr\u0103 ob\u021binut\u0103 at\u00e2t din punct de vedere teoretic (revizuirea solu\u021biilor), c\u00e2t \u0219i practic (ce am ales \u0219i ce rezultat a avut). Dar mai \u00eent\u00e2i, s\u0103 stabilim ce cerin\u021be sunt impuse unei posibile \u00eenlocuiri a RDS\u2026<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Ce este RDS<\/h2>\n<p>\nC\u00e2nd oamenii vorbesc despre RDS, din experien\u021ba noastr\u0103, ei se refer\u0103 la un serviciu de baze de date gestionat (managed) care:<\/p>\n<ol>\n<li>se configureaz\u0103 u\u0219or;<\/li>\n<li>ofer\u0103 posibilitatea de a lucra cu snapshot-uri \u0219i de a se recupera din acestea (preferabil cu suport pentru <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Point-in-time_recovery\">PITR<\/a><\/noindex>);<\/li>\n<li>permite crearea de topologii master-slave;<\/li>\n<li>are o list\u0103 bogat\u0103 de extensii;<\/li>\n<li>ofer\u0103 audit \u0219i gestionarea utilizatorilor\/accesului.<\/li>\n<\/ol>\n<p>\n\u00cen general, abord\u0103rile pentru realizarea acestei sarcini pot fi foarte diferite, \u00eens\u0103 calea cu un Ansible condi\u021bionat nu ne este apropiat\u0103. (La aceea\u0219i concluzie au ajuns \u0219i colegii de la 2GIS \u00een urma <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/509926\/\">\u00eencerc\u0103rii lor<\/a><\/noindex> de a crea \u201eun instrument pentru desf\u0103\u0219urarea rapid\u0103 a unui cluster rezistent bazat pe Postgres\u201d.)<\/p>\n<p>Exact operatorii sunt abordarea general acceptat\u0103 pentru a rezolva astfel de sarcini \u00een ecosistemul Kubernetes. Detalii despre ace\u0219tia \u00een contextul bazelor de date rulate \u00een Kubernetes au fost deja prezentate de tehnicul director \u201eFlanta\u201d, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/distol\/\" class=\"user_link\">distol<\/a><\/noindex>, pe <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">\u00eentr-una dintre expunerile sale<\/a><\/noindex>.<\/p>\n<p><i><strong>NB<\/strong><\/i><i>: Pentru crearea rapid\u0103 a unor operatori simpli, recomand\u0103m s\u0103 acorda\u021bi aten\u021bie utilitarului nostru Open Source <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/shell-operator\"><i>shell-operator<\/i><\/a><\/noindex><i>. Folosind acesta, se poate face f\u0103r\u0103 cuno\u0219tin\u021be de Go, \u00eentr-un mod mai familiar pentru administratori: pe Bash, Python etc.<\/i><\/p>\n<p>Pentru PostgreSQL exist\u0103 c\u00e2\u021biva operatori K8s populari:<\/p>\n<ul>\n<li>Stolon;<\/li>\n<li>Operatorul PostgreSQL de la Crunchy Data;<\/li>\n<li>Operatorul Postgres de la Zalando.<\/li>\n<\/ul>\n<p>\nS\u0103 le examin\u0103m mai atent.<\/p>\n<h2>Alegerea operatorului<\/h2>\n<p>\nPe l\u00e2ng\u0103 acele func\u021bionalit\u0103\u021bi importante men\u021bionate mai sus, noi \u2014 ca ingineri de opera\u021biuni \u00een infrastructura Kubernetes \u2014 ne-am a\u0219teptat de asemenea de la operatori la urm\u0103toarele:<\/p>\n<ul>\n<li> deplasare din Git \u0219i cu <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/extend-kubernetes\/operator\/#deploying-operators\">Resurse Personalizate<\/a><\/noindex>;<\/li>\n<li> suport pentru anti-afinitate pod;<\/li>\n<li> instalarea afinit\u0103\u021bii de nod sau selector de nod;<\/li>\n<li> instalarea tolerancelor;<\/li>\n<li> disponibilitatea op\u021biunilor de tuning;<\/li>\n<li> tehnologii \u0219i chiar comenzi clare.<\/li>\n<\/ul>\n<p>\nF\u0103r\u0103 a intra \u00een detalii pentru fiecare punct (\u00eentreba\u021bi \u00een comentarii dac\u0103 mai ave\u021bi \u00eentreb\u0103ri dup\u0103 citirea \u00eentregului articol), voi sublinia \u00een general c\u0103 ace\u0219ti parametri sunt necesari pentru o descriere mai precis\u0103 a specializ\u0103rii nodurilor clusterului, astfel \u00eenc\u00e2t s\u0103 le putem comanda pentru aplica\u021bii specifice. Astfel, putem ob\u021bine un echilibru optim \u00eentre performan\u021b\u0103 \u0219i cost.<\/p>\n<p>Acum, s\u0103 ne \u00eendrept\u0103m aten\u021bia asupra operatorilor PostgreSQL.<\/p>\n<h3>1. Stolon<\/h3>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/sorintlab\/stolon\">Stolon<\/a><\/noindex> de la compania italian\u0103 Sorint.lab \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">raportul deja men\u021bionat<\/a><\/noindex> a fost considerat un etalon printre operatorii pentru SGBD. Este un proiect destul de vechi: prima sa lansare public\u0103 a avut loc \u00een noiembrie 2015(!), iar repository-ul GitHub se poate l\u0103uda cu aproape 3000 de stele \u0219i 40+ de colaboratori.<\/p>\n<p>\u0218i \u00eentr-adev\u0103r, Stolon este un exemplu excelent de arhitectur\u0103 bine g\u00e2ndit\u0103:<\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/a34625c130bfd29c5645cf2417042de2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDetaliile despre acest operator pot fi g\u0103site \u00een raport sau <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/sorintlab\/stolon\/blob\/master\/doc\/architecture.md\">documenta\u021bia proiectului<\/a><\/noindex>. \u00cen general, este suficient s\u0103 spunem c\u0103 acesta poate face tot ce a fost descris: failover, proxy pentru acces transparent al clien\u021bilor, backup-uri... \u0218i, \u00een plus, proxy-urile ofer\u0103 acces printr-un singur endpoint de serviciu \u2014 spre deosebire de celelalte dou\u0103 solu\u021bii discutate mai departe (care au c\u00e2te dou\u0103 servicii pentru accesul la baz\u0103 de date).<\/p>\n<p>Cu toate acestea, Stolon <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/sorintlab\/stolon\/issues\/463#issuecomment-379666733\">nu are Resurse Personalizate<\/a><\/noindex>, motiv pentru care nu poate fi implementat astfel \u00eenc\u00e2t s\u0103 creeze rapid \u0219i u\u0219or \u2014 \u201eca ni\u0219te pl\u0103cinte calde\u201d \u2014 instan\u021be de SGBD \u00een Kubernetes. Managementul se face prin utilitarul <code>stolonctl<\/code>, implementarea \u2014 prin chart Helm, iar defini\u021biile utilizatorilor sunt specificate \u00een ConfigMap.<\/p>\n<p>Pe de o parte, se pare c\u0103 operatorul nu este chiar un operator (deoarece nu utilizeaz\u0103 CRD). Dar pe de alt\u0103 parte, este un sistem flexibil care permite configurarea resurselor \u00een K8s a\u0219a cum v\u0103 convine.<\/p>\n<p>\u00cen concluzie, personal nu ni s-a p\u0103rut optim s\u0103 avem un chart separat pentru fiecare SGBD. De aceea, am \u00eenceput s\u0103 c\u0103ut\u0103m alternative.<\/p>\n<h3>2. Crunchy Data PostgreSQL Operator<\/h3>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\">Operatorul de la Crunchy Data<\/a><\/noindex>, o t\u00e2n\u0103r\u0103 startup american\u0103, p\u0103rea o alternativ\u0103 logic\u0103. Povestea sa public\u0103 \u00eencepe cu prima lansare din martie 2017, de atunci repository-ul GitHub a ob\u021binut pu\u021bin mai pu\u021bin de 1300 de stele \u0219i 50+ de colaboratori. Ultima lansare din septembrie a fost testat\u0103 pentru a func\u021biona cu Kubernetes 1.15\u20141.18, OpenShift 3.11+ \u0219i 4.4+, GKE \u0219i VMware Enterprise PKS 1.3+.<\/p>\n<p>Arhitectura Crunchy Data PostgreSQL Operator corespunde, de asemenea, cerin\u021belor enun\u021bate:<\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/343cd0494abae42fcf5b47c5bb4eb310.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nManagementul se face prin utilitarul <code>pgo<\/code>, \u00eens\u0103 acesta genereaz\u0103 resurse personalizate pentru Kubernetes. Astfel, ne-a bucurat ca poten\u021biali utilizatori operatorul,<\/p>\n<ul>\n<li> exist\u0103 gestionare prin CRD;<\/li>\n<li> gestionare convenabil\u0103 a utilizatorilor (tot prin CRD);<\/li>\n<li> integrare cu alte componente <noindex><a rel=\"nofollow\" href=\"https:\/\/access.crunchydata.com\/documentation\/crunchy-postgres-containers\/4.3.1\/\">Crunchy Data Container Suite<\/a><\/noindex> \u2014 o colec\u021bie specializat\u0103 de imagini de containere pentru PostgreSQL \u0219i utilitare pentru lucrul cu aceasta (inclusiv pgBackRest, pgAudit, extensii din contrib etc.).<\/li>\n<\/ul>\n<p>\nCu toate acestea, \u00eencerc\u0103rile de a \u00eencepe utilizarea operatorului de la Crunchy Data au scos la iveal\u0103 c\u00e2teva probleme:<\/p>\n<ul>\n<li>Nu a existat op\u021biunea de tolera\u021bii \u2014 a fost prev\u0103zut doar nodeSelector.<\/li>\n<li>Pod-urile create au fost parte a Deployment-ului, de\u0219i am desf\u0103\u0219urat o aplica\u021bie stateful. Spre deosebire de StatefulSet, Deployment-urile nu pot crea discuri.<\/li>\n<\/ul>\n<p>\nUltima deficien\u021b\u0103 duce la momente amuzante: \u00een mediu de testare, am reu\u0219it s\u0103 lans\u0103m 3 replici cu un singur disc <i>stocare local\u0103<\/i>, rezultat \u00een care operatorul raporta c\u0103 3 replici func\u021bioneaz\u0103 (de\u0219i nu era a\u0219a).<\/p>\n<p>O alt\u0103 caracteristic\u0103 a acestui operator este integrarea sa gata f\u0103cut\u0103 cu diferite sisteme auxiliare. De exemplu, este u\u0219or de instalat pgAdmin \u0219i pgBounce, iar <noindex><a rel=\"nofollow\" href=\"https:\/\/access.crunchydata.com\/documentation\/postgres-operator\/4.4.0\/installation\/other\/ansible\/installing-metrics\/\">documentation<\/a><\/noindex> se iau \u00een considerare Grafana \u0219i Prometheus pre-configurate. \u00cen recentul <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\/releases\/tag\/v4.5.0-beta.1\">release 4.5.0-beta1<\/a><\/noindex> se remarc\u0103 integrarea \u00eembun\u0103t\u0103\u021bit\u0103 cu proiectul <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/pgmonitor\">pgMonitor<\/a><\/noindex>, ceea ce permite operatorului s\u0103 ofere o vizualizare clar\u0103 a metricelor PgSQL \u201edin cutie\u201d.<\/p>\n<p>Cu toate acestea, alegerea ciudat\u0103 a resurselor Kubernetes generate ne-a determinat s\u0103 c\u0103ut\u0103m o alt\u0103 solu\u021bie.<\/p>\n<h3>3. Zalando Postgres Operator<\/h3>\n<p>\nProdusele Zalando ne sunt cunoscute de mult: avem experien\u021b\u0103 cu Zalenium \u0219i, desigur, am \u00eencercat <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\">Patroni<\/a><\/noindex> \u2014 solu\u021bia lor popular\u0103 HA pentru PostgreSQL. Despre abordarea companiei \u00een crearea <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">Postgres Operator<\/a><\/noindex> a povestit unul dintre autorii s\u0103i \u2014 Alexey Klyukin \u2014 \u00een emisiunea <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/479438\/\">Postgres Tuesday nr. 5<\/a><\/noindex>, \u0219i ne-a pl\u0103cut.<\/p>\n<p>Aceasta este cea mai t\u00e2n\u0103r\u0103 solu\u021bie dintre cele discutate \u00een articol: primul release a avut loc \u00een august 2018. Cu toate acestea, chiar \u0219i \u00een ciuda num\u0103rului mic de release-uri formale, proiectul a parcurs un drum lung, dep\u0103\u0219ind deja solu\u021bia de la Crunchy Data cu peste 1300 de stele pe GitHub \u0219i cel mai mare num\u0103r de contribuabili (peste 70).<\/p>\n<p>\u201eSub capot\u0103\u201d, acest operator utilizeaz\u0103 solu\u021bii verificate \u00een timp:<\/p>\n<ul>\n<li> Patroni \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/spilo\">Spilo<\/a><\/noindex> pentru gestionare,<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">WAL-E<\/a><\/noindex> \u2014 pentru backup-uri,<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgbouncer\/pgbouncer\">PgBouncer<\/a><\/noindex> \u2014 ca pool de conexiuni.<\/li>\n<\/ul>\n<p>\nIat\u0103 cum este prezentat\u0103 arhitectura operatorului de la Zalando:<\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/c66f10c1a818592ecaacd2db4ce5ace5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOperatorul este gestionat complet prin Custom Resources, cre\u00e2nd automat un StatefulSet din containere, care pot fi apoi personalizate prin ad\u0103ugarea de sidecar-uri diverse \u00een poduri. Toate acestea reprezint\u0103 un avantaj semnificativ \u00een compara\u021bie cu operatorul de la Crunchy Data.<\/p>\n<p>Deoarece solu\u021bia oferit\u0103 de Zalando a fost aleas\u0103 dintre cele 3 variante analizate, descrierea ulterioar\u0103 a func\u021bionalit\u0103\u021bilor sale va fi prezentat\u0103 mai jos, \u00eempreun\u0103 cu practica aplic\u0103rii acesteia.<\/p>\n<h2>Practica cu Postgres Operator de la Zalando<\/h2>\n<p>\nImplementarea operatorului se face foarte simplu: este suficient s\u0103 desc\u0103rca\u021bi cea mai recent\u0103 versiune de pe GitHub \u0219i s\u0103 aplica\u021bi fi\u0219ierele YAML din directorul corespunz\u0103tor. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/tree\/master\/manifests\">manifests<\/a><\/noindex>Ca o op\u021biune, se poate utiliza de asemenea <noindex><a rel=\"nofollow\" href=\"https:\/\/operatorhub.io\/operator\/postgres-operator\">OperatorHub<\/a><\/noindex>.<\/p>\n<p>Dup\u0103 instalare, trebuie s\u0103 v\u0103 ocupa\u021bi de configurarea <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/docs\/reference\/operator_parameters.md#aws-or-gcp-interaction\">stocurilor pentru jurnale \u0219i backup-uri<\/a><\/noindex>. Aceasta se realizeaz\u0103 prin ConfigMap <code>postgres-operator<\/code> \u00een spa\u021biul de nume unde a fost instalat operatorul. Odat\u0103 ce stocurile sunt configurate, pute\u021bi lansa primul cluster PostgreSQL.<\/p>\n<p>De exemplu, implementarea standard arat\u0103 astfel:<\/p>\n<pre><code class=\"plaintext\">apiVersion: acid.zalan.do\/v1\nkind: postgresql\nmetadata:\n name: staging-db\nspec:\n numberOfInstances: 3\n patroni:\n   synchronous_mode: true\n postgresql:\n   version: &quot;12&quot;\n resources:\n   limits:\n     cpu: 100m\n     memory: 1Gi\n   requests:\n     cpu: 100m\n     memory: 1Gi\n sidecars:\n - env:\n   - name: DATA_SOURCE_URI\n     value: 127.0.0.1:5432\n   - name: DATA_SOURCE_PASS\n     valueFrom:\n       secretKeyRef:\n         key: password\n         name: postgres.staging-db.credentials\n   - name: DATA_SOURCE_USER\n     value: postgres\n   image: wrouesnel\/postgres_exporter\n   name: prometheus-exporter\n   resources:\n     limits:\n       cpu: 500m\n       memory: 100Mi\n     requests:\n       cpu: 100m\n       memory: 100Mi\n teamId: staging\n volume:\n   size: 2Gi\n<\/code><\/pre>\n<p>\nAcest manifest implementeaz\u0103 un cluster din 3 instan\u021be cu sidecar sub forma <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wrouesnel\/postgres_exporter\">postgres_exporter<\/a><\/noindex>, de unde colect\u0103m metrici pentru aplica\u021bie. Dup\u0103 cum observa\u021bi, totul este foarte simplu \u0219i, dac\u0103 dori\u021bi, pute\u021bi crea literal un num\u0103r nelimitat de clustere.<\/p>\n<p>Merit\u0103 s\u0103 acorda\u021bi aten\u021bie \u0219i <b>panoului web pentru administrare<\/b> \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/docs\/operator-ui.md\">postgres-operator-ui<\/a><\/noindex>. Acesta vine \u00eempreun\u0103 cu operatorul \u0219i permite crearea \u0219i \u0219tergerea clusterelor, precum \u0219i gestionarea backup-urilor efectuate de operator.<\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/2e9ae033a9817d101c843ce061aafdb5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Lista clusterelor PostgreSQL<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/74a65f7f301da14a0cb7bea6d5ef84ec.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Gestionarea backup-urilor<\/i><\/p>\n<p>O alt\u0103 caracteristic\u0103 interesant\u0103 este suportul pentru <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/docs\/user.md#teams-api-roles\">Teams API<\/a><\/noindex>. Acest mecanism creeaz\u0103 automat <b>roluri \u00een PostgreSQL<\/b>, pe baza listei de nume de utilizatori primite. Dup\u0103 aceea, API-ul permite returnarea listei de utilizatori pentru care rolurile sunt create automat.<\/p>\n<h3>Probleme \u0219i solu\u021bii<\/h3>\n<p>\nCu toate acestea, utilizarea operatorului a scos la iveal\u0103 rapid c\u00e2teva dezavantaje semnificative:<\/p>\n<ol>\n<li> lipsa suportului pentru nodeSelector;<\/li>\n<li> imposibilitatea de a dezactiva backup-urile;<\/li>\n<li> folosind func\u021bia de creare a bazelor, nu apar privilegii implicite;<\/li>\n<li> periodic, documenta\u021bia este insuficient\u0103 sau nu este actualizat\u0103.<\/li>\n<\/ol>\n<p>\nDin fericire, multe dintre acestea pot fi rezolvate. S\u0103 \u00eencepem cu sf\u00e2r\u0219itul \u2014 problemele cu <strong>documenta\u021bia<\/strong>. <\/p>\n<p>Cel mai probabil, v\u0103 ve\u021bi confrunta cu neclaritatea \u00een ceea ce prive\u0219te modul de a defini backup-ul \u0219i cum s\u0103 conecta\u021bi bucket-ul de backup la Operator UI. Despre aceasta, documenta\u021bia men\u021bioneaz\u0103 \u00een treac\u0103t, iar descrierea real\u0103 se g\u0103se\u0219te \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/481\">PR<\/a><\/noindex>:<\/p>\n<ol>\n<li>trebuie s\u0103 crea\u021bi un secret;<\/li>\n<li>s\u0103-l transmite\u021bi operatorului \u00een parametru <code>pod_environment_secret_name<\/code> \u00een CRD cu configura\u021biile operatorului sau \u00een ConfigMap (depinde de modul \u00een care a\u021bi decis s\u0103 instala\u021bi operatorul).<\/li>\n<\/ol>\n<p>\nCu toate acestea, s-a dovedit c\u0103 \u00een prezent acest lucru este imposibil. De aceea am adunat <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/postgres-operator\">versiunea noastr\u0103 a operatorului<\/a><\/noindex> cu anumite dezvolt\u0103ri suplimentare externe. Detalii despre aceasta \u2014 vezi mai jos.<\/p>\n<p>Dac\u0103 transmite\u021bi operatorului parametrii pentru backup, \u0219i anume \u2014 <code>wal_s3_bucket<\/code> \u0219i cheile de acces \u00een AWS S3, atunci el <strong>va face backup la tot<\/strong>: nu doar la bazele din produc\u021bie, ci \u0219i la cele de stagiu. Acest lucru nu ne-a convenit.<\/p>\n<p>\u00cen descrierea parametrilor pentru Spilo, care este wrapper-ul Docker de baz\u0103 pentru PgSQL atunci c\u00e2nd se folose\u0219te operatorul, s-a descoperit c\u0103 se poate transmite parametrul <code>WAL_S3_BUCKET<\/code> gol, astfel dezactiv\u00e2nd backup-urile. Mai mult, spre marele nostru avantaje a fost g\u0103sit un <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/908\">PR gata<\/a><\/noindex>, pe care l-am acceptat imediat \u00een fork-ul nostru. Acum este suficient s\u0103 ad\u0103uga\u021bi <code>enableWALArchiving: false<\/code> \u00een resursa clusterului PostgreSQL.<\/p>\n<p>Da, a existat posibilitatea de a face altfel, pornind 2 operatori: unul pentru stagiu (f\u0103r\u0103 backup-uri) \u0219i cel\u0103lalt \u2014 pentru produc\u021bie. Dar am reu\u0219it s\u0103 ne descurc\u0103m cu unul singur.<\/p>\n<p>Bine, am \u00eenv\u0103\u021bat s\u0103 oferim bazelor acces pentru S3 \u0219i backup-urile au \u00eenceput s\u0103 ajung\u0103 \u00een stocare. Cum s\u0103 facem s\u0103 func\u021bioneze paginile backup-urilor \u00een Operator UI?<\/p>\n<p><img decoding=\"async\" alt=\"Prezentare general\u0103 a operatorilor PostgreSQL pentru Kubernetes, selec\u021bia \u0219i experien\u021ba noastr\u0103\" src=\"\/wp-content\/uploads\/2020\/09\/46169b53707b0bbb686798c655022f40.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00cen Operator UI va trebui s\u0103 ad\u0103uga\u021bi 3 variabile:<\/p>\n<ul>\n<li> <code>SPILO_S3_BACKUP_BUCKET<\/code><\/li>\n<li> <code>AWS_ACCESS_KEY_ID<\/code><\/li>\n<li> <code>AWS_SECRET_ACCESS_KEY<\/code><\/li>\n<\/ul>\n<p>\nDup\u0103 aceasta, gestionarea backup-urilor va deveni disponibil\u0103, ceea ce \u00een cazul nostru va simplifica munca cu stagiu, permi\u021b\u00e2nd livrarea instantaneelor din produc\u021bie f\u0103r\u0103 scripturi suplimentare.<\/p>\n<p>Ca un alt avantaj, s-a men\u021bionat colaborarea cu Teams API \u0219i posibilit\u0103\u021bile extinse pentru a crea baze \u0219i roluri prin intermediul operatorului. Totu\u0219i, rolurile create <strong>nu aveau privilegii implicite<\/strong>. Prin urmare, utilizatorul cu drepturi de citire nu putea citi noile tabele.<\/p>\n<p>De ce a\u0219a? Cu toate c\u0103 \u00een codul <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/pkg\/cluster\/database.go#L42\">are<\/a><\/noindex> necesar <code>GRANT<\/code>, acestea nu sunt aplicate \u00eentotdeauna. Exist\u0103 2 metode: <code>syncPreparedDatabases<\/code> \u0219i <code>syncDatabases<\/code>. \u00cen <code>syncPreparedDatabases<\/code> \u2014 cu toate c\u0103 \u00een sec\u021biunea <code>preparedDatabases<\/code> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/blob\/master\/manifests\/complete-postgres-manifest.yaml#L26\">are<\/a><\/noindex> exist\u0103 o condi\u021bie <code>defaultRoles<\/code> \u0219i <code>defaultUsers<\/code> pentru crearea rolurilor, \u2014 permisiunile implicite nu se aplic\u0103. Suntem \u00een proces de preg\u0103tire a unui patch, astfel \u00eenc\u00e2t aceste permisiuni s\u0103 fie aplicate automat.<\/p>\n<p>\u0218i ultimul aspect \u00een actualiz\u0103rile relevante pentru noi \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/975\">patch<\/a><\/noindex>, ad\u0103ug\u00e2nd Node Affinity \u00een StatefulSet-ul creat. Clien\u021bii no\u0219tri prefer\u0103 adesea s\u0103 economiseasc\u0103 costurile folosind instan\u021be spot, iar pe acestea nu ar trebui s\u0103 se plaseze servicii de baze de date. Aceast\u0103 problem\u0103 ar putea fi rezolvat\u0103 \u0219i prin tolera\u021bii, dar prezen\u021ba Node Affinity ofer\u0103 o mai mare siguran\u021b\u0103.<\/p>\n<h3>Ce a ie\u0219it?<\/h3>\n<p>\nCa urmare a solu\u021bion\u0103rii problemelor enumerate, am fork-uit Postgres Operator de la Zalando \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/postgres-operator\">repozitoriu nostru<\/a><\/noindex>, unde acesta este construit cu patch-uri at\u00e2t de utile. Iar pentru un plus de confort, am str\u00e2ns \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/flant\/postgres-operator\">o imagine Docker<\/a><\/noindex>.<\/p>\n<p>Lista PR-urilor acceptate \u00een fork:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/1066\">construirea unei imagini Docker sigure \u0219i u\u0219oare pentru operator<\/a><\/noindex>;<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/908\">dezactivarea backup-urilor<\/a><\/noindex>;<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/1121\">actualizarea versiunilor resurselor pentru versiunile actuale de k8s<\/a><\/noindex>;<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\/pull\/975\">implementarea Node Affinity<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>\nAr fi grozav dac\u0103 comunitatea ar sus\u021bine aceste PR-uri, astfel \u00eenc\u00e2t s\u0103 ajung\u0103 \u00een upstream cu urm\u0103toarea versiune a operatorului (1.6).<\/p>\n<h2>Bonus! Poveste de succes cu migrarea production<\/h2>\n<p>\nDac\u0103 utiliza\u021bi Patroni, este posibil s\u0103 migra\u021bi production live pe operator cu un timp minim de nefunc\u021bionare.<\/p>\n<p>Spilo permite crearea de clustere standby prin stoc\u0103ri S3 cu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/wal-e\/wal-e\">Wal-E<\/a><\/noindex>, c\u00e2nd log-ul binar PgSQL este mai \u00eent\u00e2i salvat \u00een S3, iar apoi este desc\u0103rcat de replica. Dar ce s\u0103 face\u021bi dac\u0103 <i>nu<\/i> folosi\u021bi Wal-E \u00een infrastructura veche? Solu\u021bia la aceast\u0103 problem\u0103 a fost deja <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/true_engineering\/blog\/437318\/\">propus\u0103<\/a><\/noindex> pe Habr.<\/p>\n<p>Ajutorul vine de la replicarea logic\u0103 PostgreSQL. Totu\u0219i, nu ne vom ad\u00e2nci \u00een detalii despre cum s\u0103 cre\u0103m publica\u021bii \u0219i \u00eenscrieri, deoarece\u2026 planul nostru a e\u0219uat.<\/p>\n<p>Problema este c\u0103 \u00een baza de date existau mai multe tabele \u00eenc\u0103rcate cu milioane de r\u00e2nduri, care, \u00een plus, erau continuu populate \u0219i \u0219terse. <noindex><a rel=\"nofollow\" href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/12\/sql-createsubscription\">O simpl\u0103 \u00eenscriere<\/a><\/noindex> de <code>copy_data<\/code>, c\u00e2nd o nou\u0103 replic\u0103 copiaz\u0103 tot con\u021binutul de pe master, pur \u0219i simplu nu reu\u0219ea s\u0103 \u021bin\u0103 pasul cu master-ul. Copierea con\u021binutului a func\u021bionat o s\u0103pt\u0103m\u00e2n\u0103, dar nu a ajuns niciodat\u0103 la master. \u00cen cele din urm\u0103, am reu\u0219it s\u0103 rezolv\u0103m problema cu ajutorul <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/avitotech\/recovery-use-cases-for-logical-replication-in-postgresql-10-a1e6bab03072\">articol<\/a><\/noindex> colegilor de la Avito: putem muta datele folosind <code>pg_dump<\/code>. Voi descrie varianta noastr\u0103 (u\u0219or \u00eembun\u0103t\u0103\u021bit\u0103) a acestui algoritm.<\/p>\n<p>Ideea este c\u0103 se poate face o subscrip\u021bie oprit\u0103, legat\u0103 de un anumit slot de replicare, \u0219i apoi se poate corecta num\u0103rul de tranzac\u021bie. Exista replici disponibile pentru a lucra cu produc\u021bia. Acest lucru este important deoarece replica va ajuta la crearea unui dump consistent \u0219i va continua s\u0103 primeasc\u0103 modific\u0103ri din master.<\/p>\n<p>\u00cen comenzile ulterioare care descriu procesul de migrare, vor fi folosite urm\u0103toarele denumiri pentru gazde:<\/p>\n<ol>\n<li><i>master<\/i> \u2014 serverul surs\u0103;<\/li>\n<li><i>replica1<\/i> \u2014 replica streaming pe vechea produc\u021bie;<\/li>\n<li><i>replica2<\/i> \u2014 noua replic\u0103 logic\u0103.<\/li>\n<\/ol>\n<p><\/p>\n<h3>Planul de migra\u021bie<\/h3>\n<p>\n1. Vom crea pe master o subscrip\u021bie pentru toate tabelele din schema <code>public<\/code> bazei <code>dbname<\/code>:<\/p>\n<pre><code class=\"bash\">psql -h master -d dbname -c &quot;CREATE PUBLICATION dbname FOR ALL TABLES;&quot;\n<\/code><\/pre>\n<p>\n2. Vom crea un slot de replicare pe master:<\/p>\n<pre><code class=\"bash\">psql -h master -c &quot;select pg_create_logical_replication_slot('repl', 'pgoutput');&quot;\n<\/code><\/pre>\n<p>\n3. Vom opri replicarea pe vechea replic\u0103:<\/p>\n<pre><code class=\"bash\">psql -h replica1 -c &quot;select pg_wal_replay_pause();&quot;\n<\/code><\/pre>\n<p>\n4. Vom ob\u021bine num\u0103rul de tranzac\u021bie de la master:<\/p>\n<pre><code class=\"bash\">psql -h master -c &quot;select replay_lsn from pg_stat_replication where client_addr = 'replica1';&quot;\n<\/code><\/pre>\n<p>\n5. Vom face un dump de pe vechea replic\u0103. Vom face acest lucru \u00een mai multe fire, ceea ce va ajuta la accelerarea procesului:<\/p>\n<pre><code class=\"bash\">pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump\/ dbname\n<\/code><\/pre>\n<p>\n6. Vom \u00eenc\u0103rca dump-ul pe noul server:<\/p>\n<pre><code class=\"bash\">pg_restore -h replica2 -F d -j 8 -d dbname dump\/\n<\/code><\/pre>\n<p>\n7. Dup\u0103 \u00eenc\u0103rcarea dump-ului, putem \u00eencepe replicarea pe replica streaming:<\/p>\n<pre><code class=\"bash\">psql -h replica1 -c &quot;select pg_wal_replay_resume();&quot;\n<\/code><\/pre>\n<p>\n8. Vom crea o subscrip\u021bie pe noua replic\u0103 logic\u0103:<\/p>\n<pre><code class=\"bash\">psql -h replica2 -c &quot;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');&quot;\n<\/code><\/pre>\n<p>\n9. Vom ob\u021bine <code>oid<\/code> subscrip\u021biei:<\/p>\n<pre><code class=\"bash\">psql -h replica2 -d dbname -c &quot;select oid, * from pg_subscription;&quot;\n<\/code><\/pre>\n<p>\n10. S\u0103 presupunem c\u0103 am ob\u021binut <code>oid=1000<\/code>. Vom aplica num\u0103rul de tranzac\u021bie la subscrip\u021bie:<\/p>\n<pre><code class=\"bash\">psql -h replica2 -d dbname -c &quot;select pg_replication_origin_advance('pg_1000', 'AA\/AAAAAAAA');&quot;\n<\/code><\/pre>\n<p>\n11. Vom porni replicarea:<\/p>\n<pre><code class=\"bash\">psql -h replica2 -d dbname -c &quot;alter subscription oldprod enable;&quot;\n<\/code><\/pre>\n<p>\n12. Vom verifica statutul subscrip\u021biei, replicarea ar trebui s\u0103 func\u021bioneze:<\/p>\n<pre><code class=\"bash\">psql -h replica2 -d dbname -c &quot;select * from pg_replication_origin_status;&quot;\npsql -h master -d dbname -c &quot;select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;&quot;\n<\/code><\/pre>\n<p>\n13. Dup\u0103 ce replicarea este pornit\u0103 \u0219i bazele sunt sincronizate, se poate face switch.<\/p>\n<p>14. Dup\u0103 oprirea replic\u0103rii, trebuie corectate secven\u021bele. Acest lucru este bine descris <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Fixing_Sequences\">\u00een articolul de pe wiki.postgresql.org<\/a><\/noindex>.<\/p>\n<p>Datorit\u0103 acestui plan, switch-ul s-a realizat cu \u00eent\u00e2rzieri minime.<\/p>\n<h2>Concluzie<\/h2>\n<p>\nOperatorii Kubernetes simplific\u0103 diverse ac\u021biuni, reduc\u00e2ndu-le la creare de resurse K8s. Totu\u0219i, dup\u0103 ce a\u021bi realizat o automatizare remarcabil\u0103 cu ajutorul lor, este important s\u0103 re\u021bine\u021bi c\u0103 aceasta poate aduce \u0219i o serie de nuan\u021be nea\u0219teptate, a\u0219a c\u0103 aborda\u021bi alegerea operatorilor cu \u00een\u021belepciune.<\/p>\n<p>Dup\u0103 ce am analizat trei dintre cei mai populari operatori Kubernetes pentru PostgreSQL, ne-am decis \u00een favoarea proiectului de la Zalando. Am \u00eent\u00e2mpinat anumite dificult\u0103\u021bi \u00een acest proces, dar rezultatul ne-a bucurat realmente, a\u0219a c\u0103 pl\u0103nuim s\u0103 extindem aceast\u0103 experien\u021b\u0103 \u0219i la alte instal\u0103ri PgSQL. Dac\u0103 ave\u021bi experien\u021b\u0103 cu solu\u021bii similare, ne-ar face pl\u0103cere s\u0103 vedem detalii \u00een comentarii!<\/p>\n<h2>P.S.<\/h2>\n<p>\nCiti\u021bi \u0219i \u00een blogul nostru:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Baze de date \u0219i Kubernetes (prezentare general\u0103 \u0219i videoclip al expunerii)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/479438\/\">Postgres-mar\u021bi nr. 5: PostgreSQL \u0219i Kubernetes. CI\/CD. Automatizarea test\u0103rii.<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/480722\/\">O poveste despre operatorul Redis \u00een K8s \u0219i un mic rezumat al utilitarilor pentru analizarea datelor acestei baze de date<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/520616\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0451 \u0447\u0430\u0449\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b: \u00ab\u0425\u043e\u0442\u0438\u043c \u043a\u0430\u043a Amazon RDS, \u043d\u043e \u0434\u0435\u0448\u0435\u0432\u043b\u0435\u00bb; \u00ab\u0425\u043e\u0442\u0438\u043c \u043a\u0430\u043a RDS, \u043d\u043e \u0432\u0435\u0437\u0434\u0435, \u0432 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435\u00bb. \u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435 managed-\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 Kubernetes, \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f PostgreSQL (Stolon, \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043e\u0442 Crunchy Data \u0438 Zalando) \u0438 \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0441\u0432\u043e\u0439 \u0432\u044b\u0431\u043e\u0440. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u043c\u0438 \u043e\u043f\u044b\u0442 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":95323,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-95322","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.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0451 \u0447\u0430\u0449\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.\" \/>\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\/ro\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\udd47\u041a\u0440\u0430\u0442\u043a\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 PostgreSQL \u0434\u043b\u044f Kubernetes, \u043d\u0430\u0448 \u0432\u044b\u0431\u043e\u0440 \u0438 \u043e\u043f\u044b\u0442 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0451 \u0447\u0430\u0449\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt\" \/>\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-09-28T05:42:39+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-09-28T05:42:39+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\udd47Rezumat scurt al operatorilor PostgreSQL pentru Kubernetes, alegerea noastr\u0103 \u0219i experien\u021ba | ProHoster","description":"Din ce \u00een ce mai frecvent, din partea clien\u021bilor.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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\udd47\u041a\u0440\u0430\u0442\u043a\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 PostgreSQL \u0434\u043b\u044f Kubernetes, \u043d\u0430\u0448 \u0432\u044b\u0431\u043e\u0440 \u0438 \u043e\u043f\u044b\u0442 | ProHoster","og:description":"\u0412\u0441\u0451 \u0447\u0430\u0449\u0435 \u043e\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kratkij-obzor-operatorov-postgresql-dlya-kubernetes-nash-vybor-i-opyt","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-09-28T05:42:39+00:00","article:modified_time":"2020-09-28T05:42:39+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"95322","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 11:08:22","updated":"2022-09-30 21:12:08","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/95322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=95322"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/95322\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/95323"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=95322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=95322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=95322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}