Construindo um cluster PostgreSQL de alta disponibilidade usando Patroni, etcd, HAProxy

Aconteceu que, no momento de definir o problema, eu não tinha um grau de experiência suficiente para desenvolver e executar esta solução sozinho. E então eu comecei a pesquisar no Google.


Não sei qual é o problema, mas, pela enésima vez, sou confrontado com o fato de que, mesmo que você faça tudo passo a passo como no tutorial, prepare o mesmo ambiente do autor, nada funcionará. Não tenho ideia do que se trata, mas quando me deparei com isso novamente, decidi - e escreverei meu tutorial quando tudo der certo. Um que definitivamente funcionará.


Guias on-line


Aconteceu que a Internet não sofre com a falta de vários guias, tutoriais, passo a passo e similares. Aconteceu que me incumbiram de desenvolver uma solução para a organização e construção convenientes de um cluster PostgreSQL à prova de falhas, cujos principais requisitos eram transmitir a replicação do servidor Master para todas as réplicas e entrada automática da reserva quando o servidor Mestre falhou.


Nesta fase, a pilha de tecnologias utilizadas foi definida:


  • PostgreSQL como DBMS
  • Patroni como uma solução de cluster
  • etcd como armazenamento distribuído para o Patroni
  • HAproxy para organizar um único ponto de entrada para aplicativos que usam o banco de dados

Instalação


Sua atenção - a construção de um cluster PostgreSQL de alta disponibilidade usando Patroni, etcd, HAProxy.


Todas as operações foram realizadas em máquinas virtuais com o Debian 10 instalado.


etcd


Não recomendo instalar o etcd nas mesmas máquinas em que o patroni e o postgresql estarão localizados, pois a carga do disco é muito importante para o etcd. Mas, para fins de treinamento, faremos exatamente isso.
Instale o etcd.


#!/bin/bash apt-get update apt-get install etcd 

Adicione o conteúdo ao arquivo / etc / default / etcd

[membro]


ETCD_NAME = datanode1 # hostname da sua máquina
ETCD_DATA_DIR = "/ var / lib / etcd / default.etcd"


TODOS OS ENDEREÇOS DE IP DEVEM SER VÁLIDOS. LISTER PEER, CLIENTE etc DEVE SER CONFIGURADO PARA ENDEREÇO ​​IP DO HOST


ETCD_LISTEN_PEER_URLS = " http://192.168.0.143:2380 " # o endereço da sua máquina
ETCD_LISTEN_CLIENT_URLS = " http://192.168.0.143:2379,http://127.0.0.1:2379 " # o endereço da sua máquina


[cluster]


ETCD_INITIAL_ADVERTISE_PEER_URLS = " http://192.168.0.143:2380 " # endereço da sua máquina
ETCD_INITIAL_CLUSTER = "datanode1 = http://192.168.0.143:2380,datanode2=http://192.168.0.144:2380,datanode3=http://192.168.0.145:2380 " # endereços de todas as máquinas no cluster etcd
ETCD_INITIAL_CLUSTER_STATE = "novo"
ETCD_INITIAL_CLUSTER_TOKEN = "etcd-cluster-1"
ETCD_ADVERTISE_CLIENT_URLS = " http://192.168.0.143:2379 " # o endereço da sua máquina


Execute o comando


 systemctl restart etcd 

PostgreSQL 9.6 + patroni


A primeira coisa a fazer é instalar três máquinas virtuais para instalar o software necessário nelas. Depois de instalar as máquinas, se você seguir meu tutorial, poderá executar este script simples que (quase) faz tudo por você. Execute como root.


Observe que o script usa o PostgreSQL versão 9.6, devido aos requisitos internos de nossa empresa. A solução não foi testada em outras versões do PostgreSQL.


 #!/bin/bash apt-get install gnupg -y echo "deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main" >> /etc/apt/sources.list wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - apt-get update apt-get install postgresql-9.6 python3-pip python3-dev libpq-dev -y systemctl stop postgresql pip3 install --upgrade pip pip install psycopg2 pip install patroni[etcd] echo "\ [Unit] Description=Runners to orchestrate a high-availability PostgreSQL After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres ExecStart=/usr/local/bin/patroni /etc/patroni.yml KillMode=process TimeoutSec=30 Restart=no [Install] WantedBy=multi-user.targ\ " > /etc/systemd/system/patroni.service mkdir -p /data/patroni chown postgres:postgres /data/patroni chmod 700 /data/patroni touch /etc/patroni.yml 

Em seguida, no arquivo /etc/patroni.yml recém-criado, você precisa colocar o seguinte conteúdo, é claro, alterando os endereços IP em todos os lugares pelos endereços que você usa.
Preste atenção aos comentários neste yaml. Altere os endereços por conta própria em cada máquina no cluster.


