Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Neste artigo, você executa várias etapas de teste e validação em um banco de dados PostgreSQL implantado no AKS. Isso inclui verificar a implantação, conectar-se ao banco de dados e testar cenários de failover.
- Se você ainda não implantou o PostgreSQL, siga as etapas em Implantar um banco de dados PostgreSQL altamente disponível no AKS com a CLI do Azure para obter a configuração e, em seguida, você pode retornar a este artigo.
Importante
O software de código aberto é mencionado em toda a documentação e amostras do AKS. O software que você implanta é excluído dos contratos de nível de serviço do AKS, da garantia limitada e do suporte do Azure. Ao usar a tecnologia de código aberto ao lado do AKS, consulte as opções de suporte disponíveis nas respetivas comunidades e mantenedores do projeto para desenvolver um plano.
A Microsoft assume a responsabilidade pela criação dos pacotes de código aberto que implantamos no AKS. Essa responsabilidade inclui ter a propriedade completa do processo de compilação, digitalização, assinatura, validação e hotfix, juntamente com o controle sobre os binários em imagens de contêiner. Para mais informações, consulte Gestão de vulnerabilidades para AKS e cobertura de suporte AKS.
Inspecione o cluster PostgreSQL implantado
Valide se o PostgreSQL está distribuído por várias zonas de disponibilidade recuperando os detalhes do nó AKS usando o comando kubectl get.
kubectl get nodes \
--context $AKS_PRIMARY_CLUSTER_NAME \
--namespace $PG_NAMESPACE \
--output json | jq '.items[] | {node: .metadata.name, zone: .metadata.labels."failure-domain.beta.kubernetes.io/zone"}'
A sua saída deve ser semelhante ao exemplo de saída a seguir com a zona de disponibilidade mostrada para cada nó.
{
"node": "aks-postgres-15810965-vmss000000",
"zone": "westus3-1"
}
{
"node": "aks-postgres-15810965-vmss000001",
"zone": "westus3-2"
}
{
"node": "aks-postgres-15810965-vmss000002",
"zone": "westus3-3"
}
{
"node": "aks-systempool-26112968-vmss000000",
"zone": "westus3-1"
}
{
"node": "aks-systempool-26112968-vmss000001",
"zone": "westus3-2"
}
Conecte-se ao PostgreSQL e crie um conjunto de dados de exemplo
Nesta seção, você cria uma tabela e insere alguns dados no banco de dados do aplicativo que foi criado no CRD do Cluster CNPG implantado anteriormente. Use esses dados para validar as operações de backup e restauração para o cluster PostgreSQL.
Crie uma tabela e insira dados no banco de dados do aplicativo usando os seguintes comandos:
kubectl cnpg psql $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE-- Create a small dataset CREATE TABLE datasample (id INTEGER, name VARCHAR(255)); INSERT INTO datasample (id, name) VALUES (1, 'John'); INSERT INTO datasample (id, name) VALUES (2, 'Jane'); INSERT INTO datasample (id, name) VALUES (3, 'Alice'); SELECT COUNT(*) FROM datasample;Digite
\qpara sair do psql quando terminar.Sua saída deve ser semelhante à saída de exemplo a seguir:
CREATE TABLE INSERT 0 1 INSERT 0 1 INSERT 0 1 count ------- 3 (1 row)
Ligar-se a réplicas apenas de leitura do PostgreSQL
Conecte-se às réplicas de leitura do PostgreSQL e valide os dados de amostra usando os seguintes comandos:
kubectl cnpg psql --replica $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACESELECT pg_is_in_recovery();Exemplo de saída
pg_is_in_recovery ------------------- t (1 row)SELECT COUNT(*) FROM datasample;Exemplo de saída
count ------- 3 (1 row)
Configurar backups PostgreSQL sob demanda e agendados usando o Barman
Observação
Espera-se que o CloudNativePG subverta o suporte nativo do Barman Cloud em favor do plug-in Barman Cloud em uma próxima versão 1.29. As etapas neste guia continuam a funcionar atualmente, mas planeia migrar para o plugin assim que este estiver estabilizado.
Valide se o cluster PostgreSQL pode aceder à conta de armazenamento do Azure especificada no CRD do Cluster CNPG e que
Working WAL archivingseja relatado comoOKusando o seguinte comando:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEExemplo de saída
Continuous Backup status First Point of Recoverability: Not Available Working WAL archiving: OK WALs waiting to be archived: 0 Last Archived WAL: 00000001000000000000000A @ 2024-07-09T17:18:13.982859Z Last Failed WAL: -Implante um backup sob demanda no Armazenamento do Azure, que usa a integração de identidade de carga de trabalho AKS, usando o arquivo YAML com o
kubectl applycomando.export BACKUP_ONDEMAND_NAME="on-demand-backup-1" cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -v 9 -f - apiVersion: postgresql.cnpg.io/v1 kind: Backup metadata: name: $BACKUP_ONDEMAND_NAME spec: method: barmanObjectStore cluster: name: $PG_PRIMARY_CLUSTER_NAME EOFValide o status do backup sob demanda usando o
kubectl describecomando.kubectl describe backup $BACKUP_ONDEMAND_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEExemplo de saída
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Starting 6s cloudnative-pg-backup Starting backup for cluster pg-primary-cnpg-r8c7unrw Normal Starting 5s instance-manager Backup started Normal Completed 1s instance-manager Backup completedValide se o cluster tem um primeiro ponto de capacidade de recuperação usando o seguinte comando:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEExemplo de saída
Continuous Backup status First Point of Recoverability: 2024-06-05T13:47:18Z Working WAL archiving: OKConfigure um backup agendado para cada hora em 15 minutos após a hora usando o arquivo YAML com o
kubectl applycomando.export BACKUP_SCHEDULED_NAME="scheduled-backup-1" cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -v 9 -f - apiVersion: postgresql.cnpg.io/v1 kind: ScheduledBackup metadata: name: $BACKUP_SCHEDULED_NAME spec: # Backup once per hour schedule: "0 15 * ? * *" backupOwnerReference: self cluster: name: $PG_PRIMARY_CLUSTER_NAME EOFValide o status do backup agendado usando o
kubectl describecomando.kubectl describe scheduledbackup $BACKUP_SCHEDULED_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEExiba os arquivos de backup armazenados no armazenamento de blob do Azure para o cluster primário usando o
az storage blob listcomando.az storage blob list \ --account-name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \ --container-name backups \ --query "[*].name" \ --only-show-errorsSua saída deve ser semelhante à saída de exemplo a seguir, validando que o backup foi bem-sucedido:
[ "pg-primary-cnpg-r8c7unrw/base/20240605T134715/backup.info", "pg-primary-cnpg-r8c7unrw/base/20240605T134715/data.tar", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000001", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000002", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000003", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000003.00000028.backup", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000004", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000005", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000005.00000028.backup", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000006", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000007", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000008", "pg-primary-cnpg-r8c7unrw/wals/0000000100000000/000000010000000000000009" ]
Restaurar o backup sob demanda para um novo cluster PostgreSQL
Nesta seção, você restaura o backup sob demanda criado anteriormente usando o operador CNPG em uma nova instância usando o CRD do cluster de inicialização. Um cluster de instância única é usado para simplificar. Lembre-se de que a identidade da carga de trabalho AKS (via CNPG inheritFromAzureAD) acessa os arquivos de backup e que o nome do cluster de recuperação é usado para gerar uma nova conta de serviço Kubernetes específica para o cluster de recuperação.
Você também cria uma segunda credencial federada para mapear a nova conta de serviço de cluster de recuperação para o UAMI existente que tem acesso "Storage Blob Data Contributor" aos arquivos de backup no armazenamento de blob.
Crie uma segunda credencial de identidade federada usando o
az identity federated-credential createcomando.export PG_PRIMARY_CLUSTER_NAME_RECOVERED="$PG_PRIMARY_CLUSTER_NAME-recovered-db" az identity federated-credential create \ --name $PG_PRIMARY_CLUSTER_NAME_RECOVERED \ --identity-name $AKS_UAMI_CLUSTER_IDENTITY_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --issuer "${AKS_PRIMARY_CLUSTER_OIDC_ISSUER}" \ --subject system:serviceaccount:"${PG_NAMESPACE}":"${PG_PRIMARY_CLUSTER_NAME_RECOVERED}" \ --audience api://AzureADTokenExchangeRestaure o backup a pedido usando o CRD do cluster com o comando
kubectl apply.cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -v 9 -f - apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: $PG_PRIMARY_CLUSTER_NAME_RECOVERED spec: inheritedMetadata: annotations: service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX labels: azure.workload.identity/use: "true" instances: 1 affinity: nodeSelector: workload: postgres # Point to cluster backup created earlier and stored on Azure Blob Storage bootstrap: recovery: source: clusterBackup storage: size: 2Gi pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi storageClassName: managed-csi-premium volumeMode: Filesystem walStorage: size: 2Gi pvcTemplate: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi storageClassName: managed-csi-premium volumeMode: Filesystem serviceAccountTemplate: metadata: annotations: azure.workload.identity/client-id: "$AKS_UAMI_WORKLOAD_CLIENTID" labels: azure.workload.identity/use: "true" externalClusters: - name: clusterBackup barmanObjectStore: destinationPath: https://${PG_PRIMARY_STORAGE_ACCOUNT_NAME}.blob.core.windows.net/backups serverName: $PG_PRIMARY_CLUSTER_NAME azureCredentials: inheritFromAzureAD: true wal: maxParallel: 8 EOFConecte-se à instância recuperada e valide se o conjunto de dados criado no cluster original onde o backup completo foi feito está presente usando o seguinte comando:
kubectl cnpg psql $PG_PRIMARY_CLUSTER_NAME_RECOVERED --namespace $PG_NAMESPACESELECT COUNT(*) FROM datasample;Exemplo de saída
count ------- 3 (1 row) Type \q to exit psqlExclua o cluster recuperado usando o seguinte comando:
kubectl cnpg destroy $PG_PRIMARY_CLUSTER_NAME_RECOVERED 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEExclua a credencial de identidade federada usando o
az identity federated-credential deletecomando.az identity federated-credential delete \ --name $PG_PRIMARY_CLUSTER_NAME_RECOVERED \ --identity-name $AKS_UAMI_CLUSTER_IDENTITY_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --yes
Expor o cluster PostgreSQL usando um balanceador de carga público
Nesta secção, configura a infraestrutura necessária para expor publicamente os pontos de extremidade de leitura-escrita e de leitura única do PostgreSQL com restrições de fonte de IP para o endereço IP público da estação de trabalho do cliente.
Você também recupera os seguintes pontos de extremidade do serviço Cluster IP:
-
Uma extremidade primária de leitura-escrita que termina com
*-rw. -
De zero a N pontos finais de leitura apenas (dependendo do número de réplicas) que terminam com
*-ro. -
Um ponto de extremidade de replicação que termina com
*-r.
Obtenha os detalhes do serviço IP do cluster usando o
kubectl getcomando.kubectl get services \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE \ -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAMEExemplo de saída
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pg-primary-cnpg-sryti1qf-r ClusterIP 10.0.193.27 <none> 5432/TCP 3h57m pg-primary-cnpg-sryti1qf-ro ClusterIP 10.0.237.19 <none> 5432/TCP 3h57m pg-primary-cnpg-sryti1qf-rw ClusterIP 10.0.244.125 <none> 5432/TCP 3h57mObservação
Existem três serviços:
namespace/cluster-name-ro, mapeado para a porta 5433,namespace/cluster-name-rw, enamespace/cluster-name-r, mapeado para a porta 5433. É importante evitar usar a mesma porta que é utilizada pelo nó de leitura e gravação do cluster de bases de dados PostgreSQL. Se tu quiseres que as aplicações acedam apenas à réplica de leitura apenas do cluster de bases de dados PostgreSQL, direciona-as para a porta 5433. O serviço final é normalmente usado para backups de dados, mas também pode funcionar como um nó de leitura apenas.Obtenha os detalhes do serviço usando o
kubectl getcomando.export PG_PRIMARY_CLUSTER_RW_SERVICE=$(kubectl get services \ --namespace $PG_NAMESPACE \ --context $AKS_PRIMARY_CLUSTER_NAME \ -l "cnpg.io/cluster" \ --output json | jq -r '.items[] | select(.metadata.name | endswith("-rw")) | .metadata.name') echo $PG_PRIMARY_CLUSTER_RW_SERVICE export PG_PRIMARY_CLUSTER_RO_SERVICE=$(kubectl get services \ --namespace $PG_NAMESPACE \ --context $AKS_PRIMARY_CLUSTER_NAME \ -l "cnpg.io/cluster" \ --output json | jq -r '.items[] | select(.metadata.name | endswith("-ro")) | .metadata.name') echo $PG_PRIMARY_CLUSTER_RO_SERVICEConfigure o serviço de balanceador de carga com os seguintes arquivos YAML usando o
kubectl applycomando.cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -f - apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/azure-load-balancer-resource-group: $AKS_PRIMARY_CLUSTER_NODERG_NAME service.beta.kubernetes.io/azure-pip-name: $AKS_PRIMARY_CLUSTER_PUBLICIP_NAME service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX name: cnpg-cluster-load-balancer-rw namespace: "${PG_NAMESPACE}" spec: type: LoadBalancer ports: - protocol: TCP port: 5432 targetPort: 5432 selector: cnpg.io/instanceRole: primary cnpg.io/podRole: instance loadBalancerSourceRanges: - "$MY_PUBLIC_CLIENT_IP/32" EOF cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -f - apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/azure-load-balancer-resource-group: $AKS_PRIMARY_CLUSTER_NODERG_NAME service.beta.kubernetes.io/azure-pip-name: $AKS_PRIMARY_CLUSTER_PUBLICIP_NAME service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX name: cnpg-cluster-load-balancer-ro namespace: "${PG_NAMESPACE}" spec: type: LoadBalancer ports: - protocol: TCP port: 5433 targetPort: 5432 selector: cnpg.io/instanceRole: replica cnpg.io/podRole: instance loadBalancerSourceRanges: - "$MY_PUBLIC_CLIENT_IP/32" EOFObtenha os detalhes do serviço usando o
kubectl describecomando.kubectl describe service cnpg-cluster-load-balancer-rw \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE kubectl describe service cnpg-cluster-load-balancer-ro \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE export AKS_PRIMARY_CLUSTER_ALB_DNSNAME="$(az network public-ip show \ --resource-group $AKS_PRIMARY_CLUSTER_NODERG_NAME \ --name $AKS_PRIMARY_CLUSTER_PUBLICIP_NAME \ --query "dnsSettings.fqdn" --output tsv)" echo $AKS_PRIMARY_CLUSTER_ALB_DNSNAME
Validar endpoints públicos do PostgreSQL
Nesta seção, você valida se o Balanceador de Carga do Azure está configurado corretamente usando o IP estático criado anteriormente e roteando conexões para as réplicas primárias de leitura-gravação e somente leitura e usa a CLI psql para se conectar a ambos.
Lembre-se de que o ponto de acesso principal de leitura e escrita está associado à porta TCP 5432 e os pontos de acesso de réplica de leitura estão associados à porta 5433 para permitir a utilização do mesmo nome DNS PostgreSQL para leitores e escritores.
Observação
Você precisa do valor da senha de usuário do aplicativo para a autenticação básica do PostgreSQL que foi gerada anteriormente e armazenada na $PG_DATABASE_APPUSER_SECRET variável de ambiente.
Valide os endpoints públicos do PostgreSQL usando os seguintes
psqlcomandos:echo "Public endpoint for PostgreSQL cluster: $AKS_PRIMARY_CLUSTER_ALB_DNSNAME" # Query the primary, pg_is_in_recovery = false psql -h $AKS_PRIMARY_CLUSTER_ALB_DNSNAME \ -p 5432 -U app -d appdb -W -c "SELECT pg_is_in_recovery();"Exemplo de saída
pg_is_in_recovery ------------------- f (1 row)echo "Query a replica, pg_is_in_recovery = true" psql -h $AKS_PRIMARY_CLUSTER_ALB_DNSNAME \ -p 5433 -U app -d appdb -W -c "SELECT pg_is_in_recovery();"Exemplo de saída
# Example output pg_is_in_recovery ------------------- t (1 row)Quando se conecta com sucesso ao ponto de extremidade principal de leitura-gravação, a função PostgreSQL retorna
fpara false, indicando que a conexão atual é gravável.Quando conectada a uma réplica, a função retorna
tpara true, indicando que o banco de dados está em recuperação e somente leitura.
Simular um failover não planejado
Nesta seção, você causa uma falha repentina ao excluir o pod que executa o primário do PostgreSQL, simulando assim uma falha súbita ou perda de conectividade de rede para o nó que hospeda o primário.
Verifique o status das instâncias de pod em execução usando o seguinte comando:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACEExemplo de saída
Name Current LSN Rep role Status Node --------------------------- ----------- -------- ------- ----------- pg-primary-cnpg-sryti1qf-1 0/9000060 Primary OK aks-postgres-32388626-vmss000000 pg-primary-cnpg-sryti1qf-2 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000001 pg-primary-cnpg-sryti1qf-3 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000002Exclua o pod primário usando o
kubectl deletecomando.PRIMARY_POD=$(kubectl get pod \ --namespace $PG_NAMESPACE \ --no-headers \ -o custom-columns=":metadata.name" \ -l role=primary) kubectl delete pod $PRIMARY_POD --grace-period=1 --namespace $PG_NAMESPACEValide se a instância do
pg-primary-cnpg-sryti1qf-2pod agora é a principal usando o seguinte comando:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACEExemplo de saída
pg-primary-cnpg-sryti1qf-2 0/9000060 Primary OK aks-postgres-32388626-vmss000001 pg-primary-cnpg-sryti1qf-1 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000000 pg-primary-cnpg-sryti1qf-3 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000002Redefina a instância do
pg-primary-cnpg-sryti1qf-1pod como principal usando o seguinte comando:kubectl cnpg promote $PG_PRIMARY_CLUSTER_NAME 1 --namespace $PG_NAMESPACEConfirme que as instâncias de pod retornaram ao seu estado original antes do teste de failover não planejado usando o seguinte comando:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACEExemplo de saída
Name Current LSN Rep role Status Node --------------------------- ----------- -------- ------- ----------- pg-primary-cnpg-sryti1qf-1 0/9000060 Primary OK aks-postgres-32388626-vmss000000 pg-primary-cnpg-sryti1qf-2 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000001 pg-primary-cnpg-sryti1qf-3 0/9000060 Standby (sync) OK aks-postgres-32388626-vmss000002
Limpar recursos
Quando terminar de revisar sua implantação, exclua todos os recursos criados neste guia usando o
az group deletecomando.az group delete --resource-group $RESOURCE_GROUP_NAME --no-wait --yes
Próximos passos
Neste guia de instruções, você aprendeu como:
- Use a CLI do Azure para criar um cluster AKS de várias zonas.
- Implante um cluster e banco de dados PostgreSQL altamente disponíveis usando o operador CNPG.
- Configure o monitoramento para PostgreSQL usando Prometheus e Grafana.
- Implante um conjunto de dados de exemplo no banco de dados PostgreSQL.
- Simule uma interrupção de cluster e falha de replicação do PostgreSQL.
- Execute um backup e restauração do banco de dados PostgreSQL.
Para saber mais sobre como você pode usar o AKS para suas cargas de trabalho, consulte O que é o Serviço Kubernetes do Azure (AKS)? Para saber mais sobre o Banco de Dados do Azure para PostgreSQL, consulte O que é o Banco de Dados do Azure para PostgreSQL?
Contribuidores
A Microsoft mantém este artigo. Os seguintes colaboradores escreveram-no originalmente:
- Ken Kilty - Brasil | Principal TPM
- Russell de Pina - Brasil | Principal TPM
- Adrian Joian | Engenheiro de Clientes Senior
- Jenny Hayes | Senior Desenvolvedora de Conteúdos
- Carol Smith | Senior Desenvolvedor de Conteúdos
- Erin Schaffer | Desenvolvedora de Conteúdo 2
- Adam Sharif | Engenheiro de Clientes 2
Agradecimento
Esta documentação foi desenvolvida em conjunto com o EnterpriseDB, os mantenedores do operador CloudNativePG. Agradecemos a Gabriele Bartolini por ter revisado rascunhos anteriores deste documento e oferecido melhorias técnicas.