Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência

Cada vez mais, os clientes recebem as seguintes solicitações: “Queremos como o Amazon RDS, mas mais barato”; “Queremos que seja como o RDS, mas em qualquer lugar, em qualquer infraestrutura.” Para implementar tal solução gerenciada no Kubernetes, analisamos o estado atual dos operadores mais populares para PostgreSQL (Stolon, operadores de Crunchy Data e Zalando) e fizemos nossa escolha.

Este artigo é a experiência que adquirimos tanto do ponto de vista teórico (revisão de soluções) quanto do lado prático (o que foi escolhido e o que resultou). Mas primeiro, vamos determinar quais são os requisitos gerais para um potencial substituto do RDS...

O que é RDS

Quando as pessoas falam sobre RDS, em nossa experiência, elas se referem a um serviço gerenciado de SGBD que:

  1. fácil de configurar;
  2. tem a capacidade de trabalhar com instantâneos e recuperá-los (de preferência com suporte PITR);
  3. permite criar topologias mestre-escravo;
  4. possui uma rica lista de extensões;
  5. fornece auditoria e gerenciamento de usuários/acessos.

De modo geral, as abordagens para implementar a tarefa em questão podem ser muito diferentes, mas o caminho com o Ansible condicional não está próximo de nós. (Colegas do 2GIS chegaram a uma conclusão semelhante como resultado sua tentativa crie "uma ferramenta para implantar rapidamente um cluster de failover baseado em Postgres.")

Os operadores são uma abordagem comum para resolver problemas semelhantes no ecossistema Kubernetes. O diretor técnico da “Flanta” já falou mais detalhadamente sobre eles em relação aos bancos de dados lançados dentro do Kubernetes. distolEm um de seus relatórios.

NB: Para criar operadores simples rapidamente, recomendamos prestar atenção ao nosso utilitário Open Source operador shell. Usando-o, você pode fazer isso sem conhecimento de Go, mas de maneiras mais familiares aos administradores de sistema: em Bash, Python, etc.

Existem vários operadores K8s populares para PostgreSQL:

  • Estolão;
  • Operador PostgreSQL de dados crocantes;
  • Operador Zalando Postgres.

Vamos examiná-los mais de perto.

Seleção de operador

Além dos recursos importantes já mencionados acima, nós - como engenheiros de operações de infraestrutura do Kubernetes - também esperávamos o seguinte dos operadores:

  • implantação do Git e com Recursos personalizados;
  • suporte anti-afinidade de pod;
  • instalar afinidade de nó ou seletor de nó;
  • instalação de tolerâncias;
  • disponibilidade de recursos de ajuste;
  • tecnologias compreensíveis e até comandos.

Sem entrar em detalhes sobre cada um dos pontos (pergunte nos comentários se ainda tiver dúvidas sobre eles depois de ler o artigo inteiro), observarei em geral que esses parâmetros são necessários para descrever com mais precisão a especialização dos nós do cluster, a fim de solicite-os para aplicações específicas. Desta forma, podemos alcançar o equilíbrio ideal em termos de desempenho e custo.

Agora vamos passar para os próprios operadores do PostgreSQL.

1. Roubo

estolão da empresa italiana Sorint.lab em relatório já mencionado foi considerado uma espécie de padrão entre os operadores de SGBD. Este é um projeto bastante antigo: seu primeiro lançamento público ocorreu em novembro de 2015(!), e o repositório GitHub possui quase 3000 estrelas e mais de 40 colaboradores.

Na verdade, Stolon é um excelente exemplo de arquitetura cuidadosa:

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência
O dispositivo desta operadora pode ser encontrado detalhadamente no relatório ou Documentação do projeto. Em geral, basta dizer que ele pode fazer tudo o que foi descrito: failover, proxies para acesso transparente do cliente, backups... Além disso, os proxies fornecem acesso através de um serviço de endpoint - ao contrário das outras duas soluções discutidas abaixo (cada uma delas tem dois serviços para acessando a base).

No entanto, Stolon sem recursos personalizados, e é por isso que não pode ser implantado de forma que seja fácil e rápido – “como bolos quentes” – criar instâncias de DBMS no Kubernetes. O gerenciamento é feito através da concessionária stolonctl, a implantação é feita por meio do gráfico Helm e as customizadas são definidas e especificadas no ConfigMap.

