Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia

Cada vez máis, os clientes están a recibir as seguintes solicitudes: "Querémolo como Amazon RDS, pero máis barato"; "Querémolo como RDS, pero en todas partes, en calquera infraestrutura". Para implementar esta solución xestionada en Kubernetes, analizamos o estado actual dos operadores máis populares para PostgreSQL (Stolon, operadores de Crunchy Data e Zalando) e escollemos.

Este artigo é a experiencia que adquirimos tanto desde o punto de vista teórico (revisión de solucións) como desde o lado práctico (o que se escolleu e o que saíu). Pero primeiro, imos determinar cales son os requisitos xerais para un substituto potencial de RDS...

Que é RDS

Cando a xente fala de RDS, na nosa experiencia, refírese a un servizo de DBMS xestionado que:

  1. fácil de configurar;
  2. ten a capacidade de traballar con instantáneas e recuperarse delas (preferentemente con soporte PITR);
  3. permítelle crear topoloxías mestre-escravo;
  4. ten unha rica lista de extensións;
  5. proporciona auditoría e xestión de usuarios/acceso.

En xeral, os enfoques para implementar a tarefa en cuestión poden ser moi diferentes, pero o camiño con Ansible condicional non está preto de nós. (Os colegas de 2GIS chegaron a unha conclusión similar como resultado o seu intento crear "unha ferramenta para implementar rapidamente un clúster de conmutación por fallo baseado en Postgres").

Os operadores son un enfoque común para resolver problemas similares no ecosistema de Kubernetes. O director técnico de “Flanta” xa falou con máis detalle sobre eles en relación ás bases de datos lanzadas dentro de Kubernetes. distolEn un dos seus informes.

NB: Para crear rapidamente operadores sinxelos, recomendamos prestar atención á nosa utilidade de código aberto operador de shell. Usalo, podes facelo sen coñecementos de Go, pero dun xeito máis familiar para os administradores do sistema: en Bash, Python, etc.

Hai varios operadores K8s populares para PostgreSQL:

  • Estolón;
  • Crunchy Data Operador PostgreSQL;
  • Operador Zalando Postgres.

Mirámolos máis de preto.

Selección do operador

Ademais das importantes características xa mencionadas anteriormente, nós, como enxeñeiros de operacións de infraestruturas de Kubernetes, tamén esperamos o seguinte dos operadores:

  • implementación desde Git e con Recursos personalizados;
  • soporte anti-afinidade de pod;
  • instalar a afinidade de nodos ou selector de nodos;
  • instalación de tolerancias;
  • dispoñibilidade de capacidades de sintonización;
  • tecnoloxías comprensibles e mesmo comandos.

Sen entrar en detalles sobre cada un dos puntos (pregunta nos comentarios se aínda tes dúbidas sobre eles despois de ler todo o artigo), notarei en xeral que estes parámetros son necesarios para describir con máis precisión a especialización dos nodos do clúster co fin de ordenalos para aplicacións específicas. Deste xeito podemos conseguir o equilibrio óptimo en termos de rendemento e custo.

Agora pasemos aos propios operadores PostgreSQL.

1. Estolón

Estolon da empresa italiana Sorint.lab in informe xa mencionado foi considerado como unha especie de estándar entre os operadores para DBMS. Este é un proxecto bastante antigo: o seu primeiro lanzamento público tivo lugar en novembro de 2015 (!), e o repositorio de GitHub conta con case 3000 estrelas e máis de 40 colaboradores.

De feito, Stolon é un excelente exemplo de arquitectura reflexiva:

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia
O dispositivo deste operador pódese atopar en detalle no informe ou documentación do proxecto. En xeral, abonda con dicir que pode facer todo o que se describe: failover, proxies para o acceso transparente de clientes, copias de seguridade... Ademais, os proxies proporcionan acceso a través dun servizo de punto final, a diferenza das outras dúas solucións que se comentan a continuación (cada unha ten dous servizos para base de acceso).

Porén, Stolon sen recursos personalizados, polo que non se pode implementar de tal xeito que sexa fácil e rápido - "como tortas quentes" - crear instancias de DBMS en Kubernetes. A xestión realízase a través da utilidade stolonctl, a implantación realízase a través do gráfico Helm e defínense e especifican os personalizados en ConfigMap.

