{"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\/it\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","title":{"rendered":"Postgres marted\u00ec n. 5: \u00abPostgreSQL e Kubernetes. CI\/CD. Automazione dei test\u00bb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Postgres marted\u00ec n. 5: \u00abPostgreSQL e Kubernetes. CI\/CD. Automazione dei test\u00bb\" src=\"\/wp-content\/uploads\/2020\/01\/5eb8dd2afa4cab58a7359b305814d77f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlla fine dello scorso anno si \u00e8 svolta una nuova diretta della comunit\u00e0 russa di PostgreSQL <noindex><a rel=\"nofollow\" href=\"https:\/\/www.meetup.com\/postgresqlrussia\/\">#RuPostgres<\/a><\/noindex>, durante la quale il suo cofondatore Nikolai Samokhvalov ha parlato con il CTO di \"Flanta\" Dmitry Stolyarov riguardo a questo DBMS nel contesto di Kubernetes.<\/p>\n<p>Pubblicamo la trascrizione della parte principale di questa discussione, e su <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/channel\/UC0SBGSNmBLrTZIkbN-lJHnw\">YouTube-\u043a\u0430\u043d\u0430\u043b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430<\/a><\/noindex> \u00e8 disponibile la registrazione video completa:<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=\"Riproduci video\" 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>Database e Kubernetes<\/h2>\n<p>\n<i><b>\u041d\u0421<\/b>: Oggi non parleremo di VACUUM e CHECKPOINT. Vogliamo discutere di Kubernetes. So che hai gi\u00e0 molti anni di esperienza. Ho visto i tuoi video e ne ho rivisti alcuni anche a pezzi\u2026 Passiamo subito al sodo: perch\u00e9 Postgres o MySQL in K8s?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non c'\u00e8 una risposta definitiva a questa domanda e non pu\u00f2 esserci. Ma in generale, si tratta di semplicit\u00e0 e convenienza\u2026 potenziali. A tutti piace il managed service.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Per averlo come <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/rds\/\">RDS<\/a><\/noindex>, solo che da soli?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: S\u00ec: per averlo come RDS, ma ovunque.<\/p>\n<p><i><b>\u041d\u0421<\/b>: \"Ovunque\" \u2014 \u00e8 un'osservazione interessante. Nelle grandi aziende tutto \u00e8 situato in posti diversi. E perch\u00e9, allora, se si tratta di una grande azienda, non adottare una soluzione pronta? Ad esempio, Nutanix ha le proprie soluzioni, altre aziende (VMware\u2026) hanno il loro \"RDS, solo da noi\".<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ma stiamo parlando di una specifica implementazione che funzioner\u00e0 solo in determinate condizioni. Se parliamo di Kubernetes, esiste una grande variet\u00e0 di infrastrutture (che possono trovarsi in K8s). Fondamentalmente \u00e8 uno standard per l'API al cloud\u2026<\/p>\n<p><i><b>\u041d\u0421<\/b>: Inoltre, \u00e8 gratuito!<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non \u00e8 cos\u00ec importante. La gratuit\u00e0 \u00e8 rilevante per un segmento di mercato piuttosto ridotto. Ci\u00f2 che conta \u00e8 un'altra cosa\u2026 Probabilmente ti ricordi della mia presentazione \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Database e Kubernetes<\/a><\/noindex>\u00bb?<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ho capito che \u00e8 stata ricevuta in modo molto controverso. Parte delle persone ha pensato che dicessi: \"Ragazzi, via con tutti i DB in Kubernetes!\", mentre altri hanno deciso che si trattava solo di biciclette terribili. Ma io volevo dire altro: \"Guardate cosa sta succedendo, quali sono i problemi e come possono essere risolti. \u00c8 opportuno portare i database in Kubernetes adesso? In produzione? Solo se vi piace\u2026 occuparvi di certe cose. Per il dev invece, posso dire che lo raccomando. Per il dev \u00e8 molto importante la dinamicit\u00e0 nella creazione\/cancellazione degli ambienti.<\/p>\n<p><i>\u041d\u0421: Con dev intendi tutti gli ambienti che non sono prod? Staging, QA\u2026<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Se parliamo di perf-stand, allora probabilmente no, perch\u00e9 l\u00ec i requisiti sono specifici. Se parliamo di casi particolari dove in staging \u00e8 necessaria un'ampia DB, allora anche probabilmente no\u2026 Se \u00e8 un ambiente statico, a lungo termine, quale vantaggio ci sarebbe nell'avere il database in K8s?<\/p>\n<p><i><b>\u041d\u0421<\/b>: Nessuno. Ma dove vediamo ambienti statici? L'ambiente statico diventa obsoleto gi\u00e0 il giorno dopo.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Lo staging pu\u00f2 essere statico. Abbiamo clienti\u2026<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec, anch'io ho. \u00c8 un grosso problema, se hai un database di 10 TB e lo staging \u00e8 di 200 GB\u2026<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ho un caso molto interessante! In staging c'\u00e8 un database di produzione, al quale si apportano modifiche. E c'\u00e8 un pulsante: \"rilascialo in produzione\". Queste modifiche \u2014 delta \u2014 vengono aggiunte (sembra, semplicemente sincronizzate tramite API) alla produzione. \u00c8 un'opzione molto esotica.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Ho visto startup nella Valle che stanno ancora in RDS o anche in Heroku \u2014 sono storie di 2-3 anni fa \u2014 e scaricano il dump sui loro laptop. Perch\u00e9 il database \u00e8 solo di 80 GB e c'\u00e8 spazio sul laptop. Poi acquistano dischi per ciascuno, per avere 3 database e portare avanti sviluppi diversi. Succede anche cos\u00ec. Ho anche visto che non hanno paura di copiare la produzione in staging \u2014 dipende molto dall'azienda. Ma ho anche visto che hanno paura, e spesso non hanno tempo e personale. Ma prima di passare a questo argomento, vorrei sapere di Kubernetes. Ho capito bene che in produzione non ce l'ha nessuno?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Abbiamo piccoli database in produzione. Si parla di volumi nell'ordine di decine di gigabyte e servizi non critici, per i quali era noioso fare repliche (e non c'era neanche tanta necessit\u00e0). E a condizione che ci sia uno storage adeguato per Kubernetes. Questo database funzionava in una macchina virtuale \u2014 condizionalmente in VMware, su un SAN. Lo abbiamo trasferito in <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\">PV<\/a><\/noindex> e ora possiamo spostarlo da macchina a macchina.<\/p>\n<p><i><b>\u041d\u0421<\/b>: I database di quella dimensione, fino a 100 GB, su dischi buoni e con una buona rete possono essere distribuiti in pochi minuti, giusto? La velocit\u00e0 di 1 Gb al secondo non \u00e8 pi\u00f9 un'eccezione.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: S\u00ec, per operazioni lineari non \u00e8 un problema.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Ok, riguardo a produzione dobbiamo solo pensarci. E se consideriamo Kubernetes per ambienti non-prod \u2014 come procedere? Vedo che in Zalando <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">fanno un operatore<\/a><\/noindex>, in Crunchy <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\">stanno sviluppando<\/a><\/noindex>, ci sono altre opzioni. E c'\u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/ongres.com\/\">OnGres<\/a><\/noindex> \u2014 \u00e8 il nostro buon amico Alvaro dalla Spagna: non fanno solo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/326414\/\">operatore<\/a><\/noindex>, ma un intero distributore (<noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/ongresinc\/stackgres\">StackGres<\/a><\/noindex>), in cui oltre a PostgreSQL hanno deciso di includere anche il backup, il proxy Envoy\u2026<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: A cosa serve Envoy? Per bilanciare proprio il traffico di PostgreSQL?<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec. Cio\u00e8, lo vedono in questo modo: se prendi una distribuzione Linux e il kernel, il PostgreSQL normale \u00e8 il kernel, mentre loro vogliono creare una distribuzione che sia amichevole per il cloud e possa girare in Kubernetes. Collegano i componenti (backup e simili) e li ottimizzano affinch\u00e9 funzionino bene.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ottimo! Fondamentalmente, \u00e8 un software per creare il proprio PostgreSQL gestito.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Le distribuzioni Linux hanno sempre problemi: come fare i driver per supportare tutto l'hardware. La loro idea \u00e8 che lavoreranno in Kubernetes. So che con l'operatore di Zalando abbiamo recentemente visto un legame con AWS, e questo non \u00e8 molto positivo. Non dovrebbe esserci un legame con un'infrastruttura specifica - qual \u00e8 il senso allora?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non so in quale situazione specifica Zalando si sia legato, ma al momento in Kubernetes lo storage \u00e8 realizzato in modo tale che non \u00e8 possibile fare un backup del disco in modo generico. Recentemente, nello standard - nell'ultima versione - <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465417\/\">specifiche CSI<\/a><\/noindex> \u00e8 stata aggiunta la possibilit\u00e0 di snapshot, ma dove \u00e8 stata implementata? Onestamente, \u00e8 ancora tutto cos\u00ec grezzo\u2026 Proviamo CSI su AWS, GCE, Azure, vSphere, ma iniziamo a usare e si vede che non \u00e8 ancora pronto.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Ecco perch\u00e9 a volte ci si deve legare all'infrastruttura. Penso che sia ancora una fase iniziale - problemi di crescita. Domanda: cosa consiglieresti ai principianti che vogliono provare PgSQL in K8s? Quale operatore, forse?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Il problema \u00e8 che Postgres per noi \u00e8 solo il 3%. Abbiamo ancora un lungo elenco di vari software in Kubernetes, non voglio nemmeno elencarli tutti. Ad esempio, Elasticsearch. Ci sono molti operatori: alcuni si sviluppano attivamente, altri no. Abbiamo definito dei requisiti che devono sussistere in un operatore affinch\u00e9 lo prendiamo sul serio. In un operatore specifico per Kubernetes \u2014 non nell'\u00aboperatore per fare qualcosa in Amazon\u00bb... Di fatto, utilizziamo piuttosto largamente (= quasi tutti i clienti) un solo operatore \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spotahome\/redis-operator\">per Redis<\/a><\/noindex> <i>(pubblicheremo presto anche un articolo su di esso)<\/i>.<\/p>\n<p><i><b>\u041d\u0421<\/b>: E per MySQL non c'\u00e8 nulla? So che Percona... dato che ora si occupano sia di MySQL, sia di MongoDB, sia di Postgres, dovrebbero realizzare qualcosa di universale: per tutti i database, per tutti i provider di cloud.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non abbiamo avuto il tempo di guardare gli operatori per MySQL. Per noi non \u00e8 attualmente una priorit\u00e0. MySQL funziona bene in standalone. Perch\u00e9 usare un operatore, se puoi semplicemente avviare il database... Puoi avviare un contenitore Docker con Postgres, oppure farlo in modo semplice.<\/p>\n<p><i><b>\u041d\u0421<\/b>: C'era anche questa domanda. Completamente senza operatore?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: S\u00ec, al 100% abbiamo PostgreSQL avviato senza operatore. Finora \u00e8 cos\u00ec. Utilizziamo attivamente l'operatore per Prometheus, per Redis. Abbiamo piani per trovare un operatore per Elasticsearch - \u00e8 quello che 'brucia' di pi\u00f9, perch\u00e9 vogliamo installarlo nel 100% dei casi in Kubernetes. Cos\u00ec come vogliamo arrivare a installare MongoDB sempre in Kubernetes. Ci sono certe esigenze che si presentano - c'\u00e8 la sensazione che in questi casi si possa fare qualcosa. Ma per Postgres non abbiamo nemmeno guardato. Certo, sappiamo della esistenza di varie opzioni, ma in effetti abbiamo standalone.<\/p>\n<h2>Database per test in Kubernetes<\/h2>\n<p>\n<i><b>\u041d\u0421<\/b>: Passiamo al tema del testing. Come gestire le modifiche nel database - dal punto di vista della prospettiva DevOps. Ci sono microservizi, molti database, in continuazione ci sono cambiamenti. Come garantire un CI\/CD normale, affinch\u00e9 dal punto di vista del DB tutto sia a posto. Qual \u00e8 il tuo approccio?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non pu\u00f2 esserci una risposta unica. Ci sono diversi parametri. Il primo \u00e8 la dimensione del database che desideriamo distribuire. Hai gi\u00e0 accennato che le aziende trattano in modo diverso il fatto di avere una copia del database di produzione su dev e stage.<\/p>\n<p><i><b>\u041d\u0421<\/b>: E in ottica GDPR, penso che stiano diventando sempre pi\u00f9 cauti... Posso dire che in Europa hanno gi\u00e0 iniziato a multare.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ma spesso \u00e8 possibile scrivere un software che effettua un dump da production e lo obfuscates. Si ottengono dati di produzione (snapshot, dump, copia binaria...), ma sono anonimizzati. In alternativa, possono esserci degli script di generazione: possono essere fixture o semplicemente uno script che genera un ampio database. Qual \u00e8 il problema: quanto tempo ci vuole per creare un'immagine di base? E quanto tempo occorre per distribuirla nell'ambiente desiderato?<\/p>\n<p>Siamo arrivati a uno schema: se il cliente ha un set di dati di fixture (versione minima del database), allora di default li usiamo. Se parliamo di ambienti di revisione, quando abbiamo creato un branch, abbiamo distribuito un'istanza dell'app - l\u00ec distribuiamo un piccolo database. Ma \u00e8 andata bene anche <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/417509\/\">una variante<\/a><\/noindex>, quando una volta al giorno (di notte) prendiamo un dump da production e creiamo un container Docker con PostgreSQL e MySQL con questi dati caricati. Se da quest'immagine \u00e8 necessario distribuire il database 50 volte, ci\u00f2 si realizza in modo abbastanza semplice e veloce.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Copiando semplicemente?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: I dati sono memorizzati direttamente nell'immagine Docker. Cio\u00e8, abbiamo un'immagine pronta, magari di 100 GB. Grazie ai layer in Docker, possiamo distribuire rapidamente questa immagine il numero di volte necessario. \u00c8 un metodo semplice, ma funziona piuttosto bene.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Poi, quando testate, cambia proprio all'interno di Docker, vero? Il copy-on-write all'interno di Docker \u2014 scartiamo e ricominciamo, tutto bene. Fantastico! E gi\u00e0 lo state usando intensamente?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Da un po'.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Ci occupiamo di cose molto simili. Solo che non utilizziamo il copy-on-write di Docker, ma un altro sistema.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non \u00e8 generico. Quello di Docker funziona ovunque.<\/p>\n<p><i><b>\u041d\u0421<\/b>: In teoria, s\u00ec. Ma anche noi abbiamo dei moduli, possiamo crearne diversi e lavorare con vari sistemi di file. Qui c'\u00e8 un punto. Noi guardiamo tutto questo da una prospettiva di Postgres. Ora ho guardato dalla prospettiva di Docker e ho visto che tutto funziona. Ma se il database \u00e8 enorme, ad esempio di 1 TB, allora tutto diventa lento: sia le operazioni notturne, sia il trasferimento di tutto in Docker... E se dobbiamo trasferire 5 TB in Docker... O tutto va bene?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Qual \u00e8 la differenza: lo state facendo tramite dump e restore?<\/p>\n<p><i><b>\u041d\u0421<\/b>: Non \u00e8 affatto necessario. I modi per generare questa immagine possono essere diversi.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Per alcuni clienti abbiamo fatto in modo che, invece di generare regolarmente l'immagine di base, la mantenessimo sempre aggiornata. \u00c8 sostanzialmente una replica, ma i dati non vengono ottenuti direttamente dal master, bens\u00ec tramite un archivio. Un archivio binario, dove i WAL vengono aggiornati ogni giorno, e l\u00ec vengono anche eseguiti i backup... Questi WAL poi arrivano \u2014 con un piccolo ritardo (solo 1-2 secondi) \u2014 all'immagine di base. Da essa cloniamo in qualsiasi modo \u2014 attualmente usiamo ZFS come default.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Per alcuni clienti abbiamo creato una soluzione tale che, invece di generare regolarmente un'immagine di base, la manteniamo costantemente aggiornata. Essa \u00e8 praticamente una replica, ma i dati non vengono ricevuti direttamente dal master, bens\u00ec attraverso un archivio. Un archivio binario, dove i WAL vengono accumulati ogni giorno, e vengono anche effettuati backup... Questi WAL vengono poi trasferiti \u2014 con un piccolo ritardo (letteralmente 1-2 secondi) \u2014 all'immagine di base. Da essa possiamo clonare in qualsiasi modo \u2014 ora come impostazione predefinita utilizziamo ZFS.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ma con ZFS sei limitato a un solo nodo.<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec. Ma ZFS ha anche un magico <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/cd\/E18752_01\/html\/819-5461\/gbchx.html\">send<\/a><\/noindex>: con cui puoi inviare uno snapshot e persino (questo non l'ho ancora testato molto bene, ma...) puoi inviare la delta tra due <code>PGDATA<\/code>. Infatti, abbiamo anche un altro strumento che non abbiamo considerato molto per tali compiti. In PostgreSQL c'\u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/app-pgrewind.html\">pg_rewind<\/a><\/noindex>, che funziona come un rsync 'intelligente', saltando molte cose che non \u00e8 necessario controllare, perch\u00e9 non sono certamente cambiate. Possiamo fare una sincronizzazione rapida tra due server e ripristinare allo stesso modo.<\/i><\/p>\n<p><i>Ecco, cerchiamo di realizzare uno strumento da questo lato pi\u00f9 da DBA che permette di fare esattamente quello di cui hai parlato: abbiamo un database, ma vogliamo testare qualcosa 50 volte, quasi simultaneamente.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: 50 volte significa che devi ordinare 50 istanze Spot.<\/p>\n<p><i><b>\u041d\u0421<\/b>: No, facciamo tutto su una macchina.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ma come distribuite 50 volte, se questo \u00e8 un database, diciamo, terabyte? Probabilmente avr\u00e0 bisogno in modo condizionale di 256 GB di RAM?<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec, a volte serve molta memoria \u2014 \u00e8 normale. Ma un esempio dalla vita reale. Su una macchina di produzione ci sono 96 core e 600 GB. In questo caso, per il database vengono utilizzati 32 core (anche 16 core a volte) e 100-120 GB di memoria.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: E l\u00ec ci stanno 50 copie?<\/p>\n<p><i><b>\u041d\u0421<\/b>: Quindi la copia \u00e8 una, poi funziona il copy-on-write (di ZFS)... Ti racconter\u00f2 in dettaglio.<\/i><\/p>\n<p><i>Ad esempio, abbiamo un database da 10 TB. Abbiamo creato un disco per esso, e ZFS ha anche ridotto la sua dimensione di circa il 30-40%. Poich\u00e9 non facciamo test di carico, non ci importa del tempo di risposta esatto: pu\u00f2 essere fino a 2 volte pi\u00f9 lento \u2014 va bene.<\/i><\/p>\n<p><i>Offriamo la possibilit\u00e0 a programmatori, QA, DBA, ecc. di eseguire test in 1-2 flussi. Ad esempio, possono avviare una qualche migrazione. Non richiede subito 10 core \u2014 le serve 1 backend di Postgres, 1 core. La migrazione partir\u00e0 \u2014 forse, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/routine-vacuuming.html#AUTOVACUUM\">autovacuum<\/a><\/noindex> si avvier\u00e0 un'altra, a quel punto si utilizza il secondo core. Abbiamo riservato 16-32 core, quindi 10 persone possono lavorare contemporaneamente, non ci sono problemi.<\/i><\/p>\n<p><i>Poich\u00e9 fisicamente <code>PGDATA<\/code> identica, risulta cos\u00ec che in realt\u00e0 inganniamo Postgres. La questione \u00e8: ad esempio, si avviano 10 istanze di Postgres contemporaneamente. Qual \u00e8 di solito il problema? Posizionano <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-resource.html\">shared_buffers<\/a><\/noindex>, diciamo, al 25%. Di conseguenza, sono 200 GB. Non puoi avviarne pi\u00f9 di tre, perch\u00e9 la memoria finisce.<\/i><\/p>\n<p><i>: Ma a un certo punto abbiamo capito che non \u00e8 necessario: impostiamo shared_buffers a 2 GB. PostgreSQL ha <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE\">effective_cache_size<\/a><\/noindex>, e in realt\u00e0 solo questo influisce su <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Query_plan\">i piani<\/a><\/noindex>. Lo impostiamo a 0,5 TB. E neanche importa che in realt\u00e0 non ci siano: costruisce piani come se ci fossero.<\/i><\/p>\n<p><i>Di conseguenza, quando testiamo una certa migrazione, possiamo raccogliere tutti i piani \u2014 vedremo come si svolger\u00e0 in produzione. I secondi saranno diversi (pi\u00f9 lenti), ma i dati che leggiamo davvero e i piani stessi (quali JOIN, ecc.) sono esattamente uguali a quelli in produzione. E parallelamente si possono eseguire molte di queste verifiche su una macchina.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non pensi che ci siano diversi problemi qui? Il primo \u00e8 che questa soluzione funziona solo con PostgreSQL. Questo approccio \u00e8 molto specifico, non \u00e8 generico. Il secondo \u00e8 che Kubernetes (e tutto ci\u00f2 che ora si sta spostando verso le tecnologie cloud) presuppone molti nodi, e questi nodi sono effimeri. E nel tuo caso si tratta di un nodo stateful, persistente. Queste cose mi creano delle contraddizioni.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Primo \u2014 sono d'accordo, \u00e8 una storia puramente di Postgres. Penso che se abbiamo un qualche direct IO e un buffer pool quasi per tutta la memoria, un tale approccio non funzionerebbe \u2014 i piani sarebbero diversi. Ma finora lavoriamo solo con Postgres e non consideriamo altri.<\/i><\/p>\n<p><i>Parlando di Kubernetes. Tu stesso racconti ovunque che il nostro database \u00e8 persistente. Se l'istanza cade, l'importante \u00e8 mantenere il disco. Anche la nostra piattaforma \u00e8 in Kubernetes, e il componente con Postgres \u00e8 separato (anche se un giorno sar\u00e0 integrato). Quindi funziona cos\u00ec: l'istanza \u00e8 caduta, ma abbiamo mantenuto il suo PV e lo abbiamo semplicemente collegato a un'altra (nuova) istanza, come se non fosse successo nulla.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Dal mio punto di vista, creiamo pod in Kubernetes. K8s \u00e8 elastico: i nodi vengono ordinati automaticamente secondo necessit\u00e0. Il compito \u00e8 semplicemente creare un pod e dire che ha bisogno di X risorse, e poi K8s si occuper\u00e0 del resto. Ma il supporto per lo storage in Kubernetes \u00e8 ancora instabile: in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/467477\/\">1.16<\/a><\/noindex>, nel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476998\/\">1.17<\/a><\/noindex> questo rilascio \u00e8 uscito <i>settimane<\/i> fa) queste funzionalit\u00e0 stanno solo diventando beta.<\/p>\n<p>tra sei mesi o un anno \u2014 diventer\u00e0 pi\u00f9 o meno stabile, o almeno sar\u00e0 dichiarato tale. Allora la possibilit\u00e0 di snapshot e resize risolve completamente il tuo problema. Perch\u00e9 hai un database. S\u00ec, potrebbe non essere molto veloce, ma la velocit\u00e0 dipende da cosa c'\u00e8 \u00absotto il cofano\u00bb, perch\u00e9 alcune implementazioni sanno fare copie e copy-on-write a livello di sistema di dischi.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Qui bisogna anche aspettare che tutti i motori (Amazon, Google\u2026) inizino a supportare questa versione \u2014 ci vuole anche un po' di tempo.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Per ora non li usiamo. Utilizziamo il nostro.<\/p>\n<h2>Sviluppo locale per Kubernetes<\/h2>\n<p>\n<i><b>\u041d\u0421<\/b>: Ti \u00e8 mai capitato di avere la necessit\u00e0 di sollevare tutti i pod su una singola macchina e fare un piccolo test? Per ottenere rapidamente una prova di concetto e vedere se l'applicazione funziona in Kubernetes, senza dover dedicare molte macchine a questo. C'\u00e8 Minikube, giusto?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Mi sembra che questo caso \u2014 l'implementazione su un singolo nodo \u2014 riguardi esclusivamente lo sviluppo locale. O qualche manifestazione di tale pattern. Esiste <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/333470\/\">Minikube<\/a><\/noindex>, esiste <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>. Stiamo procedendo verso l'uso di Kubernetes in Docker. Abbiamo appena iniziato a lavorarci per test.<\/p>\n<p><i><b>\u041d\u0421<\/b>: All'inizio pensavo che fosse un tentativo di impacchettare tutti i pod in un'unica immagine Docker. Ma si \u00e8 rivelato essere completamente diverso. Ci sono sempre contenitori separati, pod separati \u2014 solo in Docker.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: S\u00ec. E hanno fatto una simulazione piuttosto divertente, ma il concetto \u00e8 che\u2026 Abbiamo uno strumento per il deployment \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>. Vogliamo implementare una modalit\u00e0 \u2014 ipoteticamente <code>werf up<\/code>: 'Sollevami un Kubernetes locale'. E poi lanciare un ipotetico <code>werf follow<\/code>. Cos\u00ec il programmatore pu\u00f2 modificare in IDE, mentre nel sistema \u00e8 in esecuzione un processo che rileva le modifiche e ricompila le immagini, ridistribuendole nel K8s locale. Questo \u00e8 il tentativo di risolvere il problema dello sviluppo locale.<\/p>\n<h2>Snapshots e clonazione di DB nelle realt\u00e0 K8s<\/h2>\n<p>\n<i><b>\u041d\u0421<\/b>: Tornando al copy-on-write. Ho notato che anche i cloud hanno snapshot. Funzionano in modo diverso. Ad esempio, in GCP: hai un'istanza multi-terabyte sulla costa est degli Stati Uniti. Esegui periodicamente snapshot. Crei una copia del disco dallo snapshot sulla costa ovest \u2014 dopo pochi minuti \u00e8 tutto pronto, funziona molto rapidamente, basta riempire la cache in memoria. Ma questi cloni (snapshot) servono per provisionare un nuovo volume. \u00c8 fantastico quando hai bisogno di creare molte istanze.<\/i><\/p>\n<p><i>Per i test, penso che gli snapshot di cui parli in Docker, o di cui parlo io in ZFS, btrfs e persino LVM\u2026 \u2014 consentono di non generare realmente nuovi dati su una singola macchina. Nel cloud, pagherai anche per loro ogni volta e aspetterai non secondi, ma minuti (e nel caso <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\u2019<\/a><\/noindex>, forse anche ore).<\/i><\/p>\n<p><i>Invece, puoi ottenere questi dati in un paio di secondi, eseguire il test e scartarlo. Questi snapshots risolvono problemi diversi. Nel primo caso \u2014 per scalare e ottenere nuove repliche, nel secondo \u2014 per i test.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Non sono d'accordo. Fare una clonazione normale dei volumi \u00e8 un compito del cloud. Non ho guardato la loro implementazione, ma so come lo facciamo noi su hardware. Abbiamo Ceph, in cui a qualsiasi volume fisico (<noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ceph.com\/docs\/master\/rbd\/\">RBD<\/a><\/noindex>) puoi dire <i>clone<\/i> e ricevere in decine di millisecondi un secondo volume con le stesse caratteristiche, <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/IOPS\">IOPS<\/a><\/noindex>e cos\u00ec via. \u00c8 importante capire che all'interno c'\u00e8 un astuto copy-on-write. Perch\u00e9 il cloud non potrebbe farlo allo stesso modo? Sono certo che in un modo o nell'altro stiano cercando di farlo.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Ma ci vorranno comunque secondi, decine di secondi, per avviare l'istanza, portare Docker e cos\u00ec via.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Perch\u00e9 \u00e8 necessario avviare un'intera istanza? Abbiamo un'istanza con 32 core, una con 16... e ci stanno dentro solo alcune \u2014 ad esempio, quattro. Quando ordiniamo un quinto, verr\u00e0 avviata l'istanza, e poi verr\u00e0 eliminata.<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec, interessante, in Kubernetes la situazione \u00e8 diversa. Abbiamo un DB non in K8s, e un'istanza. Ma per clonare un database multiterrabyte ci vogliono non pi\u00f9 di due secondi.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Questo \u00e8 fantastico. Ma il mio messaggio iniziale \u00e8 che non si tratta di una soluzione generica. S\u00ec, \u00e8 ottima, ma \u00e8 adatta solo a Postgres e solo su un nodo.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Non \u00e8 adatta solo per Postgres: i piani, come ho descritto, funzioneranno cos\u00ec solo per esso. Ma se non ci preoccupiamo dei piani, e abbiamo solo bisogno di dati per test funzionali, allora va bene per qualsiasi DBMS.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Molti anni fa abbiamo fatto qualcosa di simile con snapshot LVM. \u00c8 un classico. Questo approccio \u00e8 stato utilizzato molto attivamente. Solo che i nodi stateful sono un problema. Perch\u00e9 non vanno mai dimenticati, bisogna sempre tenerne conto...<\/p>\n<p><i><b>\u041d\u0421<\/b>: Non vedi qui qualche opportunit\u00e0 per un ibrido? Diciamo, uno stateful \u2014 \u00e8 un pod, funziona per pi\u00f9 persone (molti tester). Abbiamo un solo volume, ma grazie al filesystem i clone sono locali. Se il pod si guasta, il disco rimane \u2014 il pod si riavvia, legge le informazioni su tutti i clone, ripristina tutto e dice: \u00abEcco i vostri clone su queste porte, lavorateci sopra\u00bb.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Tecnicamente, questo significa che all'interno di Kubernetes abbiamo un pod, all'interno del quale eseguiamo molti Postgres.<\/p>\n<p><i><b>\u041d\u0421<\/b>: S\u00ec. Ha un limite: diciamo, non pi\u00f9 di 10 persone possono lavorare contemporaneamente. Se servono 20 \u2014 avviamo un secondo pod simile. \u00c8 completamente possibile clonarlo, ottenendo un secondo volume completo, su cui ci saranno gli stessi 10 \u00abfine\u00bb clone. Non vedi questa possibilit\u00e0?<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Dobbiamo aggiungere qui le questioni di sicurezza. Questa organizzazione implica che questo pod abbia privilegi elevati (capabilities), poich\u00e9 pu\u00f2 eseguire operazioni non standard sul filesystem\u2026 Ma ripeto: credo che a medio termine Kubernetes sistemer\u00e0 lo storage, i cloud risolveranno l'intera questione dei volumi \u2014 tutto funzioner\u00e0 \u00abnormalmente\u00bb. Ci sar\u00e0 il resize, il cloning\u2026 Esiste un volume \u2014 diciamo: \u00abCrea un nuovo volume basato su quello\u00bb, \u2014 e dopo un secondo e mezzo otteniamo ci\u00f2 di cui abbiamo bisogno.<\/p>\n<p><i><b>\u041d\u0421<\/b>: Non credo che ci vogliano un secondo e mezzo per diversi terabyte. Su Ceph lo fai da solo, ma stai parlando di cloud. Vai nel cloud, su EC2 fai un clone di un volume EBS di diversi terabyte e guarda quale sar\u00e0 la performance. Non ci vorr\u00e0 qualche secondo. Sono molto curioso di vedere quando arriveranno a quei livelli. Capisco cosa vuoi dire, ma mi permetto di non essere d'accordo.<\/i><\/p>\n<p><b>\u0414\u0421<\/b>: Ok, ma ho detto che a medio termine, non a breve termine. Nei prossimi anni.<\/p>\n<h2>Riguardo all'operatore per PostgreSQL di Zalando<\/h2>\n<p>\nA met\u00e0 di questo incontro si \u00e8 unito anche Alexey Klyukin, ex sviluppatore di Zalando, che ha raccontato la storia dell'operatore PostgreSQL:<\/p>\n<blockquote><p>\u00c8 fantastico che questo tema sia stato toccato: sia Postgres che Kubernetes. Quando abbiamo iniziato a svilupparlo in Zalando nel 2017, era un argomento che tutti volevano affrontare, ma nessuno lo faceva. Tutti gi\u00e0 usavano Kubernetes, ma quando si chiedeva come gestire i database, anche persone come <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kelseyhightower\">Kelsey Hightower<\/a><\/noindex>, predicando K8s, dicevano circa quanto segue:<\/p>\n<p><i>\u00abAndate verso i servizi gestiti e usateli, non avviate DB in Kubernetes. Altrimenti il vostro K8s decider\u00e0, ad esempio, di eseguire un aggiornamento, spegner\u00e0 tutti i nodi, e i vostri dati voleranno lontano lontano\u00bb.<\/i><\/p>\n<p>Abbiamo deciso di realizzare un operatore che, contro questo consiglio, avvier\u00e0 DB Postgres in Kubernetes. E avevamo una buona ragione \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\">Patroni<\/a><\/noindex>. \u00c8 un failover automatico per PostgreSQL, realizzato nel modo giusto, cio\u00e8 utilizzando etcd, consul o ZooKeeper come deposito delle informazioni sul cluster. Un deposito che fornir\u00e0 a tutti, che chiedono, ad esempio, chi \u00e8 il leader attuale, le stesse informazioni \u2014 nonostante sia tutto distribuito, \u2014 per evitare che si verifichi uno split brain. Inoltre, avevamo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\/tree\/master\/docker\">immagine Docker<\/a><\/noindex> per esso.<\/p>\n<p>In generale, la necessit\u00e0 di un auto failover \u00e8 emersa dopo la migrazione da un data center interno a un cloud. Il cloud si basava su una propria soluzione PaaS (Platform-as-a-Service). Era open source, ma per implementarlo bisognava lavorare sodo. Si chiamava <noindex><a rel=\"nofollow\" href=\"https:\/\/stups.io\/\">STUPS<\/a><\/noindex>.<\/p>\n<p>Inizialmente non c'era alcun Kubernetes. Cio\u00e8, quando \u00e8 stata implementata la propria soluzione, K8s era gi\u00e0 presente, ma era cos\u00ec grezzo che non era adatto per la produzione. Era, secondo me, il 2015 o il 2016. Fino al 2017 Kubernetes era diventato pi\u00f9 o meno maturo \u2014 \u00e8 emersa la necessit\u00e0 di migrare l\u00ec.<\/p>\n<p>E avevamo gi\u00e0 un contenitore Docker. C'era una PaaS che utilizzava Docker. Perch\u00e9 non provare K8s? Perch\u00e9 non scrivere il proprio operatore? Murat Kabilov, che \u00e8 venuto da noi da Avito, ha iniziato questo come un progetto personale \u2014 \"giocare\" \u2014 e il progetto ha decollato.<\/p>\n<p>Ma in realt\u00e0 volevo parlare di AWS. Perch\u00e9 l\u00ec c'era storicamente del codice legato ad AWS\u2026<\/p>\n<p>Quando avviate qualcosa in Kubernetes, bisogna capire che K8s \u00e8 un lavoro in corso. Si sviluppa costantemente, migliora e a volte si rompe. \u00c8 necessario seguire attentamente tutte le modifiche in Kubernetes e essere pronti a tuffarsi nel suo funzionamento nei dettagli \u2014 forse pi\u00f9 di quanto vorreste. Questo \u00e8 vero per qualsiasi piattaforma su cui eseguirete i vostri DB\u2026<\/p>\n<p>Quindi, quando abbiamo creato l'operatore, avevamo Postgres che funzionava con un volume esterno (in questo caso EBS, dato che lavoravamo in AWS). Il database cresceva e a un certo punto \u00e8 stato necessario effettuare un resize: ad esempio, la dimensione iniziale dell'EBS era 100 TB, il database ha raggiunto tale dimensione e ora vogliamo fare l'EBS a 200 TB. Come? Diciamo che si potrebbe fare un dump\/restore su una nuova istanza, ma questo \u00e8 lungo e comporta dei tempi di inattivit\u00e0.<\/p>\n<p>Pertanto, desideravamo un resize che aumentasse la partizione EBS e poi dicesse al filesystem di utilizzare il nuovo spazio. E l'abbiamo fatto, ma all'epoca Kubernetes non aveva alcuna API per l'operazione di resize. Poich\u00e9 lavoravamo su AWS, abbiamo scritto il codice per la sua API.<\/p>\n<p>Nessuno impedisce di fare lo stesso per altre piattaforme. Nell'operatore non c'\u00e8 vincolo che possa essere eseguito solo su AWS, non funziona su tutto il resto. In generale, \u00e8 un progetto Open Source: se qualcuno vuole accelerare l'adozione di una nuova API, \u00e8 il benvenuto. Ci sono <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">GitHub<\/a><\/noindex>, pull request \u2014 il team di Zalando cerca di rispondere abbastanza rapidamente e promuovere l'operatore. Per quanto ne so, il progetto <noindex><a rel=\"nofollow\" href=\"https:\/\/summerofcode.withgoogle.com\/archive\/2019\/organizations\/6187982082539520\/\">ha partecipato<\/a><\/noindex> a Google Summer of Code e ad altre iniziative simili. Zalando sta lavorando molto attivamente su di esso.\n<\/p><\/blockquote>\n<p><\/p>\n<h2>P.S. Bonus!<\/h2>\n<p>\nSe siete interessati all'argomento PostgreSQL e Kubernetes, vorremmo anche farvi notare che la scorsa settimana c'\u00e8 stato il prossimo Postgres Tuesday, dove Nikolai ha parlato con <b>Alexander Kukushkin di Zalando<\/b>. Il video \u00e8 disponibile <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=FE0xi7SBqsg\">qui<\/a><\/noindex>.<\/p>\n<h2>P.P.S.<\/h2>\n<p>\nLeggete anche nel nostro blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Database e Kubernetes (panoramica e video della presentazione)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/475036\/\">Migrazione di Cassandra in Kubernetes: caratteristiche e soluzioni<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/461149\/\">Migrazione non semplice di MongoDB in Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/450662\/\">Migrazione non semplice di RabbitMQ in Kubernetes<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Fonte: <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.0.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\/it\/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.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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\/it\/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 Tuesday n. 5: \"PostgreSQL e Kubernetes. CI\/CD. Automazione del testing\" | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/55467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=55467"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/55467\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/55468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=55467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=55467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=55467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}