Por um lado, verifica-se que o operador não é realmente um operador (afinal, não utiliza CRD). Mas por outro lado, é um sistema flexível que permite configurar recursos em K8s como achar melhor.

Resumindo, para nós pessoalmente não parecia ideal criar um gráfico separado para cada banco de dados. Portanto, começamos a buscar alternativas.

2. Operador PostgreSQL de dados crocantes

Operador de Crunchy Data, uma jovem startup americana, parecia uma alternativa lógica. Sua história pública começa com o primeiro lançamento em março de 2017, desde então o repositório GitHub recebeu pouco menos de 1300 estrelas e mais de 50 colaboradores. A versão mais recente de setembro foi testada para funcionar com Kubernetes 1.15-1.18, OpenShift 3.11+ e 4.4+, GKE e VMware Enterprise PKS 1.3+.

A arquitetura do Crunchy Data PostgreSQL Operator também atende aos requisitos declarados:

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência

O gerenciamento ocorre através da concessionária pgo, no entanto, ele, por sua vez, gera recursos personalizados para Kubernetes. Portanto, a operadora nos agradou como potenciais usuários:

  • há controle via CRD;
  • gerenciamento conveniente de usuários (também via CRD);
  • integração com outros componentes Pacote de contêineres de dados crocantes — uma coleção especializada de imagens de contêiner para PostgreSQL e utilitários para trabalhar com ele (incluindo pgBackRest, pgAudit, extensões do contrib, etc.).

No entanto, as tentativas de começar a usar o operador da Crunchy Data revelaram vários problemas:

  • Não houve possibilidade de tolerâncias - apenas o nodeSelector é fornecido.
  • Os pods criados faziam parte da implantação, apesar de termos implantado um aplicativo com estado. Ao contrário dos StatefulSets, as implantações não podem criar discos.

A última desvantagem leva a momentos engraçados: no ambiente de teste conseguimos rodar 3 réplicas com um disco armazenamento local, fazendo com que o operador informasse que 3 réplicas estavam funcionando (mesmo que não estivessem).

Outra característica deste operador é a sua integração pronta com diversos sistemas auxiliares. Por exemplo, é fácil instalar o pgAdmin e o pgBounce, e em documentação Grafana e Prometheus pré-configurados são considerados. Recentemente versão 4.5.0-beta1 A melhoria da integração com o projeto é observada separadamente pgMonitor, graças ao qual o operador oferece uma visualização clara das métricas PgSQL prontas para uso.

Porém, a estranha escolha dos recursos gerados pelo Kubernetes levou-nos à necessidade de encontrar uma solução diferente.

3. Operador Zalando Postgres

Conhecemos os produtos Zalando há muito tempo: temos experiência na utilização do Zalenium e, claro, experimentámos Patroni é sua solução HA popular para PostgreSQL. Sobre a abordagem da empresa para criar Operador Postgres um de seus autores, Alexey Klyukin, disse no ar Postgres-Terça-feira #5, e gostamos.

Esta é a solução mais nova discutida no artigo: o primeiro lançamento ocorreu em agosto de 2018. Porém, mesmo apesar do pequeno número de lançamentos formais, o projeto percorreu um longo caminho, já superando em popularidade a solução da Crunchy Data com mais de 1300 estrelas no GitHub e o número máximo de colaboradores (70+).

“Sob o capô”, este operador usa soluções testadas pelo tempo:

É assim que se apresenta a arquitetura do operador do Zalando:

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência

O operador é totalmente gerenciado por meio de Recursos Personalizados, cria automaticamente um StatefulSet a partir de contêineres, que pode então ser personalizado adicionando vários sidecars ao pod. Tudo isso é uma vantagem significativa em comparação com a operadora da Crunchy Data.

Dado que escolhemos a solução da Zalando entre as 3 opções em consideração, a seguir será apresentada uma descrição mais detalhada das suas capacidades, imediatamente juntamente com a prática de aplicação.

Pratique com o Operador Postgres da Zalando

A implantação do operador é muito simples: basta baixar a versão atual do GitHub e aplicar os arquivos YAML do diretório manifestos. Alternativamente, você também pode usar Operador Hub.