Por unha banda, resulta que o operador non é realmente un operador (despois de todo, non usa CRD). Pero, por outra banda, trátase dun sistema flexible que permite configurar os recursos en K8s como creas oportuno.

En resumo, para nós persoalmente non nos pareceu óptimo crear un gráfico separado para cada base de datos. Por iso, comezamos a buscar alternativas.

2. Crunchy Data Operador PostgreSQL

Operador de Crunchy Data, unha nova startup estadounidense, parecía unha alternativa lóxica. A súa historia pública comeza coa primeira versión en marzo de 2017, desde entón o repositorio de GitHub recibiu algo menos de 1300 estrelas e máis de 50 colaboradores. A última versión de setembro probouse para funcionar con Kubernetes 1.15-1.18, OpenShift 3.11+ e 4.4+, GKE e VMware Enterprise PKS 1.3+.

A arquitectura de Crunchy Data PostgreSQL Operator tamén cumpre os requisitos indicados:

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia

A xestión realízase a través da utilidade pgo, porén, á súa vez xera Recursos personalizados para Kubernetes. Polo tanto, a operadora agradou como posibles usuarios:

  • hai control mediante CRD;
  • xestión de usuarios conveniente (tamén a través de CRD);
  • integración con outros compoñentes Crunchy Data Container Suite — unha colección especializada de imaxes de contedores para PostgreSQL e utilidades para traballar con ela (incluíndo pgBackRest, pgAudit, extensións de contrib, etc.).

Non obstante, os intentos de comezar a usar o operador de Crunchy Data revelaron varios problemas:

  • Non había posibilidade de tolerancias - só se proporciona nodeSelector.
  • Os pods creados formaban parte de Deployment, a pesar de que implantamos unha aplicación con estado. A diferenza de StatefulSets, as implementacións non poden crear discos.

O último inconveniente leva a momentos divertidos: no ambiente de proba conseguimos executar 3 réplicas cun só disco almacenamento local, facendo que o operador informase de que 3 réplicas estaban funcionando (aínda que non).

Outra característica deste operador é a súa integración preparada con varios sistemas auxiliares. Por exemplo, é fácil instalar pgAdmin e pgBounce, e en documentación considéranse Grafana e Prometheus preconfigurados. En recentes versión 4.5.0-beta1 Nótase por separado a mellora da integración co proxecto pgMonitor, grazas ao cal o operador ofrece unha visualización clara das métricas de PgSQL fóra da caixa.

Non obstante, a estraña elección dos recursos xerados por Kubernetes levounos á necesidade de buscar unha solución diferente.

3. Operador Zalando Postgres

Coñecemos os produtos de Zalando dende hai tempo: temos experiencia no uso de Zalenium e, por suposto, probámolo Patroi é a súa popular solución de alta disponibilidad para PostgreSQL. Sobre o enfoque da empresa para crear Operador Postgres un dos seus autores, Alexey Klyukin, dixo ao aire Postgres-Martes #5, e gustounos.

Esta é a solución máis nova discutida no artigo: o primeiro lanzamento tivo lugar en agosto de 2018. Non obstante, a pesar do pequeno número de lanzamentos formais, o proxecto percorreu un longo camiño, superando xa en popularidade a solución de Crunchy Data con máis de 1300 estrelas en GitHub e o número máximo de colaboradores (70+).

"Debaixo do capó" este operador utiliza solucións probadas no tempo:

  • Patroni e Spilo Para conducir,
  • WAL-E - para copias de seguridade,
  • PgBouncer - como grupo de conexión.

Así se presenta a arquitectura de operador de Zalando:

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia

O operador está totalmente xestionado a través de Recursos personalizados, crea automaticamente un StatefulSet a partir de contedores, que despois se pode personalizar engadindo varios sidecars ao pod. Todo isto é unha vantaxe significativa en comparación co operador de Crunchy Data.

Dado que escollemos a solución de Zalando entre as 3 opcións en consideración, a continuación presentarase unha descrición máis detallada das súas capacidades, inmediatamente xunto coa práctica da aplicación.

Practica con Postgres Operator de Zalando

A implantación do operador é moi sinxela: basta con descargar a versión actual de GitHub e aplicar os ficheiros YAML do directorio manifesta. Alternativamente, tamén podes usar operadorhub.

