Partilhar via


Criar infraestrutura para implantar um banco de dados PostgreSQL altamente disponível no Serviço Kubernetes do Azure (AKS)

Neste artigo, você cria os recursos de infraestrutura necessários para implantar um banco de dados PostgreSQL altamente disponível no AKS usando o operador CloudNativePG (CNPG).

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 correção rápida, juntamente com o controlo dos binários nas imagens de contentor. Para mais informações, consulte Gestão de vulnerabilidades para AKS e cobertura de suporte AKS.

Antes de começar

Definir variáveis de ambiente

Defina as seguintes variáveis de ambiente para uso ao longo deste guia:

export SUFFIX=$(cat /dev/urandom | LC_ALL=C tr -dc 'a-z0-9' | fold -w 8 | head -n 1)
export LOCAL_NAME="cnpg"
export TAGS="owner=user"
export RESOURCE_GROUP_NAME="rg-${LOCAL_NAME}-${SUFFIX}"
export PRIMARY_CLUSTER_REGION="canadacentral"
export AKS_PRIMARY_CLUSTER_NAME="aks-primary-${LOCAL_NAME}-${SUFFIX}"
export AKS_PRIMARY_MANAGED_RG_NAME="rg-${LOCAL_NAME}-primary-aksmanaged-${SUFFIX}"
export AKS_PRIMARY_CLUSTER_FED_CREDENTIAL_NAME="pg-primary-fedcred1-${LOCAL_NAME}-${SUFFIX}"
export AKS_PRIMARY_CLUSTER_PG_DNSPREFIX=$(echo $(echo "a$(openssl rand -hex 5 | cut -c1-11)"))
export AKS_UAMI_CLUSTER_IDENTITY_NAME="mi-aks-${LOCAL_NAME}-${SUFFIX}"
export AKS_CLUSTER_VERSION="1.32"
export PG_NAMESPACE="cnpg-database"
export PG_SYSTEM_NAMESPACE="cnpg-system"
export PG_PRIMARY_CLUSTER_NAME="pg-primary-${LOCAL_NAME}-${SUFFIX}"
export PG_PRIMARY_STORAGE_ACCOUNT_NAME="hacnpgpsa${SUFFIX}"
export PG_STORAGE_BACKUP_CONTAINER_NAME="backups"
export MY_PUBLIC_CLIENT_IP=$(dig +short myip.opendns.com @resolver3.opendns.com)

Instalar as extensões necessárias

Instale as extensões necessárias para integração e monitoramento do Kubernetes:

az extension add --upgrade --name k8s-extension --yes
az extension add --upgrade --name amg --yes

Como pré-requisito para usar o kubectl, precisas primeiro instalar o Krew, seguido pela instalação do plugin CNPG. Essas instalações permitem o gerenciamento do operador PostgreSQL usando os comandos subsequentes.

(
    set -x; cd "$(mktemp -d)" &&
    OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
    ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
    KREW="krew-${OS}_${ARCH}" &&
    curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
    tar zxvf "${KREW}.tar.gz" &&
    ./"${KREW}" install krew
)

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

kubectl krew install cnpg

Criar um grupo de recursos

Crie um grupo de recursos para armazenar os recursos criados neste guia usando o az group create comando.

az group create \
    --name $RESOURCE_GROUP_NAME \
    --location $PRIMARY_CLUSTER_REGION \
    --tags $TAGS \
    --query 'properties.provisioningState' \
    --output tsv

Criar uma identidade gerida atribuída pelo utilizador