Após a instalação, você deve se preocupar em configurar armazenamento para logs e backups. Isso é feito através do ConfigMap postgres-operator no namespace onde você instalou o operador. Depois que os repositórios estiverem configurados, você poderá implantar seu primeiro cluster PostgreSQL.

Por exemplo, nossa implantação padrão é assim:

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 implanta um cluster de 3 instâncias com um arquivo secundário no formato postgres_exportador, do qual extraímos métricas de aplicação. Como você pode ver, tudo é muito simples e, se desejar, você pode criar um número literalmente ilimitado de clusters.

Vale a pena prestar atenção painel de administração web - postgres-operador-ui. Ele vem com a operadora e permite criar e excluir clusters, bem como trabalhar com backups feitos pela operadora.

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência
Lista de clusters PostgreSQL

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência
Gerenciamento de backup

Outra característica interessante é o suporte API Teams. Este mecanismo cria automaticamente funções no PostgreSQL, com base na lista resultante de nomes de usuários. A API permite retornar uma lista de usuários para os quais as funções são criadas automaticamente.

Problemas e soluções

No entanto, o uso do operador logo revelou várias deficiências significativas:

  1. falta de suporte ao nodeSelector;
  2. incapacidade de desabilitar backups;
  3. ao utilizar a função de criação de banco de dados, os privilégios padrão não aparecem;
  4. Às vezes, a documentação está faltando ou está desatualizada.

Felizmente, muitos deles podem ser resolvidos. Vamos começar pelo fim - problemas com documentação.

Provavelmente, você descobrirá que nem sempre é claro como registrar um backup e como conectar o bucket de backup à UI do Operador. A documentação fala sobre isso de passagem, mas a descrição real está em PR:

  1. precisa fazer um segredo;
  2. passe-o para o operador como parâmetro pod_environment_secret_name no CRD com configurações do operador ou no ConfigMap (dependendo de como você decidir instalar o operador).

No entanto, ao que parece, isso é atualmente impossível. É por isso que coletamos sua versão da operadora com alguns desenvolvimentos adicionais de terceiros. Para mais informações sobre isso, veja abaixo.

Se você passar os parâmetros de backup para a operadora, a saber - wal_s3_bucket e chaves de acesso no AWS S3, então fará backup de tudo: não apenas bases na produção, mas também na encenação. Isso não nos convinha.

Na descrição dos parâmetros do Spilo, que é o wrapper básico do Docker para PgSQL ao usar o operador, descobriu-se: você pode passar um parâmetro WAL_S3_BUCKET vazio, desabilitando assim os backups. Além disso, para grande alegria, descobri relações públicas prontas, que aceitamos imediatamente em nosso fork. Agora você só precisa adicionar enableWALArchiving: false para um recurso de cluster PostgreSQL.

Sim, houve uma oportunidade de fazer diferente executando 2 operadores: um para teste (sem backups) e outro para produção. Mas conseguimos nos contentar com um.

Ok, aprendemos como transferir o acesso aos bancos de dados para S3 e os backups começaram a entrar no armazenamento. Como fazer as páginas de backup funcionarem na UI do Operador?

Uma breve visão geral das instruções do PostgreSQL para Kubernetes, nossas escolhas e experiência

Você precisará adicionar três variáveis ​​à IU do Operador:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Depois disso, ficará disponível o gerenciamento de backups, o que no nosso caso simplificará o trabalho com o staging, permitindo-nos entregar ali slices da produção sem scripts adicionais.

Outra vantagem foi o trabalho com a API Teams e amplas oportunidades de criação de bancos de dados e funções por meio de ferramentas de operação. No entanto, o criado as funções não tinham direitos por padrão. Conseqüentemente, um usuário com direitos de leitura não poderia ler novas tabelas.

Por que é que? Apesar do fato de que no código tem necessário GRANT, eles nem sempre são usados. Existem 2 métodos: syncPreparedDatabases и syncDatabases. Em syncPreparedDatabases - apesar do fato de que na seção preparedDatabases tem há uma condição defaultRoles и defaultUsers para criar funções, os direitos padrão não são aplicados. Estamos preparando um patch para que esses direitos sejam aplicados automaticamente.

E o último ponto das melhorias que são relevantes para nós - remendo, que adiciona Node Affinity ao StatefulSet criado. Nossos clientes geralmente preferem reduzir custos usando instâncias spot e claramente não vale a pena hospedar serviços de banco de dados. Este problema poderia ser resolvido através de tolerâncias, mas a presença do Node Affinity dá maior confiança.