Despois da instalación, debes preocuparte pola configuración almacenamento para rexistros e copias de seguridade. Isto faise a través de ConfigMap postgres-operator no espazo de nomes onde instalou o operador. Unha vez configurados os repositorios, pode implantar o seu primeiro clúster PostgreSQL.

Por exemplo, a nosa implementación estándar ten o seguinte aspecto:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

Este manifesto desprega un grupo de 3 instancias cun sidecar no formulario postgres_exporter, do que tomamos as métricas da aplicación. Como podes ver, todo é moi sinxelo e, se o desexas, podes crear un número literalmente ilimitado de clusters.

Paga a pena prestarlle atención panel de administración web - postgres-operator-ui. Vén co operador e permítelle crear e eliminar clústeres, así como traballar con copias de seguridade realizadas polo operador.

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia
Lista de clústeres PostgreSQL

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia
Xestión de copias de seguridade

Outra característica interesante é o soporte API de equipos. Este mecanismo crea automaticamente roles en PostgreSQL, baseándose na lista resultante de nomes de usuario. A API permite entón devolver unha lista de usuarios para os que se crean roles automaticamente.

Problemas e solucións

Non obstante, o uso do operador pronto revelou varias deficiencias importantes:

  1. falta de compatibilidade con nodeSelector;
  2. incapacidade para desactivar as copias de seguridade;
  3. cando se utiliza a función de creación de base de datos, os privilexios predeterminados non aparecen;
  4. Ás veces falta documentación ou está desactualizada.

Afortunadamente, moitos deles pódense resolver. Imos comezar polo final - problemas con documentación.

O máis probable é que atopes o feito de que non sempre está claro como rexistrar unha copia de seguridade e como conectar o balde de copia de seguridade á IU do operador. A documentación fala diso de paso, pero a descrición real está na PR:

  1. necesidade de facer un segredo;
  2. pasalo ao operador como parámetro pod_environment_secret_name no CRD coa configuración do operador ou en ConfigMap (dependendo de como decida instalar o operador).

Non obstante, polo que se ve, isto é actualmente imposible. Por iso recollemos a súa versión do operador con algúns desenvolvementos adicionais de terceiros. Para obter máis información ao respecto, consulte a continuación.

Se pasa os parámetros para a copia de seguridade ao operador, é dicir: wal_s3_bucket e claves de acceso en AWS S3, despois el fará unha copia de seguridade de todo: non só bases na produción, senón tamén na posta en escena. Isto non nos conviña.

Na descrición dos parámetros de Spilo, que é o envoltorio básico de Docker para PgSQL cando se usa o operador, resultou: pode pasar un parámetro WAL_S3_BUCKET baleiro, desactivando así as copias de seguridade. Ademais, para moita alegría, atopeino listo PR, que aceptamos inmediatamente no noso garfo. Agora só tes que engadir enableWALArchiving: false a un recurso de clúster PostgreSQL.

Si, houbo unha oportunidade de facelo doutro xeito executando 2 operadores: un para a posta en escena (sen copias de seguridade) e o segundo para a produción. Pero puidemos conformarnos cun.

Ok, aprendemos a transferir o acceso ás bases de datos para S3 e as copias de seguridade comezaron a almacenarse. Como facer que as páxinas de copia de seguranza funcionen na interface de usuario do operador?

Unha breve visión xeral das declaracións PostgreSQL para Kubernetes, as nosas opcións e experiencia

Terás que engadir 3 variables á IU do operador:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Despois disto, estará dispoñible a xestión das copias de seguridade, o que no noso caso simplificará o traballo coa posta en escena, permitíndonos entregar alí partes da produción sen scripts adicionais.

Outra vantaxe foi o traballo coa API de Teams e amplas oportunidades para crear bases de datos e roles utilizando ferramentas de operador. Porén, o creado roles non tiñan dereitos por defecto. En consecuencia, un usuario con dereitos de lectura non podía ler novas táboas.

Por que é iso? A pesar de que no código ten necesario GRANT, non sempre se usan. Hai 2 métodos: syncPreparedDatabases и syncDatabases. En syncPreparedDatabases - a pesar de que no apartado preparedDatabases ten hai unha condición defaultRoles и defaultUsers para crear roles, non se aplican os dereitos predeterminados. Estamos en proceso de preparar un parche para que estes dereitos se apliquen automaticamente.

