O guia mostra como implantar clusters do PostgreSQL no Google Kubernetes Engine (GKE) usando o operador CloudNativePG.
O PostgreSQL é um banco de dados relacional de objeto de código aberto com várias décadas de desenvolvimento ativo, garantindo um desempenho estável do cliente. Ele oferece uma variedade de recursos, incluindo replicação, recuperação pontual, recursos de segurança e extensibilidade. O PostgreSQL é compatível com os principais sistemas operacionais e está em total conformidade com os padrões ACID (atomicidade, consistência, isolamento e durabilidade).
Este guia é destinado a administradores de plataformas, arquitetos de nuvem e profissionais de operações interessados em implantar clusters do Postgres no GKE. A execução do Postgres no GKE em vez de usar o Cloud SQL pode oferecer mais flexibilidade e controle de configuração para administradores de bancos de dados experientes.
Benefícios
O CloudNativePG é um operador de código aberto desenvolvido pelo EDB sob uma licença Apache 2. Ele traz os seguintes recursos para a implantação do PostgreSQL:
- Uma maneira declarativa e nativa do Kubernetes de gerenciar e configurar os clusters do PostgreSQL
- Gerenciamento de backup usando snapshots de volume ou o Cloud Storage
- Conexão TLS criptografada em trânsito, a capacidade de usar sua própria autoridade de certificação e a integração com o Gerenciador de certificados para a emissão e a rotação automatizadas de certificados TLS.
- Atualizações graduais para versões secundárias do PostgreSQL
- Uso do servidor da API Kubernetes para manter um status do cluster do PostgreSQL e failovers para alta disponibilidade sem a necessidade de outras ferramentas
- Configuração de exportador integrada do Prometheus por meio de métricas definidas pelo usuário e escritas em SQL
Objetivos
- Planejar e implantar a infraestrutura do GKE para Postgres
- Implante e configure o operador CloudNativePG Postgres com o Helm
- Implantar um cluster do PostgreSQL
- Configurar a autenticação e a observabilidade do PostgreSQL
Arquitetura de implantação
O PostgreSQL tem várias opções de implantação, de um servidor de banco de dados independente para um cluster de alta disponibilidade replicado. Este tutorial se concentra na implantação de clusters altamente disponível no GKE.
Nesta implantação, as cargas de trabalho do cluster do PostgreSQL são distribuídas por várias zonas de disponibilidade no cluster regional do GKE, garantindo alta disponibilidade e redundância. Para mais informações, consulte Clusters regionais.
O diagrama a seguir mostra um cluster do Postgres em execução em vários nós e zonas em um cluster do GKE:
A configuração padrão inclui um servidor PostgreSQL principal e dois servidores de backup prontos para serem usados caso o servidor principal falhe, garantindo a disponibilidade contínua do banco de dados.
Os recursos do operador CloudNativePG usam um namespace separado do cluster do GKE para melhorar o isolamento de recursos e a abordagem recomendada de microsserviços de um banco de dados por cluster do PostgreSQL. O banco de dados e o usuário correspondente (usuário do app) são definidos no recurso personalizado do Kubernetes que representa o cluster.
O armazenamento é um componente crucial quando se trata de bancos de dados. O armazenamento precisa ter um desempenho eficiente, garantir a disponibilidade contínua e a consistência dos dados. Por esses motivos, recomendamos a classe de armazenamento
premium-rwo
, que é baseada em discos SSD. O operador CloudNativePG criaPersistentVolumeClaims
automaticamente conforme necessário ao configurar pods para o cluster do PostgreSQL.
Custos
Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.
Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.
Antes de começar
O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo o kubectl
, a gcloud CLI, o Helm e o Terraform. Se você não usa o Cloud Shell, é necessário instalar a gcloud CLI.
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com - Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/compute.securityAdmin, roles/compute.viewer, roles/container.clusterAdmin, roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
configurar o ambiente
Para configurar o ambiente, siga estas etapas:
Defina as variáveis de ambiente:
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1
Substitua o
PROJECT_ID
pelo ID do projeto do Google Cloud.Clone o repositório do GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Mude para o diretório de trabalho:
cd kubernetes-engine-samples/databases/postgresql-cloudnativepg
Criar a infraestrutura do cluster
Nesta seção, você executa um script do Terraform para criar um cluster regional do GKE privado e altamente disponível.
É possível instalar o operador usando um cluster padrão ou Autopilot.
Padrão
O diagrama a seguir mostra um cluster regional padrão particular do GKE implantado em três zonas diferentes:
Para implantar essa infraestrutura, execute os seguintes comandos:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
Quando solicitado, digite yes
. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.
O Terraform cria os seguintes recursos:
- Uma rede VPC e uma sub-rede particular para os nós do Kubernetes.
- Um roteador para acessar a Internet usando NAT.
- Um cluster particular do GKE na região
us-central1
. - Um pool de nós com escalonamento automático ativado (de um a dois nós por zona, um nó por zona no mínimo);
O resultado será assim:
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...
Piloto automático
O diagrama a seguir mostra um cluster particular regional do Autopilot do GKE:
Para implantar a infraestrutura, execute os seguintes comandos:
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
Quando solicitado, digite yes
. Pode levar vários minutos para que esse comando seja concluído e o cluster mostre um status pronto.
O Terraform cria os seguintes recursos:
- Uma rede VPC e uma sub-rede particular para os nós do Kubernetes.
- Um roteador para acessar a Internet usando NAT.
- Um cluster particular do GKE na região
us-central1
. - Um
ServiceAccount
com permissão de geração de registros e monitoramento. - Google Cloud Managed Service para Prometheus para monitoramento de clusters.
O resultado será assim:
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
...
Conexão ao cluster
Configure kubectl
para se comunicar com o cluster:
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --region ${REGION}
Implantar o operador CloudNativePG
Implante o CloudNativePG no seu cluster do Kubernetes usando um gráfico do Helm:
Adicionar o repositório de gráficos Helm do operador CloudNativePG:
helm repo add cnpg https://cloudnative-pg.github.io/charts
Implantar o operador do CloudNativePG usando a ferramenta de linha de comando Helm:
helm upgrade --install cnpg \ --namespace cnpg-system \ --create-namespace \ cnpg/cloudnative-pg
O resultado será assim:
Release "cnpg" does not exist. Installing it now. NAME: cnpg LAST DEPLOYED: Fri Oct 13 13:52:36 2023 NAMESPACE: cnpg-system STATUS: deployed REVISION: 1 TEST SUITE: None ...
Implantar o Postgres
O manifesto a seguir descreve um cluster do PostgreSQL, conforme definido pelo recurso personalizado do operador CloudNativePG:
Esse manifesto tem os seguintes campos:
spec.instances
: o número de pods do clusterspec.primaryUpdateStrategy
: a estratégia de atualização gradual:Unsupervised
: atualiza de maneira autônoma o nó do cluster principal após os nós de réplica.Supervised
: a alternância manual é necessária para o nó do cluster principal
spec.postgresql
: substituições de parâmetros de arquivopostgres.conf
, como regras pg-hba, LDAP e requisitos para que as réplicas de sincronização sejam atendidas.spec.storage
: configurações relacionadas ao armazenamento, como classe de armazenamento, tamanho do volume e configurações de registro prévio de escrita.spec.bootstrap
: parâmetros do banco de dados inicial criado no cluster, credenciais do usuário e opções de restauração do banco de dadosspec.resources
: solicitações e limites para pods de clusterspec.affinity
: regras de afinidade e antiafinidade das cargas de trabalho do cluster
Criar um cluster básico do Postgres
Para criar um namespace:
kubectl create ns pg-ns
Crie o cluster do PostgreSQL usando o recurso personalizado:
kubectl apply -n pg-ns -f manifests/01-basic-cluster/postgreSQL_cluster.yaml
Esse comando pode levar alguns minutos para ser concluído.
Verifique o status do cluster:
kubectl get cluster -n pg-ns --watch
Antes de prosseguir, aguarde até que o status
Cluster in healthy state
seja exibido na saída.NAME AGE INSTANCES READY STATUS PRIMARY gke-pg-cluster 2m53s 3 3 Cluster in healthy state gke-pg-cluster-1
Inspecionar os recursos
Confirme se o GKE criou os recursos para o cluster:
kubectl get cluster,pod,svc,pvc,pdb,secret,cm -n pg-ns
O resultado será assim:
NAME AGE INSTANCES READY STATUS PRIMARY
cluster.postgresql.cnpg.io/gke-pg-cluster 32m 3 3 Cluster in healthy state gke-pg-cluster-1
NAME READY STATUS RESTARTS AGE
pod/gke-pg-cluster-1 1/1 Running 0 31m
pod/gke-pg-cluster-2 1/1 Running 0 30m
pod/gke-pg-cluster-3 1/1 Running 0 29m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gke-pg-cluster-r ClusterIP 10.52.11.24 <none> 5432/TCP 32m
service/gke-pg-cluster-ro ClusterIP 10.52.9.233 <none> 5432/TCP 32m
service/gke-pg-cluster-rw ClusterIP 10.52.1.135 <none> 5432/TCP 32m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/gke-pg-cluster-1 Bound pvc-bbdd1cdd-bdd9-4e7c-8f8c-1a14a87e5329 2Gi RWO standard 32m
persistentvolumeclaim/gke-pg-cluster-2 Bound pvc-e7a8b4df-6a3e-43ce-beb0-b54ec1d24011 2Gi RWO standard 31m
persistentvolumeclaim/gke-pg-cluster-3 Bound pvc-dac7f931-6ac5-425f-ac61-0cfc55aae72f 2Gi RWO standard 30m
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
poddisruptionbudget.policy/gke-pg-cluster 1 N/A 1 32m
poddisruptionbudget.policy/gke-pg-cluster-primary 1 N/A 0 32m
NAME TYPE DATA AGE
secret/gke-pg-cluster-app kubernetes.io/basic-auth 3 32m
secret/gke-pg-cluster-ca Opaque 2 32m
secret/gke-pg-cluster-replication kubernetes.io/tls 2 32m
secret/gke-pg-cluster-server kubernetes.io/tls 2 32m
secret/gke-pg-cluster-superuser kubernetes.io/basic-auth 3 32m
NAME DATA AGE
configmap/cnpg-default-monitoring 1 32m
configmap/kube-root-ca.crt 1 135m
O operador cria os seguintes recursos:
- Um recurso personalizado de cluster que representa o cluster do PostgreSQL controlado pelo operador
- Recursos PersistentVolumeClaim com os volumes permanentes correspondentes
- Secrets com credenciais de usuário para acessar o banco de dados e a replicação entre os nós do Postgres
- Três serviços de endpoint de banco de dados:
<name>-rw
,<name>-ro
e<name>-r
para conectar-se ao cluster. Para mais informações, consulte Arquitetura do PostgreSQL.
Autenticar no Postgres
É possível se conectar ao banco de dados PostgreSQL e verificar o acesso por meio de diferentes endpoints de serviço criados pelo operador. Para fazer isso, use um pod extra com um cliente PostgreSQL e credenciais de usuário de aplicativo sincronizadas ativadas como variáveis de ambiente.
Execute o pod cliente para interagir com o cluster do Postgres:
kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yaml
Execute um comando
exec
no podpg-client
e faça login no serviçogke-pg-cluster-rw
:kubectl wait --for=condition=Ready -n pg-ns pod/pg-client --timeout=300s kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
Faça login no banco de dados usando o serviço
gke-pg-cluster-rw
para estabelecer uma conexão com privilégios de leitura e gravação:psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app
O terminal começa com o nome do banco de dados:
app=>
Crie uma tabela:
CREATE TABLE travel_agency_clients ( client VARCHAR ( 50 ) UNIQUE NOT NULL, address VARCHAR ( 50 ) UNIQUE NOT NULL, phone VARCHAR ( 50 ) UNIQUE NOT NULL);
Insira dados na tabela:
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('Tom', 'Warsaw', '+55555') RETURNING *;
Confira os dados que você criou:
SELECT * FROM travel_agency_clients ;
O resultado será assim:
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Saia da sessão do banco de dados atual:
exit
Faça login no banco de dados usando o serviço
gke-pg-cluster-ro
para verificar o acesso somente leitura. Esse serviço permite a consulta de dados, mas restringe qualquer operação de gravação:psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app
Tente inserir novos dados:
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('John', 'Paris', '+55555') RETURNING *;
O resultado será assim:
ERROR: cannot execute INSERT in a read-only transaction
Tentativa de ler os dados:
SELECT * FROM travel_agency_clients ;
O resultado será assim:
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)
Saia da sessão do banco de dados atual:
exit
Saia do shell do pod:
exit
Entender como o Prometheus coleta métricas para seu cluster do Redis
No diagrama a seguir, mostramos como funciona a coleta de métricas do Prometheus:
No diagrama, um cluster particular do GKE contém os seguintes componentes:
- Um pod Postgres que coleta métricas no caminho
/
e na porta9187
. - Coletores baseados em Prometheus que processam as métricas do pod do Postgres.
- Um recurso
PodMonitoring
que envia métricas ao Cloud Monitoring.
Para permitir a coleta de métricas dos pods, siga estas etapas:
Crie o recurso
PodMonitoring
:kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-ns
No Console do Google Cloud, acesse a página do Metrics Explorer:
O painel mostra uma taxa de ingestão de métricas diferente de zero.
Em Selecionar uma métrica, insira Destino do Prometheus.
Na seção Categorias de métricas ativas, selecione Cnpg.
Criar um painel de métricas
Para conferir as métricas exportadas, crie um painel de métricas.
Implante um painel:
gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.json
No console do Google Cloud, acesse a página Painéis.
Selecione o painel Visão geral do Prometheus do PostgresQL.
Para analisar como os painéis monitoram as funções, reutilize ações da seção Autenticação do banco de dados, aplique solicitações de leitura e gravação no banco de dados e analise a visualização das métricas coletadas em um painel.
Conecte-se ao pod cliente:
kubectl exec -n pg-ns -i -t pg-client -- /bin/sh
Inserir dados aleatórios:
psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);INSERT INTO test (randomdata) VALUES (generate_series(1, 1000));"
Atualize o painel. Os gráficos são atualizados com as métricas atualizadas.
Saia do shell do pod:
exit
Limpar
Excluir o projeto
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Excluir recursos individuais
Defina variáveis de ambiente.
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1
Execute o comando
terraform destroy
:export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=terraform/FOLDER destroy \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
Substitua
FOLDER
porgke-autopilot
ougke-standard
.Quando solicitado, digite
yes
.Encontre todos os discos desanexados:
export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")
Exclua os discos:
for i in $disk_list; do disk_name=$(echo $i| cut -d'|' -f1) disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||') echo "Deleting $disk_name" gcloud compute disks delete $disk_name --zone $disk_zone --quiet done
A seguir
- Confira arquiteturas de referência, diagramas, tutoriais e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.