{"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\/es\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","title":{"rendered":"Martes de Postgres #5: \u00abPostgreSQL y Kubernetes. CI\/CD. Automatizaci\u00f3n de pruebas\u00bb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Martes de Postgres #5: \u00abPostgreSQL y Kubernetes. CI\/CD. Automatizaci\u00f3n de pruebas\u00bb\" src=\"\/wp-content\/uploads\/2020\/01\/5eb8dd2afa4cab58a7359b305814d77f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA finales del a\u00f1o pasado, se llev\u00f3 a cabo una nueva transmisi\u00f3n en vivo de la comunidad rusa de PostgreSQL <noindex><a rel=\"nofollow\" href=\"https:\/\/www.meetup.com\/postgresqlrussia\/\">#RuPostgres<\/a><\/noindex>, durante la cual su cofundador Nikolai Samokhvalov habl\u00f3 con el director t\u00e9cnico de 'Flanta', Dmitry Stolyarov, sobre esta base de datos en el contexto de Kubernetes.<\/p>\n<p>Publicamos la transcripci\u00f3n de la parte principal de esta discusi\u00f3n, y en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/channel\/UC0SBGSNmBLrTZIkbN-lJHnw\">el canal de YouTube de la comunidad<\/a><\/noindex> se ha publicado la grabaci\u00f3n 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=\"Reproducir 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>Bases de datos y Kubernetes<\/h2>\n<p>\n<i><b>HS<\/b>: Hoy no vamos a hablar de VACUUM y CHECKPOINT&#8217;s. Queremos hablar de Kubernetes. S\u00e9 que tienes muchos a\u00f1os de experiencia. He visto tus videos e incluso he vuelto a ver algunos fragmentos... Vamos directo al grano: \u00bfpor qu\u00e9 usar Postgres o MySQL en K8s?<\/i><\/p>\n<p><b>DS<\/b>: No hay una respuesta definitiva a esta pregunta, y no puede haberla. Pero, en general, se trata de simplicidad y conveniencia\u2026 potenciales. A todos les gustar\u00eda tener servicios gestionados.<\/p>\n<p><i><b>HS<\/b>: \u00bfPara que sea como <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/rds\/\">RDS<\/a><\/noindex>, solo que en casa?<\/i><\/p>\n<p><b>DS<\/b>: S\u00ed, que sea como RDS, pero en cualquier lugar.<\/p>\n<p><i><b>HS<\/b>: 'En cualquier lugar' es un buen comentario. En las grandes empresas, todo est\u00e1 ubicado en diferentes lugares. Entonces, si se trata de una gran empresa, \u00bfpor qu\u00e9 no optar por una soluci\u00f3n lista para usar? Por ejemplo, Nutanix tiene sus propios desarrollos, otras empresas (VMware\u2026) tienen lo mismo: 'RDS, pero en casa'.<\/i><\/p>\n<p><b>DS<\/b>: Pero hablamos de una implementaci\u00f3n espec\u00edfica que funcionar\u00e1 solo en ciertas condiciones. Cuando se trata de Kubernetes, hay una gran variedad de infraestructuras (que pueden existir en K8s). En esencia, es un est\u00e1ndar para API en la nube\u2026<\/p>\n<p><i><b>HS<\/b>: \u00a1Adem\u00e1s, es gratis!<\/i><\/p>\n<p><b>DS<\/b>: Eso no es tan importante. La gratuidad importa a un segmento de mercado no muy grande. Lo que realmente importa es\u2026 Seguramente recuerdas la presentaci\u00f3n '<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Bases de datos y Kubernetes<\/a><\/noindex>\u00bb?<\/p>\n<p><i><b>HS<\/b>: S\u00ed.<\/i><\/p>\n<p><b>DS<\/b>: Entend\u00ed que fue recibido de manera muy ambigua. Parte de la gente pens\u00f3 que estaba diciendo: \u201c\u00a1Chicos, vamos a llevar todas las bases de datos a Kubernetes!\u201d, mientras que otros decidieron que eran bicicletas horribles. Y lo que realmente quer\u00eda decir era otra cosa: \u201cMiren lo que est\u00e1 ocurriendo, cu\u00e1les son los problemas y c\u00f3mo pueden resolverse. \u00bfDeber\u00edan llevar bases de datos a Kubernetes? \u00bfA producci\u00f3n? Bueno, solo si les gusta... hacer ciertas cosas. Pero para desarrollo, puedo decir que lo recomiendo. Para el desarrollo, la din\u00e1mica de crear\/borrar entornos es muy importante\u201d.<\/p>\n<p><i>NS: \u00bfTe refieres a todos los entornos que no son prod? Staging, QA...<\/i><\/p>\n<p><b>DS<\/b>: Si hablamos de los perf-stands, probablemente no, porque all\u00ed los requisitos son espec\u00edficos. Si hablamos de casos especiales donde se necesita una base de datos muy grande en staging, tampoco ser\u00eda el caso... Si es un entorno est\u00e1tico, de larga duraci\u00f3n, \u00bfcu\u00e1l es la ventaja de que la base est\u00e9 ubicada en K8s?<\/p>\n<p><i><b>HS<\/b>: Ninguna. Pero, \u00bfd\u00f3nde vemos entornos est\u00e1ticos? El entorno est\u00e1tico qued\u00f3 obsoleto ayer.<\/i><\/p>\n<p><b>DS<\/b>: Staging puede ser est\u00e1tico. Tenemos clientes...<\/p>\n<p><i><b>HS<\/b>: S\u00ed, yo tambi\u00e9n tengo. Es un gran problema si tienes una base de 10 Tb y staging es de 200 Gb...<\/i><\/p>\n<p><b>DS<\/b>: \u00a1Tengo un caso muy interesante! En staging hay una base de datos de producci\u00f3n donde se realizan cambios. Y hay un bot\u00f3n: \u201cdesplegar en producci\u00f3n\u201d. Estos cambios \u2014deltas\u2014 se a\u00f1aden (parece que simplemente se sincronizan por API) a producci\u00f3n. Es una opci\u00f3n muy ex\u00f3tica.<\/p>\n<p><i><b>HS<\/b>: He visto startups en Silicon Valley que est\u00e1n en RDS o incluso en Heroku, historias de hace 2-3 a\u00f1os, y ellos descargan un dump a su laptop. Porque la base de datos tiene solo 80 GB y hay espacio en la laptop. Luego compran discos para tener 3 bases de datos y poder trabajar en diferentes desarrollos. Esto tambi\u00e9n sucede. Tambi\u00e9n he visto que no tienen miedo de copiar producci\u00f3n a staging \u2014depende mucho de la empresa. Pero he visto que hay quienes tienen miedo, y a menudo falta tiempo y manos. Pero antes de que hablemos de este tema, me gustar\u00eda escuchar sobre Kubernetes. \u00bfEntiendo bien que en producci\u00f3n todav\u00eda nadie lo tiene?<\/i><\/p>\n<p><b>DS<\/b>: Tenemos peque\u00f1as bases de datos en producci\u00f3n. Se trata de vol\u00famenes en decenas de gigabytes y servicios no cr\u00edticos, para los cuales no val\u00eda la pena hacer r\u00e9plicas (y no hab\u00eda necesidad). Y con la condici\u00f3n de que haya un almacenamiento adecuado para Kubernetes. Esta base trabajaba en una m\u00e1quina virtual \u2014en VMware, sobre un SAN. La colocamos en <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/\">PV<\/a><\/noindex> y ahora podemos trasladarla de m\u00e1quina a m\u00e1quina.<\/p>\n<p><i><b>HS<\/b>: Bases de ese tama\u00f1o, hasta 100 Gb, en buenos discos y con una buena red se pueden extender en unos minutos, \u00bfverdad? Una velocidad de 1 Gb por segundo ya no es una excentricidad.<\/i><\/p>\n<p><b>DS<\/b>: S\u00ed, para una operaci\u00f3n lineal no es un problema.<\/p>\n<p><i><b>HS<\/b>: Ok, sobre prod solo debemos pensar. Pero si consideramos Kubernetes para entornos no prod, \u00bfc\u00f3mo proceder? Veo que en Zalando <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">hacen un operador<\/a><\/noindex>, en Crunchy <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/postgres-operator\">est\u00e1n desarrollando<\/a><\/noindex>, hay otras opciones. Y hay <noindex><a rel=\"nofollow\" href=\"https:\/\/ongres.com\/\">OnGres<\/a><\/noindex> \u2014 es nuestro buen amigo Alvaro de Espa\u00f1a: ellos hacen no solo <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/326414\/\">un operador<\/a><\/noindex>, sino todo un distribuidor (<noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/ongresinc\/stackgres\">StackGres<\/a><\/noindex>), donde adem\u00e1s de Postgres tambi\u00e9n decidimos incluir un backup, un proxy Envoy...<\/i><\/p>\n<p><b>DS<\/b>: \u00bfEnvoy para qu\u00e9? \u00bfPara equilibrar precisamente el tr\u00e1fico de Postgres?<\/p>\n<p><i><b>HS<\/b>: S\u00ed. Es decir, lo ven as\u00ed: si tomas una distribuci\u00f3n de Linux y el n\u00facleo, el PostgreSQL normal ser\u00eda el n\u00facleo, y ellos quieren crear una distribuci\u00f3n que sea amigable con la nube y que funcione en Kubernetes. Est\u00e1n integrando componentes (respaldo, etc.) y ajustando para que funcionen bien.<\/i><\/p>\n<p><b>DS<\/b>: \u00a1Muy bien! En esencia, es software para construir su propio Postgres gestionado.<\/p>\n<p><i><b>HS<\/b>: Las distribuciones de Linux tienen problemas eternos: c\u00f3mo hacer drivers para que todo el hardware sea soportado. Y ellos tienen la idea de que funcionar\u00e1n en Kubernetes. S\u00e9 que en el operador de Zalando recientemente vimos una dependencia de AWS y eso no es muy bueno. No deber\u00eda haber una dependencia de una infraestructura concreta, \u00bfcu\u00e1l ser\u00eda entonces el sentido?<\/i><\/p>\n<p><b>DS<\/b>: No s\u00e9 en qu\u00e9 situaci\u00f3n exactamente se at\u00f3 Zalando, pero en Kubernetes actualmente el almacenamiento est\u00e1 hecho de tal manera que no se puede hacer un respaldo de disco de forma gen\u00e9rica. Recientemente en el est\u00e1ndar \u2014 en la \u00faltima versi\u00f3n <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465417\/\">especificaci\u00f3n CSI<\/a><\/noindex> \u2014 se hizo posible la creaci\u00f3n de instant\u00e1neas, pero \u00bfd\u00f3nde se ha implementado? Honestamente, todav\u00eda est\u00e1 bastante crudo\u2026 Estamos probando CSI sobre AWS, GCE, Azure, vSphere, pero en cuanto comienzas a usarlo, se hace evidente que a\u00fan no est\u00e1 listo.<\/p>\n<p><i><b>HS<\/b>: Por eso a veces hay que depender de la infraestructura. Creo que esto sigue siendo una fase temprana \u2014 problemas de crecimiento. La pregunta: \u00bfqu\u00e9 aconsejar\u00edas a los novatos que quieren probar PgSQL en K8s? \u00bfQu\u00e9 operador, tal vez?<\/i><\/p>\n<p><b>DS<\/b>: El problema es que Postgres para nosotros es solo el 3%. Tenemos una lista muy grande de diferentes softwares en Kubernetes, no quiero enumerar todo. Por ejemplo, Elasticsearch. Hay un mont\u00f3n de operadores: algunos se desarrollan activamente, otros no. Hemos establecido requisitos sobre lo que deber\u00eda tener un operador para que lo tomemos en serio. Especialmente para Kubernetes, no en el 'operador para hacer algo en condiciones de Amazon'... De hecho, utilizamos masivamente (casi todos nuestros clientes) un \u00fanico operador - <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/spotahome\/redis-operator\">para Redis<\/a><\/noindex> <i>(pronto publicaremos un art\u00edculo sobre \u00e9l)<\/i>.<\/p>\n<p><i><b>HS<\/b>: \u00bfY para MySQL tampoco hay? S\u00e9 que Percona\u2026 ya que ahora se ocupan de MySQL, MongoDB y Postgres, deber\u00edan desarrollar algo universal: para todas las bases, para todos los proveedores de nube.<\/i><\/p>\n<p><b>DS<\/b>: No hemos tenido tiempo de mirar los operadores para MySQL. Ahora mismo no es nuestro principal enfoque. MySQL funciona bien en modo standalone. \u00bfPara qu\u00e9 un operador si puedes simplemente lanzar la base de datos...? Se puede iniciar un contenedor Docker con Postgres, o hacerlo de forma sencilla.<\/p>\n<p><i><b>HS<\/b>: Tambi\u00e9n hubo preguntas al respecto. \u00bfTotalmente sin operador?<\/i><\/p>\n<p><b>DS<\/b>: S\u00ed, al 100% tenemos PostgreSQL ejecut\u00e1ndose sin operador. Por ahora es as\u00ed. Usamos activamente el operador para Prometheus, para Redis. Planeamos encontrar un operador para Elasticsearch, ya que es el que m\u00e1s urgencia tiene, porque queremos implementarlo en Kubernetes en el 100% de los casos. Tambi\u00e9n queremos que MongoDB siempre se ejecute en Kubernetes. Aparecen ciertas necesidades, y tenemos la sensaci\u00f3n de que en estos casos se puede hacer algo. Pero en cuanto a Postgres, ni siquiera lo hemos mirado. Por supuesto, sabemos de la existencia de diferentes opciones, pero en la pr\u00e1ctica, tenemos standalone.<\/p>\n<h2>Base de datos para pruebas en Kubernetes<\/h2>\n<p>\n<i><b>HS<\/b>: Pasemos al tema de las pruebas. \u00bfC\u00f3mo desplegar cambios en la base de datos desde la perspectiva de DevOps? Hay microservicios, muchas bases, siempre hay algo que cambia. \u00bfC\u00f3mo asegurar un CI\/CD adecuado para que desde la perspectiva de la base de datos todo est\u00e9 en orden? \u00bfCu\u00e1l es tu enfoque?<\/i><\/p>\n<p><b>DS<\/b>: No puede haber una \u00fanica respuesta. Hay varios par\u00e1metros. El primero es el tama\u00f1o de la base de datos que queremos desplegar. T\u00fa mismo mencionaste que las empresas tienen diferentes enfoques sobre tener una copia de la base de datos de producci\u00f3n en dev y stage.<\/p>\n<p><i><b>HS<\/b>: Y en el contexto del GDPR, creo que son cada vez m\u00e1s cautelosos... Puedo decir que en Europa ya han comenzado a aplicar multas.<\/i><\/p>\n<p><b>DS<\/b>: Pero a menudo se puede escribir software que crea un volcado desde producci\u00f3n y lo ofusca. Se generan datos de producci\u00f3n (snapshot, volcado, copia binaria...), pero est\u00e1n anonimizados. En su lugar, tambi\u00e9n pueden haber scripts de generaci\u00f3n: pueden ser fixtures o simplemente un script que genere una gran base. El problema es: \u00bfcu\u00e1nto tiempo tarda en crearse la imagen base? \u00bfY cu\u00e1nto tiempo se necesita para desplegarla en el entorno adecuado?<\/p>\n<p>: Hemos llegado a un esquema: si el cliente tiene un conjunto de datos de fixture (versi\u00f3n m\u00ednima de la base), por defecto los usamos. Si se trata de entornos de revisi\u00f3n, cuando creamos una rama, se despliega una instancia de la aplicaci\u00f3n \u2014 ah\u00ed desplegamos una base de datos peque\u00f1a. Pero result\u00f3 bien tambi\u00e9n. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/417509\/\">una variante<\/a><\/noindex>, cuando de producci\u00f3n hacemos un volcado una vez al d\u00eda (de noche) y recopilamos un contenedor Docker con PostgreSQL y MySQL basado en esos datos cargados. Si a partir de esta imagen hay que desplegar la base 50 veces, eso se hace de forma bastante sencilla y r\u00e1pida.<\/p>\n<p><i><b>HS<\/b>: \u00bfSimplemente copiando?<\/i><\/p>\n<p><b>DS<\/b>: Los datos se almacenan directamente en la imagen de Docker. Es decir, tenemos una imagen lista, de 100 GB. Gracias a las capas en Docker podemos desplegar r\u00e1pidamente esta imagen el n\u00famero necesario de veces. Es un m\u00e9todo rudimentario, pero funciona bastante bien.<\/p>\n<p><i><b>HS<\/b>: Luego, cuando se prueba, cambia directamente dentro de Docker, \u00bfverdad? Copy-on-write dentro de Docker - lo desechamos y empezamos de nuevo, todo bien. \u00a1Genial! \u00bfY ya lo est\u00e1n utilizando a fondo?<\/i><\/p>\n<p><b>DS<\/b>: Desde hace tiempo.<\/p>\n<p><i><b>HS<\/b>: Hacemos cosas muy parecidas. Solo que no usamos el copy-on-write de Docker, sino alguno diferente.<\/i><\/p>\n<p><b>DS<\/b>: No es gen\u00e9rico. Pero el de Docker funciona en todas partes.<\/p>\n<p><i><b>HS<\/b>: En teor\u00eda, s\u00ed. Pero tambi\u00e9n tenemos m\u00f3dulos, se pueden hacer diferentes m\u00f3dulos y trabajar con diferentes sistemas de archivos. Aqu\u00ed hay un punto importante. Desde la perspectiva de Postgres vemos todo esto de manera diferente. Ahora mir\u00e9 desde la perspectiva de Docker y vi que todo funciona. Pero si la base de datos es enorme, por ejemplo, 1 TB, ya todo toma tiempo: tanto las operaciones nocturnas como meter todo en Docker... \u00bfY si se debe meter 5 TB en Docker...? \u00bfO est\u00e1 todo bien?<\/i><\/p>\n<p><b>DS<\/b>: \u00bfCu\u00e1l es la diferencia? Son blobs, solo bits y bytes.<\/p>\n<p><i><b>HS<\/b>: La diferencia es: \u00bflo haces a trav\u00e9s de volcado y restauraci\u00f3n?<\/i><\/p>\n<p><b>DS<\/b>: No necesariamente. Los m\u00e9todos de generaci\u00f3n de esta imagen pueden ser variados.<\/p>\n<p><i><b>HS<\/b>: Para algunos clientes, hemos hecho que en lugar de generar un sistema base regularmente, lo mantengamos constantemente actualizado. Es b\u00e1sicamente una r\u00e9plica, pero los datos no se obtienen directamente del m\u00e1ster, sino a trav\u00e9s de un archivo. Un archivo binario, donde los WAL se aplican cada d\u00eda, ah\u00ed tambi\u00e9n se realizan las copias de seguridad... Estos WAL luego llegan, con un peque\u00f1o retraso (literalmente 1-2 segundos), al sistema base. A partir de ah\u00ed clonamos de cualquier manera; ahora, por defecto, usamos ZFS.<\/i><\/p>\n<p><b>DS<\/b>: Pero con ZFS est\u00e1s limitado a un nodo.<\/p>\n<p><i><b>HS<\/b>: S\u00ed. Pero ZFS tambi\u00e9n tiene el m\u00e1gico <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.oracle.com\/cd\/E18752_01\/html\/819-5461\/gbchx.html\">send<\/a><\/noindex>: con \u00e9l puedes enviar un snapshot e incluso (esto a\u00fan no lo he probado mucho, pero...) puedes enviar la delta entre dos <code>PGDATA<\/code>. En realidad, tenemos otra herramienta que no hemos considerado mucho para tales tareas. En PostgreSQL existe <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/app-pgrewind.html\">pg_rewind<\/a><\/noindex>, que funciona como un \u00abrsync\u00bb inteligente, omitiendo mucho de lo que no se necesita ver, ya que realmente no ha cambiado nada. Podemos hacer una r\u00e1pida sincronizaci\u00f3n entre dos servidores y retroceder de la misma manera.<\/i><\/p>\n<p><i>Entonces, intentamos, desde esta perspectiva m\u00e1s centrada en DBA, crear una herramienta que permita hacer lo mismo de lo que hablabas: tenemos una base de datos, pero queremos probar algo 50 veces, casi simult\u00e1neamente.<\/i><\/p>\n<p><b>DS<\/b>: 50 veces significa que necesitas solicitar 50 instancias Spot.<\/p>\n<p><i><b>HS<\/b>: No, lo hacemos todo en una m\u00e1quina.<\/i><\/p>\n<p><b>DS<\/b>: Pero, \u00bfc\u00f3mo desplegar\u00e1s 50 veces si esta \u00fanica base de datos, digamos, es de un terabyte? Probablemente necesite, digamos, 256 GB de RAM.<\/p>\n<p><i><b>HS<\/b>: S\u00ed, a veces se necesita mucha memoria, eso es normal. Pero un ejemplo de la vida real. En una m\u00e1quina de producci\u00f3n hay 96 n\u00facleos y 600 GB. Para la base de datos se utilizan 32 n\u00facleos (incluso a veces 16 n\u00facleos ahora) y de 100 a 120 GB de memoria.<\/i><\/p>\n<p><b>DS<\/b>: \u00bfY ah\u00ed caben 50 copias?<\/p>\n<p><i><b>HS<\/b>: As\u00ed que la copia es una sola, luego funciona la copia en escritura (ZFS)... Te contar\u00e9 m\u00e1s en detalle.<\/i><\/p>\n<p><i>Por ejemplo, tenemos una base de datos de 10 TB. Hicimos un disco para ella, ZFS compress\u00f3 su tama\u00f1o en un 30-40%. Como no hacemos pruebas de carga, no nos importa el tiempo de respuesta exacto: si es dos veces m\u00e1s lento, est\u00e1 bien.<\/i><\/p>\n<p><i>Damos la posibilidad a programadores, QA, DBA, etc., de realizar pruebas en 1-2 hilos. Por ejemplo, pueden iniciar alguna migraci\u00f3n. No necesita de inmediato 10 n\u00facleos; solo requiere 1 backend de Postgres, 1 n\u00facleo. La migraci\u00f3n se iniciar\u00e1; puede que <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/12\/routine-vacuuming.html#AUTOVACUUM\">autovacuum<\/a><\/noindex> tambi\u00e9n se inicie la segunda, entonces se usar\u00e1 el segundo n\u00facleo. Tenemos asignados de 16 a 32 n\u00facleos, as\u00ed que 10 personas pueden trabajar simult\u00e1neamente, no hay problemas.<\/i><\/p>\n<p><i>Dado que f\u00edsicamente <code>PGDATA<\/code> sea id\u00e9ntica, lo que en realidad significa que estamos enga\u00f1ando a Postgres. La cuesti\u00f3n es: se inician, por ejemplo, 10 Postgres al mismo tiempo. \u00bfCu\u00e1l es el problema normalmente? Se instalan <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-resource.html\">shared_buffers<\/a><\/noindex>, digamos, en un 25%. Por lo tanto, son 200 GB. No puedes iniciar m\u00e1s de tres as\u00ed, porque se te acabar\u00e1 la memoria.<\/i><\/p>\n<p><i>Pero en alg\u00fan momento nos dimos cuenta de que eso no era necesario: establecemos shared_buffers en 2 GB. PostgreSQL tiene <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE\">effective_cache_size<\/a><\/noindex>, y en realidad solo eso influye en <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Query_plan\">los planes<\/a><\/noindex>. Lo configuramos en 0.5 TB. Y no importa que en realidad no existan: \u00e9l construye planes como si existieran.<\/i><\/p>\n<p><i>Por lo tanto, cuando probamos alguna migraci\u00f3n, podemos recopilar todos los planes; veremos c\u00f3mo ocurrir\u00e1 en production. Los segundos ser\u00e1n diferentes (m\u00e1s lentos), pero los datos que realmente leemos y los propios planes (qu\u00e9 JOINs, etc.) son exactamente los mismos que en producci\u00f3n. Y, al mismo tiempo, se pueden ejecutar m\u00faltiples comprobaciones en una misma m\u00e1quina.<\/i><\/p>\n<p><b>DS<\/b>: \u00bfNo crees que aqu\u00ed hay varios problemas? Primero: es una soluci\u00f3n que solo funciona en PostgreSQL. Este enfoque es muy espec\u00edfico, no es gen\u00e9rico. Segundo: Kubernetes (y todo a donde van las tecnolog\u00edas en la nube) implica m\u00faltiples nodos, y estos nodos son ef\u00edmeros. En tu caso, es un nodo stateful, persistente. Estas cosas me generan contradicciones.<\/p>\n<p><i><b>HS<\/b>: Primero, estoy de acuerdo, esto es puramente una historia de Postgres. Creo que si tenemos alg\u00fan tipo de IO directo y un pool de b\u00fafer casi para toda la memoria, este enfoque no funcionar\u00e1; los planes ser\u00e1n distintos. Pero por ahora solo estamos trabajando con Postgres, no estamos considerando otros.<\/i><\/p>\n<p><i>Sobre Kubernetes. T\u00fa mismo lo cuentas por todas partes, que nuestra base de datos es persistente. Si una instancia falla, lo principal es conservar el disco. Tambi\u00e9n tenemos toda la plataforma en Kubernetes, y el componente con Postgres es separado (aunque alguna vez estar\u00e1 all\u00ed). Por lo tanto, es as\u00ed: la instancia falla, pero hemos conservado su PV y simplemente lo conectamos a otra instancia (nueva), como si nada hubiera pasado.<\/i><\/p>\n<p><b>DS<\/b>: Desde mi perspectiva, creamos pods en Kubernetes. K8s es el\u00e1stico: los nodos se solicitan por s\u00ed mismos seg\u00fan sea necesario. La tarea es simplemente crear un pod y decirle que necesita X recursos, y luego K8s se ocupa de todo. Pero el soporte de almacenamiento en Kubernetes sigue siendo inestable: en <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/467477\/\">1.16<\/a><\/noindex>, en <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476998\/\">1.17<\/a><\/noindex> (esta versi\u00f3n sali\u00f3 <i>hace semanas<\/i> ) estas caracter\u00edsticas se vuelven solo beta.<\/p>\n<p>Pasar\u00e1n seis meses o un a\u00f1o, y se volver\u00e1 m\u00e1s o menos estable, o al menos se anunciar\u00e1 como tal. Entonces, la posibilidad de snapshots y resize resolver\u00e1 completamente tu problema. Porque tienes una base. S\u00ed, puede que no sea muy r\u00e1pida, pero la velocidad depende de lo que haya \"bajo el cap\u00f3\", porque algunas implementaciones manejan la copia y copy-on-write a nivel del subsistema de disco.<\/p>\n<p><i><b>HS<\/b>: Aqu\u00ed tambi\u00e9n necesitamos que todos los motores (Amazon, Google\u2026) comiencen a soportar esta versi\u00f3n, eso tambi\u00e9n lleva tiempo.<\/i><\/p>\n<p><b>DS<\/b>: Por ahora no los usamos. Usamos el nuestro.<\/p>\n<h2>Desarrollo local en Kubernetes<\/h2>\n<p>\n<i><b>HS<\/b>: \u00bfTe has encontrado alguna vez con la necesidad de levantar todos los pods en una sola m\u00e1quina y hacer una peque\u00f1a prueba? Para obtener r\u00e1pidamente una prueba de concepto y ver si la aplicaci\u00f3n funciona en Kubernetes, sin asignar un mont\u00f3n de m\u00e1quinas para ello. Hay Minikube, \u00bfverdad?<\/i><\/p>\n<p><b>DS<\/b>: Creo que este caso \u2014 desplegar en un solo nodo \u2014 se refiere exclusivamente al desarrollo local. O a algunas manifestaciones de ese patr\u00f3n. Hay <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/333470\/\">Minikube<\/a><\/noindex>, hay <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>. Estamos avanzando hacia el uso de Kubernetes en Docker. Ya hemos comenzado a trabajar con ello para pruebas.<\/p>\n<p><i><b>HS<\/b>: Antes pensaba que era un intento de empaquetar todos los pods en una \u00fanica imagen de Docker. Pero result\u00f3 ser algo completamente diferente. A\u00fan hay contenedores separados, pods separados, simplemente en Docker.<\/i><\/p>\n<p><b>DS<\/b>: S\u00ed. Y hay una imitaci\u00f3n bastante divertida hecha, pero la idea es esta\u2026 Tenemos una herramienta para el despliegue \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/werf.io\/\">werf<\/a><\/noindex>. Queremos hacer un modo \u2014 condicionalmente <code>werf up<\/code>: \u00abLevanta un Kubernetes local para m\u00ed\u00bb. Y luego ejecutar un <code>werf follow<\/code>. Entonces, el desarrollador podr\u00e1 editar en el IDE, mientras que en el sistema hay un proceso en ejecuci\u00f3n que ve los cambios y reconstruye las im\u00e1genes, redistribuy\u00e9ndolas en el K8s local. As\u00ed queremos intentar resolver el problema del desarrollo local.<\/p>\n<h2>Instant\u00e1neas y clonaci\u00f3n de bases de datos en el contexto de K8s<\/h2>\n<p>\n<i><b>HS<\/b>: Si regresamos a copy-on-write. He notado que las nubes tambi\u00e9n tienen snapshots. Funcionan de manera diferente. Por ejemplo, en GCP: tienes una instancia de varios terabytes en la costa este de EE. UU. Haces snapshots peri\u00f3dicamente. Levantas una copia del disco desde un snapshot en la costa oeste: en unos minutos todo est\u00e1 listo y funciona muy r\u00e1pido, solo hay que llenar la cach\u00e9 en memoria. Pero esos clones (snapshots) son para poder 'provisionar' un nuevo volumen. Es genial cuando necesitas crear muchas instancias.<\/i><\/p>\n<p><i>Pero para pruebas, creo que los snapshots de los que hablas en Docker o los que yo menciono en ZFS, btrfs e incluso LVM\u2026 permiten realmente no generar nuevos datos en una sola m\u00e1quina. En la nube, adem\u00e1s, tienes que pagar por ellos cada vez y esperar ya no segundos, sino minutos (y en el caso de <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<\/a><\/noindex>, posiblemente, horas).<\/i><\/p>\n<p><i>En lugar de eso, puedes obtener esos datos en uno o dos segundos, ejecutar pruebas y descartarlas. Estas instant\u00e1neas resuelven diferentes tareas. En el primer caso \u2014 para escalar y obtener nuevas r\u00e9plicas, y en el segundo \u2014 para pruebas.<\/i><\/p>\n<p><b>DS<\/b>: No estoy de acuerdo. Hacer una clonaci\u00f3n completa de vol\u00famenes es una tarea de la nube. No he mirado su implementaci\u00f3n, pero s\u00e9 c\u00f3mo lo hacemos nosotros en hardware. Tenemos Ceph, y se puede indicar a cualquier volumen f\u00edsico (<noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ceph.com\/docs\/master\/rbd\/\">RBD<\/a><\/noindex>) <i>clone<\/i> y recibir en decenas de milisegundos un segundo volumen con las mismas caracter\u00edsticas, <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/IOPS\">IOPS<\/a><\/noindex>'s y dem\u00e1s. Hay que entender que ah\u00ed dentro hay un ingenioso copy-on-write. \u00bfPor qu\u00e9 la nube no lo har\u00eda tambi\u00e9n? Estoy seguro de que de alguna manera intentan hacerlo.<\/p>\n<p><i><b>HS<\/b>: Pero a\u00fan les llevar\u00e1 segundos, decenas de segundos, levantar una instancia, llevar ah\u00ed Docker, etc.<\/i><\/p>\n<p><b>DS<\/b>: \u00bfPor qu\u00e9 necesariamente levantar toda una instancia? Nosotros tenemos instancias de 32 n\u00facleos, de 16... y en ella cabe cierta cantidad, por ejemplo, cuatro. Cuando pedimos la quinta, ya se levantar\u00e1 una instancia y luego se eliminar\u00e1.<\/p>\n<p><i><b>HS<\/b>: S\u00ed, es interesante, en Kubernetes es otra historia. Nuestra base de datos no est\u00e1 en K8s, y tenemos una instancia. Sin embargo, para clonar una base de datos de varios terabytes no se tarda m\u00e1s de dos segundos.<\/i><\/p>\n<p><b>DS<\/b>: Eso es genial. Pero mi mensaje original es que esto no es una soluci\u00f3n gen\u00e9rica. S\u00ed, es impresionante, pero solo sirve para Postgres y solo en un nodo.<\/p>\n<p><i><b>HS<\/b>: No solo es para Postgres: estos planes, como describ\u00ed, funcionar\u00e1n solo en \u00e9l. Pero si no nos preocupamos por los planes y solo necesitamos todos los datos para pruebas funcionales, entonces esto sirve para cualquier SGBD.<\/i><\/p>\n<p><b>DS<\/b>: Hace muchos a\u00f1os hicimos algo parecido con instant\u00e1neas de LVM. Es un cl\u00e1sico. Este enfoque se utilizaba muy activamente. Simplemente, los nodos con estado son un problema. Porque no se pueden caer, siempre hay que recordar de ellos...<\/p>\n<p><i><b>HS<\/b>: \u00bfNo ves aqu\u00ed alguna posibilidad de hibridaci\u00f3n? Supongamos que el estado es un pod, funciona para varias personas (muchos testers). Tenemos un volumen, pero gracias al sistema de archivos, los clones son locales. Si el pod falla, el disco permanece; se levantar\u00e1 el pod, leer\u00e1 la informaci\u00f3n sobre todos los clones, lo levantar\u00e1 todo de nuevo y dir\u00e1: \u00abAqu\u00ed est\u00e1n sus clones en estos puertos, sigan trabajando con ellos\u00bb.<\/i><\/p>\n<p><b>DS<\/b>: T\u00e9cnicamente, esto significa que dentro de Kubernetes es un pod, dentro del cual ejecutamos muchos Postgres.<\/p>\n<p><i><b>HS<\/b>: S\u00ed. Tiene un l\u00edmite: supongamos que no m\u00e1s de 10 personas trabajan con \u00e9l al mismo tiempo. Si se necesitan 20, levantaremos un segundo pod de este tipo. Es completamente posible clonarlo, obteniendo un segundo volumen completo, en el cual habr\u00e1 10 clones \"delgados\" iguales. \u00bfNo ves esta posibilidad?<\/i><\/p>\n<p><b>DS<\/b>: Es necesario a\u00f1adir aqu\u00ed preguntas de seguridad. Esta opci\u00f3n de organizaci\u00f3n implica que este pod tiene altos privilegios (capabilities), porque puede realizar operaciones no est\u00e1ndar sobre el sistema de archivos\u2026 Pero repito: creo que a mediano plazo, Kubernetes resolver\u00e1 el tema del almacenamiento, en la nube se solucionar\u00e1 toda la historia con los vol\u00famenes \u2014 todo empezar\u00e1 a \u00abfuncionar de manera sencilla\u00bb. Habr\u00e1 resize, clonaci\u00f3n\u2026 Hay un volumen \u2014 decimos: \u00abCrea uno nuevo basado en ese\u00bb, \u2014 y en un segundo y medio obtenemos lo que necesitamos.<\/p>\n<p><i><b>HS<\/b>: No creo que sea posible en un segundo y medio para varios terabytes. En Ceph lo haces t\u00fa mismo, pero hablas de la nube. Ve a la nube, haz un cl\u00f3n de un volumen EBS de varios terabytes en EC2 y observa qu\u00e9 rendimiento obtienes. No tomar\u00e1 unos segundos. Me interesa mucho cu\u00e1ndo alcanzar\u00e1n ese indicador. Entiendo a lo que te refieres, pero me permitir\u00e9 no estar de acuerdo.<\/i><\/p>\n<p><b>DS<\/b>: Est\u00e1 bien, pero dije que a medio plazo, no a corto plazo. En un par de a\u00f1os.<\/p>\n<h2>Sobre el operador para PostgreSQL de Zalando<\/h2>\n<p>\nA mitad de esta reuni\u00f3n tambi\u00e9n se uni\u00f3 Alexey Klyukin, un exdesarrollador de Zalando, quien habl\u00f3 sobre la historia del operador PostgreSQL:<\/p>\n<blockquote><p>Es genial que se haya abordado este tema: tanto Postgres como Kubernetes. Cuando comenzamos a trabajarlo en Zalando en 2017, era un tema que todos quer\u00edan, pero nadie hac\u00eda. Todos ya contaban con Kubernetes, pero cuando se preguntaba c\u00f3mo manejar las bases de datos, incluso personas como <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kelseyhightower\">Kelsey Hightower<\/a><\/noindex>, que predicaban sobre K8s, dec\u00edan algo como esto:<\/p>\n<p><i>\u00abVe a los servicios administrados y util\u00edzalos, no ejecutes bases de datos en Kubernetes. De lo contrario, tu K8s decidir\u00e1, por ejemplo, hacer una actualizaci\u00f3n, apagar\u00e1 todos los nodos y tus datos se ir\u00e1n lejos, muy lejos\u00bb.<\/i><\/p>\n<p>Decidimos crear un operador que, en contra de ese consejo, ejecutar\u00eda bases de datos Postgres en Kubernetes. Y ten\u00edamos una buena base \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\">Patroni<\/a><\/noindex>. Este es un failover autom\u00e1tico para PostgreSQL, hecho correctamente, es decir, usando etcd, consul o ZooKeeper como almac\u00e9n de informaci\u00f3n del cl\u00faster. Un almac\u00e9n que devuelve a todos los que preguntan, por ejemplo, qui\u00e9n es el l\u00edder en este momento, la misma informaci\u00f3n \u2014 a pesar de que todo est\u00e1 distribuido \u2014 para evitar el split brain. Adem\u00e1s, tuvimos <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/patroni\/tree\/master\/docker\">imagen de Docker<\/a><\/noindex> para ello.<\/p>\n<p>En realidad, la necesidad de auto failover surgi\u00f3 en la empresa tras la migraci\u00f3n del centro de datos interno a la nube. La nube se bas\u00f3 en una soluci\u00f3n PaaS (Platform-as-a-Service) propia. Es de c\u00f3digo abierto, pero para implementarla, hubo que trabajar mucho. Se llamaba <noindex><a rel=\"nofollow\" href=\"https:\/\/stups.io\/\">STUPS<\/a><\/noindex>.<\/p>\n<p>Inicialmente no hab\u00eda Kubernetes. M\u00e1s bien, cuando se implement\u00f3 la soluci\u00f3n propia, K8s ya exist\u00eda, pero estaba tan inestable que no era adecuado para producci\u00f3n. Creo que fue en 2015 o 2016. Para 2017, Kubernetes se volvi\u00f3 m\u00e1s o menos maduro \u2014 surgi\u00f3 la necesidad de migrar all\u00ed.<\/p>\n<p>Y ya ten\u00edamos un contenedor Docker. Hab\u00eda una PaaS que utilizaba Docker. \u00bfPor qu\u00e9 no probar K8s? \u00bfPor qu\u00e9 no escribir nuestro propio operador? Murat Kabilov, que vino a nosotros de Avito, comenz\u00f3 esto como un proyecto por iniciativa propia: 'jugar un poco', y el proyecto 'despeg\u00f3'.<\/p>\n<p>Pero en realidad quer\u00eda hablar sobre AWS. \u00bfPor qu\u00e9 hab\u00eda c\u00f3digo hist\u00f3ricamente relacionado con AWS?<\/p>\n<p>Cuando lanzas algo en Kubernetes, necesitas entender que K8s es un trabajo en progreso. Est\u00e1 en constante desarrollo, mejora y a veces incluso se rompe. Debes estar atento a todos los cambios en Kubernetes y estar preparado para sumergirte en \u00e9l y aprender c\u00f3mo funciona en detalle, posiblemente m\u00e1s de lo que te gustar\u00eda. Esto aplica, en principio, a cualquier plataforma donde ejecutas tus bases de datos...<\/p>\n<p>As\u00ed que, cuando hicimos el operador, ten\u00edamos Postgres que trabajaba con un volumen externo (en este caso, EBS, ya que est\u00e1bamos en AWS). La base de datos creci\u00f3 y, en alg\u00fan momento, fue necesario hacer un cambio de tama\u00f1o: por ejemplo, el tama\u00f1o inicial de EBS era de 100 TB, la base lleg\u00f3 a ese tama\u00f1o y ahora quer\u00edamos hacer EBS de 200 TB. \u00bfC\u00f3mo? Supongamos que podr\u00edamos hacer un volcado\/restauraci\u00f3n en una nueva instancia, pero eso tarda y causa inactividad.<\/p>\n<p>Por eso quer\u00edamos un resize que aumentara la partici\u00f3n de EBS y luego indicara al sistema de archivos que utilizara el nuevo espacio. Y lo hicimos, pero en ese momento Kubernetes no ten\u00eda ninguna API para la operaci\u00f3n de resize. Como est\u00e1bamos trabajando en AWS, escribimos c\u00f3digo para su API.<\/p>\n<p>Nada impide hacer lo mismo para otras plataformas. En el operador no hay ninguna dependencia de que solo se pueda ejecutar en AWS, y que no funcione en todo lo dem\u00e1s. En resumen, es un proyecto de c\u00f3digo abierto: si alguien quiere acelerar la aparici\u00f3n de un nuevo uso de la API, es bienvenido. Hay <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zalando\/postgres-operator\">GitHub<\/a><\/noindex>, los pull requests \u2014 el equipo de Zalando intenta reaccionar r\u00e1pidamente a ellos y promover al operador. Hasta donde s\u00e9, el proyecto <noindex><a rel=\"nofollow\" href=\"https:\/\/summerofcode.withgoogle.com\/archive\/2019\/organizations\/6187982082539520\/\">particip\u00f3<\/a><\/noindex> en Google Summer of Code y otras iniciativas similares. Zalando est\u00e1 trabajando muy activamente en ello.\n<\/p><\/blockquote>\n<p><\/p>\n<h2>P.D. \u00a1Bonus!<\/h2>\n<p>\nSi te interesa el tema de PostgreSQL y Kubernetes, tambi\u00e9n queremos se\u00f1alar que la semana pasada tuvo lugar el pr\u00f3ximo Postgres Martes, donde Nikolay habl\u00f3 con <b>Alexander Kukushkin de Zalando<\/b>. El video est\u00e1 disponible <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=FE0xi7SBqsg\">aqu\u00ed<\/a><\/noindex>.<\/p>\n<h2>P.P.D.<\/h2>\n<p>\nTambi\u00e9n puedes leer en nuestro blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/431500\/\">Bases de datos y Kubernetes (rese\u00f1a y video de la presentaci\u00f3n)<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/475036\/\">Migraci\u00f3n de Cassandra en Kubernetes: caracter\u00edsticas y soluciones<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/461149\/\">Migraci\u00f3n sin complicaciones de MongoDB a Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/450662\/\">Migraci\u00f3n no trivial de RabbitMQ en Kubernetes<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Fuente: <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.2 - 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\/es\/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.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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 Martes #5: \u00abPostgreSQL y Kubernetes. CI\/CD. Automatizaci\u00f3n de pruebas\u00bb | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/postgres-vtornik-5-postgresql-i-kubernetes-ci-cd-avtomatizatsiya-testirovaniya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/55467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=55467"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/55467\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/55468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=55467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=55467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=55467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}