Nesta seção, você cria uma identidade gerenciada atribuída pelo usuário (UAMI) para permitir que o PostgreSQL do CNPG use uma identidade de carga de trabalho AKS para acessar o Armazenamento de Blobs do Azure. Essa configuração permite que o cluster PostgreSQL no AKS se conecte ao Armazenamento de Blobs do Azure sem um segredo.

  1. Crie uma identidade gerenciada atribuída pelo usuário usando o az identity create comando.

    AKS_UAMI_WI_IDENTITY=$(az identity create \
        --name $AKS_UAMI_CLUSTER_IDENTITY_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --location $PRIMARY_CLUSTER_REGION \
        --output json)
    
  2. Habilite a identidade da carga de trabalho do AKS e gere uma conta de serviço para usar posteriormente neste guia usando os seguintes comandos:

    export AKS_UAMI_WORKLOAD_OBJECTID=$( \
        echo "${AKS_UAMI_WI_IDENTITY}" | jq -r '.principalId')
    export AKS_UAMI_WORKLOAD_RESOURCEID=$( \
        echo "${AKS_UAMI_WI_IDENTITY}" | jq -r '.id')
    export AKS_UAMI_WORKLOAD_CLIENTID=$( \
        echo "${AKS_UAMI_WI_IDENTITY}" | jq -r '.clientId')
    
    echo "ObjectId: $AKS_UAMI_WORKLOAD_OBJECTID"
    echo "ResourceId: $AKS_UAMI_WORKLOAD_RESOURCEID"
    echo "ClientId: $AKS_UAMI_WORKLOAD_CLIENTID"
    

A ID do objeto é um identificador exclusivo para a ID do cliente (também conhecida como ID do aplicativo) que identifica exclusivamente uma entidade de segurança do tipo Aplicativo dentro do locatário do Microsoft Entra ID. A ID do recurso é um identificador exclusivo para gerenciar e localizar um recurso no Azure. Esses valores são necessários para habilitar a identidade da carga de trabalho do AKS.

O operador CNPG gera automaticamente uma conta de serviço chamada postgres que você usa posteriormente no guia para criar uma credencial federada que permite o acesso OAuth do PostgreSQL para o Armazenamento do Azure.

Criar uma conta de armazenamento na região principal

  1. Crie uma conta de armazenamento de objetos para armazenar backups PostgreSQL na região primária usando o az storage account create comando.

    az storage account create \
        --name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --location $PRIMARY_CLUSTER_REGION \
        --sku Standard_ZRS \
        --kind StorageV2 \
        --query 'provisioningState' \
        --output tsv
    
  2. Crie o contêiner de armazenamento para armazenar os Write Ahead Logs (WAL) e backups regulares do PostgreSQL sob demanda e agendados usando o az storage container create comando.

    az storage container create \
        --name $PG_STORAGE_BACKUP_CONTAINER_NAME \
        --account-name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \
        --auth-mode login
    

    Saída de exemplo:

    {
        "created": true
    }
    

    Nota

    Se você encontrar a mensagem de erro: The request may be blocked by network rules of storage account. Please check network rule set using 'az storage account show -n accountname --query networkRuleSet'. If you want to change the default action to apply when no rule matches, please use 'az storage account update'. Certifique-se de verificar as permissões de usuário para o Armazenamento de Blobs do Azure e, se necessário, elevar sua função para Storage Blob Data Owner usar os comandos fornecidos e depois de tentar novamente o az storage container create comando.

    export USER_ID=$(az ad signed-in-user show --query id --output tsv)
    
    export STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID=$(az storage account show \
        --name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --query "id" \
        --output tsv)
    
    az role assignment list --scope $STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID --output table
    
    az role assignment create \
        --assignee-object-id $USER_ID \
        --assignee-principal-type User \
        --scope $STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID \
        --role "Storage Blob Data Owner" \
        --output tsv
    

Atribuir RBAC a contas de armazenamento

Para habilitar backups, o cluster PostgreSQL precisa ler e gravar em um repositório de objetos. O cluster PostgreSQL em execução no AKS usa uma identidade de carga de trabalho para acessar a conta de armazenamento por meio do parâmetro inheritFromAzureADde configuração do operador CNPG.

  1. Obtenha o ID do recurso primário para a conta de armazenamento usando o az storage account show comando.

    export STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID=$(az storage account show \
        --name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --query "id" \
        --output tsv)
    
    echo $STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID
    
  2. Usando o comando az role assignment create, atribua a função interna do Azure "Storage Blob Data Contributor" ao ID do objeto com o escopo da ID de recurso da conta de armazenamento para o UAMI associado à identidade gerida de cada cluster AKS.

    az role assignment create \
        --role "Storage Blob Data Contributor" \
        --assignee-object-id $AKS_UAMI_WORKLOAD_OBJECTID \
        --assignee-principal-type ServicePrincipal \
        --scope $STORAGE_ACCOUNT_PRIMARY_RESOURCE_ID \
        --query "id" \
        --output tsv
    