E o último punto das melloras que son relevantes para nós - parche, que engade Node Affinity ao StatefulSet creado. Os nosos clientes a miúdo prefiren reducir os custos utilizando instancias puntuales, e claramente non pagan a pena hospedar servizos de bases de datos. Este problema podería resolverse mediante tolerancias, pero a presenza de Node Affinity dá unha maior confianza.

Que pasou?

En base aos resultados da resolución dos problemas anteriores, introducimos o operador Postgres de Zalando o teu repositorio, onde se recolle con parches tan útiles. E para maior comodidade, tamén recollemos Imaxe de Docker.

Lista de PR aceptados no fork:

Será xenial que a comunidade admita estes PRs para que suban coa seguinte versión do operador (1.6).

Bonificación! Caso de éxito da migración da produción

Se usas Patroni, a produción en directo pódese migrar ao operador cun tempo de inactividade mínimo.

Spilo permítelle crear clústeres en espera mediante o almacenamento S3 con Wal-E, cando o rexistro binario de PgSQL se almacena por primeira vez en S3 e despois é bombeado pola réplica. Pero que facer se tes non utilizado por Wal-E en infraestruturas antigas? A solución a este problema xa está suxeriuse no hub.

A replicación lóxica de PostgreSQL vén ao rescate. Non obstante, non entraremos en detalles sobre como crear publicacións e subscricións, porque... o noso plan foi un fiasco.

O caso é que a base de datos tiña varias táboas cargadas con millóns de filas, que, ademais, reabastecíanse e eliminaban constantemente. Subscrición sinxela с copy_data, cando a nova réplica copia todos os contidos do mestre, simplemente non pode seguir o ritmo do mestre. A copia de contido funcionou durante unha semana, pero nunca chegou ao mestre. Ao final, axudoume a resolver o problema artigo compañeiros de Avito: podes transferir datos usando pg_dump. Vou describir a nosa versión (lixeiramente modificada) deste algoritmo.

A idea é que pode facer unha subscrición desactivada vinculada a un slot de replicación específico e, a continuación, corrixir o número de transacción. Había réplicas dispoñibles para o traballo de produción. Isto é importante porque a réplica axudará a crear un volcado consistente e seguirá recibindo cambios do mestre.

Os comandos posteriores que describen o proceso de migración usarán as seguintes notacións de host:

  1. mestre - servidor fonte;
  2. réplica 1 — réplica de streaming na produción antiga;
  3. réplica 2 - nova réplica lóxica.

Plan migratorio

1. Cree unha subscrición no mestre para todas as táboas do esquema public base dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. Cree un slot de replicación no mestre:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. Deter a replicación na réplica antiga:

psql -h replica1 -c "select pg_wal_replay_pause();"

4. Obtén o número de transacción do mestre:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. Elimina o vertedoiro da réplica antiga. Farémolo en varios fíos, o que axudará a acelerar o proceso:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. Cargue o volcado ao novo servidor:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. Despois de descargar o volcado, podes comezar a replicación na réplica de streaming:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. Imos crear unha subscrición nunha nova réplica lóxica:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. Vamos oid subscricións:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. Digamos que foi recibido oid=1000. Apliquemos o número de transacción á subscrición:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10. Comecemos a replicación:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. Comprobe o estado da subscrición, a replicación debería funcionar:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. Despois de iniciar a replicación e sincronizar as bases de datos, pode cambiar.

13. Despois de desactivar a replicación, cómpre corrixir as secuencias. Isto está ben descrito no artigo en wiki.postgresql.org.

Grazas a este plan, o cambio produciuse cun mínimo atraso.

Conclusión

Os operadores de Kubernetes permítenche simplificar varias accións reducíndoas á creación de recursos K8s. Non obstante, tendo conseguido unha notable automatización coa súa axuda, vale a pena lembrar que tamén pode traer unha serie de matices inesperados, polo que elixe os teus operadores con prudencia.

Considerando os tres operadores de Kubernetes máis populares para PostgreSQL, escollemos o proxecto de Zalando. E tivemos que superar certas dificultades con el, pero o resultado foi realmente agradable, polo que pensamos ampliar esta experiencia a outras instalacións de PgSQL. Se tes experiencia usando solucións similares, estaremos encantados de ver os detalles nos comentarios!

PS

Lea tamén no noso blog:

Fonte: www.habr.com

Engadir un comentario