/etc/patroni.yml
 scope: pgsql #       namespace: /cluster/ #       name: postgres1 #       restapi: listen: 192.168.0.143:8008 #   ,      connect_address: 192.168.0.143:8008 #   ,      etcd: hosts: 192.168.0.143:2379,192.168.0.144:2379,192.168.0.145:2379 #     ,      etcd    # this section (bootstrap) will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster # and all other cluster members will use it as a `global configuration` bootstrap: dcs: ttl: 100 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters: wal_level: replica hot_standby: "on" wal_keep_segments: 5120 max_wal_senders: 5 max_replication_slots: 5 checkpoint_timeout: 30 initdb: - encoding: UTF8 - data-checksums - locale: en_US.UTF8 # init pg_hba.conf     ,    pg_hba: - host replication postgres ::1/128 md5 - host replication postgres 127.0.0.1/8 md5 - host replication postgres 192.168.0.143/24 md5 - host replication postgres 192.168.0.144/24 md5 - host replication postgres 192.168.0.145/24 md5 - host all all 0.0.0.0/0 md5 users: admin: password: admin options: - createrole - createdb postgresql: listen: 192.168.0.143:5432 #   ,      connect_address: 192.168.0.143:5432 #   ,      data_dir: /data/patroni #    ,       bin_dir: /usr/lib/postgresql/9.6/bin #       postgresql pgpass: /tmp/pgpass authentication: replication: username: postgres password: postgres superuser: username: postgres password: postgres create_replica_methods: basebackup: checkpoint: 'fast' parameters: unix_socket_directories: '.' tags: nofailover: false noloadbalance: false clonefrom: false nosync: false 

O script deve ser executado nas três máquinas do cluster, assim como você precisa colocar a configuração no arquivo /etc/patroni.yml em todas as máquinas.


Ao executar essas operações em todas as máquinas no cluster, execute o seguinte comando em qualquer uma delas


 systemctl start patroni systemctl start postgresql 

Aguarde cerca de 30 segundos e execute este comando no restante das máquinas de cluster.


HAproxy


Usamos o maravilhoso HAproxy para fornecer um único ponto de entrada. O servidor mestre estará sempre disponível no endereço da máquina na qual o HAproxy está implantado.


Para não tornar a máquina HAproxy um único ponto de falha, execute-a no contêiner do Docker, depois será possível executá-la no cluster do K8 e tornar nosso cluster de failover ainda mais confiável.


Crie um diretório no qual você possa armazenar dois arquivos - Dockerfile e haproxy.cfg. Vá para lá.


Dockerfile
 FROM ubuntu:latest RUN apt-get update \ && apt-get install -y haproxy rsyslog \ && rm -rf /var/lib/apt/lists/* RUN mkdir /run/haproxy COPY haproxy.cfg /etc/haproxy/haproxy.cfg CMD haproxy -f /etc/haproxy/haproxy.cfg && tail -F /var/log/haproxy.log 

Cuidado, as últimas três linhas do arquivo haproxy.cfg devem listar os endereços de suas máquinas. O HAproxy entrará em contato com Patroni, nos cabeçalhos HTTP, o servidor mestre sempre retornará 200 e a réplica retornará 503.


haproxy.cfg
 global maxconn 100 defaults log global mode tcp retries 2 timeout client 30m timeout connect 4s timeout server 30m timeout check 5s listen stats mode http bind *:7000 stats enable stats uri / listen postgres bind *:5000 option httpchk http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions server postgresql1 192.168.0.143:5432 maxconn 100 check port 8008 server postgresql2 192.168.0.144:5432 maxconn 100 check port 8008 server postgresql3 192.168.0.145:5432 maxconn 100 check port 8008 

Estando no diretório em que nossos arquivos "se encontram", executaremos sequencialmente os comandos de empacotamento do contêiner, bem como seu lançamento com o encaminhamento das portas necessárias:


 docker build -t my-haproxy . docker run -d -p5000:5000 -p7000:7000 my-haproxy 

Agora, abrindo o endereço da sua máquina com o HAproxy no navegador e especificando a porta 7000, você verá estatísticas no seu cluster.


No estado UP, o servidor que é o mestre será localizado e as réplicas no estado DOWN. Isso é normal, na verdade eles funcionam, mas são exibidos neste formulário devido ao fato de que eles retornam 503 para solicitações do HAproxy. Isso nos permite saber sempre exatamente qual dos três servidores é o mestre no momento.


Conclusão


Você é incrível! Em apenas 30 minutos, você implantou um excelente cluster de banco de dados produtivo e seguro contra falhas, com replicação de fluxo contínuo e provisionamento automático. Se você planeja usar esta solução, consulte a documentação oficial da Patroni e, principalmente, sua parte referente ao utilitário patronictl, que fornece acesso conveniente para gerenciar seu cluster.


Parabéns!

Source: https://habr.com/ru/post/pt482314/


All Articles