Configurar a infraestrutura de monitoramento

Nesta seção, você implanta uma instância do Azure Managed Grafana, um espaço de trabalho do Azure Monitor e um espaço de trabalho do Azure Monitor Log Analytics para habilitar o monitoramento do cluster PostgreSQL. Você também armazena referências à infraestrutura de monitoramento criada para usar como entrada durante o processo de criação do cluster AKS mais adiante no guia. Esta seção pode levar algum tempo para ser concluída.

Nota

As instâncias do Azure Managed Grafana e os clusters AKS são cobrados de forma independente. Para obter mais informações sobre preços, consulte Preços do Azure Managed Grafana.

  1. Crie uma instância do Azure Managed Grafana usando o az grafana create comando.

    export GRAFANA_PRIMARY="grafana-${LOCAL_NAME}-${SUFFIX}"
    
    export GRAFANA_RESOURCE_ID=$(az grafana create \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $GRAFANA_PRIMARY \
        --location $PRIMARY_CLUSTER_REGION \
        --zone-redundancy Enabled \
        --tags $TAGS \
        --query "id" \
        --output tsv)
    
    echo $GRAFANA_RESOURCE_ID
    
  2. Crie um espaço de trabalho do Azure Monitor usando o az monitor account create comando.

    export AMW_PRIMARY="amw-${LOCAL_NAME}-${SUFFIX}"
    
    export AMW_RESOURCE_ID=$(az monitor account create \
        --name $AMW_PRIMARY \
        --resource-group $RESOURCE_GROUP_NAME \
        --location $PRIMARY_CLUSTER_REGION \
        --tags $TAGS \
        --query "id" \
        --output tsv)
    
    echo $AMW_RESOURCE_ID
    
  3. Crie um espaço de trabalho do Azure Monitor Log Analytics usando o az monitor log-analytics workspace create comando.

    export ALA_PRIMARY="ala-${LOCAL_NAME}-${SUFFIX}"
    
    export ALA_RESOURCE_ID=$(az monitor log-analytics workspace create \
        --resource-group $RESOURCE_GROUP_NAME \
        --workspace-name $ALA_PRIMARY \
        --location $PRIMARY_CLUSTER_REGION \
        --query "id" \
        --output tsv)
    
    echo $ALA_RESOURCE_ID
    

Criar o cluster AKS para hospedar o cluster PostgreSQL

Nesta seção, você cria um cluster AKS multizona com um pool de nós do sistema. O cluster AKS hospeda a réplica primária do cluster PostgreSQL e duas réplicas em espera, cada uma alinhada a uma zona de disponibilidade diferente para permitir a redundância zonal.

Você também adiciona um pool de nós de usuário ao cluster AKS para hospedar o cluster PostgreSQL. O uso de um pool de nós separado permite o controle sobre as SKUs de VM do Azure usadas para PostgreSQL e permite que o pool de sistemas AKS otimize o desempenho e os custos. Você aplica um rótulo ao pool de nós do usuário que pode ser utilizado como referência para a seleção de nós quando se implanta o operador CNPG mais tarde neste guia. Esta seção pode levar algum tempo para ser concluída.

Importante