O que aconteceu?

Com base nos resultados da solução dos problemas acima, bifurcamos o Operador Postgres do Zalando em seu repositório, onde é coletado com esses patches úteis. E para maior comodidade, também coletamos Imagem do Docker.

Lista de PRs aceitos no fork:

Será ótimo se a comunidade apoiar esses PRs para que eles sejam atualizados com a próxima versão do operador (1.6).

Bônus! História de sucesso de migração de produção

Se você usar o Patroni, a produção ao vivo poderá ser migrada para a operadora com tempo de inatividade mínimo.

Spilo permite criar clusters em espera por meio de armazenamento S3 com Wal-E, quando o log binário do PgSQL é armazenado pela primeira vez no S3 e depois bombeado pela réplica. Mas o que fazer se você tiver não usado pelo Wal-E em infraestrutura antiga? A solução para este problema já está foi sugerido no centro.

A replicação lógica do PostgreSQL vem em socorro. Porém, não entraremos em detalhes sobre como criar publicações e assinaturas, porque... nosso plano foi um fiasco.

O fato é que o banco de dados possuía diversas tabelas carregadas com milhões de linhas, que, além disso, eram constantemente reabastecidas e excluídas. Assinatura simples с copy_data, quando a nova réplica copia todo o conteúdo do mestre, ela simplesmente não consegue acompanhar o mestre. Copiar conteúdo funcionou por uma semana, mas nunca alcançou o mestre. No final, isso me ajudou a resolver o problema artigo colegas do Avito: você pode transferir dados usando pg_dump. Descreverei nossa versão (ligeiramente modificada) deste algoritmo.

A ideia é que você possa fazer uma assinatura desabilitada vinculada a um slot de replicação específico e, em seguida, corrigir o número da transação. Havia réplicas disponíveis para trabalhos de produção. Isso é importante porque a réplica ajudará a criar um dump consistente e continuará a receber alterações do mestre.

Os comandos subsequentes que descrevem o processo de migração usarão as seguintes notações de host:

  1. dominar — servidor de origem;
  2. réplica1 — streaming de réplica da produção antiga;
  3. réplica2 - nova réplica lógica.

Plano de migração

1. Crie uma assinatura no mestre para todas as tabelas do esquema public bases dbname:

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

2. Crie um slot de replicação no mestre:

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

3. Pare a replicação na réplica antiga:

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

4. Obtenha o número da transação do mestre:

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

5. Remova o dump da réplica antiga. Faremos isso em vários tópicos, o que ajudará a agilizar o processo:

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

6. Faça upload do dump para o novo servidor:

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

7. Depois de baixar o dump, você pode iniciar a replicação na réplica de streaming:

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

7. Vamos criar uma assinatura em uma nova réplica lógica:

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 lá oid assinaturas:

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

9. Digamos que foi recebido oid=1000. Vamos aplicar o número da transação à assinatura:

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

10. Vamos começar a replicação:

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

11. Verifique o status da assinatura, a replicação deve 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. Após o início da replicação e a sincronização dos bancos de dados, você poderá alternar.

13. Após desabilitar a replicação, é necessário corrigir as sequências. Isso está bem descrito no artigo em wiki.postgresql.org.

Graças a este plano, a transição ocorreu com atrasos mínimos.

Conclusão

Os operadores Kubernetes permitem simplificar diversas ações, reduzindo-as à criação de recursos K8s. Porém, tendo alcançado uma automação notável com a ajuda deles, vale lembrar que ela também pode trazer uma série de nuances inesperadas, por isso escolha seus operadores com sabedoria.

Tendo considerado os três operadores Kubernetes mais populares para PostgreSQL, escolhemos o projeto de Zalando. E tivemos que superar algumas dificuldades com isso, mas o resultado foi muito agradável, por isso planejamos expandir essa experiência para algumas outras instalações do PgSQL. Se você tem experiência no uso de soluções semelhantes, teremos prazer em ver os detalhes nos comentários!

PS

Leia também em nosso blog:

Fonte: habr.com

Compre hospedagem confiável para sites com proteção DDoS, servidores VPS VDS 🔥 Compre hospedagem de sites confiável com proteção contra DDoS, servidores VPS/VDS | ProHoster