Se você optar por usar NVMe local como seu armazenamento PostgreSQL nas partes posteriores deste guia, precisará escolher uma SKU de VM que suporte unidades NVMe locais, por exemplo, SKUs de VM otimizadas para armazenamento ou SKUs de VM aceleradas por GPU. Atualize $USER_NODE_POOL_VMSKU em conformidade.

  1. Crie um cluster AKS usando o az aks create comando.

    export SYSTEM_NODE_POOL_VMSKU="standard_d2s_v3"
    export USER_NODE_POOL_NAME="postgres"
    export USER_NODE_POOL_VMSKU="standard_d4s_v3"
    
    az aks create \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --tags $TAGS \
        --resource-group $RESOURCE_GROUP_NAME \
        --location $PRIMARY_CLUSTER_REGION \
        --generate-ssh-keys \
        --node-resource-group $AKS_PRIMARY_MANAGED_RG_NAME \
        --enable-managed-identity \
        --assign-identity $AKS_UAMI_WORKLOAD_RESOURCEID \
        --network-plugin azure \
        --network-plugin-mode overlay \
        --network-dataplane cilium \
        --nodepool-name systempool \
        --enable-oidc-issuer \
        --enable-workload-identity \
        --enable-cluster-autoscaler \
        --min-count 2 \
        --max-count 3 \
        --node-vm-size $SYSTEM_NODE_POOL_VMSKU \
        --enable-azure-monitor-metrics \
        --azure-monitor-workspace-resource-id $AMW_RESOURCE_ID \
        --grafana-resource-id $GRAFANA_RESOURCE_ID \
        --api-server-authorized-ip-ranges $MY_PUBLIC_CLIENT_IP \
        --tier standard \
        --kubernetes-version $AKS_CLUSTER_VERSION \
        --zones 1 2 3 \
        --output table
    
  2. Aguarde a conclusão da operação inicial do cluster usando o az aks wait comando para que atualizações adicionais, como a adição do pool de nós do usuário, não colidam com uma atualização de cluster gerenciado em andamento:

    az aks wait \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --created
    
  3. Adicione um pool de nós de usuário ao cluster AKS usando o az aks nodepool add comando.

    az aks nodepool add \
        --resource-group $RESOURCE_GROUP_NAME \
        --cluster-name $AKS_PRIMARY_CLUSTER_NAME \
        --name $USER_NODE_POOL_NAME \
        --enable-cluster-autoscaler \
        --min-count 3 \
        --max-count 6 \
        --node-vm-size $USER_NODE_POOL_VMSKU \
        --zones 1 2 3 \
        --labels workload=postgres \
        --output table
    

Conecte-se ao cluster AKS e crie namespaces

Nesta seção, você obtém as credenciais do cluster AKS, que servem como as chaves que permitem autenticar e interagir com o cluster. Uma vez conectado, você cria dois namespaces: um para os serviços do gerenciador de controladores CNPG e outro para o cluster PostgreSQL e seus serviços relacionados.

  1. Obtenha as credenciais do cluster AKS usando o az aks get-credentials comando.

    az aks get-credentials \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --output none
    
  2. Crie o namespace para os serviços do gerenciador de controladores CNPG, o cluster PostgreSQL e seus serviços relacionados usando o kubectl create namespace comando.

    kubectl create namespace $PG_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
    kubectl create namespace $PG_SYSTEM_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
    

Agora você pode definir outra variável de ambiente com base na opção de armazenamento desejada, que você menciona mais adiante no guia ao implantar o PostgreSQL.

Você pode referir-se à classe de armazenamento do driver CSI padrão pré-instalado dos Azure Disks SSD Premium:

export POSTGRES_STORAGE_CLASS="managed-csi-premium"

Atualizar a infraestrutura de monitoramento

O espaço de trabalho do Azure Monitor para Managed Prometheus e Azure Managed Grafana são automaticamente vinculados ao cluster AKS para métricas e visualização durante o processo de criação do cluster. Nesta seção, você habilita a coleta de logs com o AKS Container insights e valida que o Managed Prometheus está raspando métricas e o Container insights está ingerindo logs.

  1. Ative a monitorização de insights de contentores no cluster AKS utilizando o comando az aks enable-addons.

    az aks enable-addons \
        --addon monitoring \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --workspace-resource-id $ALA_RESOURCE_ID \
        --output table
    
  2. Valide se o Prometheus Gerido está a recolher métricas e o Container Insights está a ingerir logs do cluster AKS, inspecionando o DaemonSet usando o comando kubectl get e o comando az aks show.

    kubectl get ds ama-metrics-node \
        --context $AKS_PRIMARY_CLUSTER_NAME \
        --namespace=kube-system
    
    kubectl get ds ama-logs \
        --context $AKS_PRIMARY_CLUSTER_NAME \
        --namespace=kube-system
    
    az aks show \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --query addonProfiles
    

    A sua saída deve ser semelhante ao exemplo de saída a seguir, com seis nós no total (três para o pool de nós do sistema e três para o pool de nós PostgreSQL) e os insights do contentor mostrando "enabled": true:

    NAME               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR
    ama-metrics-node   6         6         6       6            6           <none>       
    
    NAME               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR
    ama-logs           6         6         6       6            6           <none>       
    
    {
      "omsagent": {
        "config": {
          "logAnalyticsWorkspaceResourceID": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/rg-cnpg-9vbin3p8/providers/Microsoft.OperationalInsights/workspaces/ala-cnpg-9vbin3p8",
          "useAADAuth": "true"
        },
        "enabled": true,
        "identity": null
      }
    }
    

Criar um IP estático público para entrada de cluster PostgreSQL

Para validar a implementação do cluster PostgreSQL e usar ferramentas cliente PostgreSQL, como psql e PgAdmin, é necessário expor a réplica primária e as réplicas somente de leitura para o tráfego de entrada. Nesta seção, cria-se um recurso de IP público do Azure que é posteriormente fornecido a um balanceador de carga do Azure para expor endereços de acesso PostgreSQL para consultas.

  1. Obtenha o nome do grupo de recursos do nó do cluster AKS usando o comando az aks show.

    export AKS_PRIMARY_CLUSTER_NODERG_NAME=$(az aks show \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --query nodeResourceGroup \
        --output tsv)
    
    echo $AKS_PRIMARY_CLUSTER_NODERG_NAME
    
  2. Crie o endereço IP público usando o az network public-ip create comando.

    export AKS_PRIMARY_CLUSTER_PUBLICIP_NAME="$AKS_PRIMARY_CLUSTER_NAME-pip"
    
    az network public-ip create \
        --resource-group $AKS_PRIMARY_CLUSTER_NODERG_NAME \
        --name $AKS_PRIMARY_CLUSTER_PUBLICIP_NAME \
        --location $PRIMARY_CLUSTER_REGION \
        --sku Standard \
        --zone 1 2 3 \
        --allocation-method static \
        --output table
    
  3. Obtenha o endereço IP público recém-criado usando o az network public-ip show comando.

    export AKS_PRIMARY_CLUSTER_PUBLICIP_ADDRESS=$(az network public-ip show \
        --resource-group $AKS_PRIMARY_CLUSTER_NODERG_NAME \
        --name $AKS_PRIMARY_CLUSTER_PUBLICIP_NAME \
        --query ipAddress \
        --output tsv)
    
    echo $AKS_PRIMARY_CLUSTER_PUBLICIP_ADDRESS
    
  4. Obtenha a ID do grupo de recursos do nó usando o comando az group show.

    export AKS_PRIMARY_CLUSTER_NODERG_NAME_SCOPE=$(az group show --name \
        $AKS_PRIMARY_CLUSTER_NODERG_NAME \
        --query id \
        --output tsv)
    
    echo $AKS_PRIMARY_CLUSTER_NODERG_NAME_SCOPE
    
  5. Atribua a função "Colaborador de Rede" ao ID do objeto UAMI usando o escopo do grupo de recursos do nó usando o az role assignment create comando.

    az role assignment create \
        --assignee-object-id ${AKS_UAMI_WORKLOAD_OBJECTID} \
        --assignee-principal-type ServicePrincipal \
        --role "Network Contributor" \
        --scope ${AKS_PRIMARY_CLUSTER_NODERG_NAME_SCOPE}
    

Instalar o operador CNPG no cluster AKS

Nesta seção, você instala o operador CNPG no cluster AKS usando Helm ou um manifesto YAML.

  1. Adicione o repositório CNPG Helm usando o helm repo add comando.

    helm repo add cnpg https://cloudnative-pg.github.io/charts
    
  2. Atualize o repositório CNPG Helm e instale-o no cluster AKS usando o comando helm upgrade com a flag --install.

    helm upgrade --install cnpg \
        --namespace $PG_SYSTEM_NAMESPACE \
        --create-namespace \
        --kube-context=$AKS_PRIMARY_CLUSTER_NAME \
        cnpg/cloudnative-pg
    
  3. Verifique a instalação do operador no cluster AKS usando o kubectl get comando.

    kubectl get deployment \
        --context $AKS_PRIMARY_CLUSTER_NAME \
        --namespace $PG_SYSTEM_NAMESPACE cnpg-cloudnative-pg
    

Próximos passos

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 | Desenvolvedora de Conteúdo Senior
  • Carol Smith | Desenvolvedora Sénior de Conteúdos
  • Erin Schaffer | Criadora de Conteúdo 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.