Condividi tramite


Distribuire un database PostgreSQL a disponibilità elevata sul servizio Azure Kubernetes

In questo articolo, implementerai un database PostgreSQL ad alta disponibilità su AKS.

Importante

Il software open source è citato nella documentazione e negli esempi di AKS (Azure Kubernetes Service). Il software che distribuisci è escluso dai contratti di livello di servizio di AKS, dalla garanzia limitata e dal supporto tecnico di Azure. Quando si usa la tecnologia open source insieme al servizio Azure Kubernetes, consultare le opzioni del supporto disponibili nelle rispettive community e i gestori di progetto per sviluppare un piano.

Ad esempio, il repository GitHub Ray descrive diverse piattaforme che variano in tempo di risposta, scopo e livello di supporto.

Microsoft si assume la responsabilità di creare i pacchetti open source che distribuiamo su AKS. Tale responsabilità include la proprietà completa del processo di compilazione, analisi, firma, convalida e hotfix, oltre al controllo sui file binari nelle immagini del contenitore. Per altre informazioni, vedere Gestione delle vulnerabilità per il servizio Azure Kubernetes e Copertura del supporto del servizio Azure Kubernetes.

Creare un segreto per l'utente dell'app bootstrap

  1. Generare un segreto per convalidare la distribuzione di PostgreSQL tramite l'accesso interattivo per un utente dell'app bootstrap usando il comando kubectl create secret.

    PG_DATABASE_APPUSER_SECRET=$(echo -n | openssl rand -base64 16)
    
    kubectl create secret generic db-user-pass \
        --from-literal=username=app \
        --from-literal=password="${PG_DATABASE_APPUSER_SECRET}" \
        --namespace $PG_NAMESPACE \
        --context $AKS_PRIMARY_CLUSTER_NAME
    
  2. Verificare che il segreto sia stato creato correttamente usando il comando kubectl get.

    kubectl get secret db-user-pass --namespace $PG_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
    

Impostare le variabili di ambiente per il cluster PostgreSQL

  • Distribuire un oggetto ConfigMap per impostare le variabili di ambiente per il cluster PostgreSQL usando il comando kubectl apply seguente:

    cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
        name: cnpg-controller-manager-config
    data:
        ENABLE_AZURE_PVC_UPDATES: 'true'
    EOF
    

Installare i PodMonitors di Prometheus

Prometheus crea PodMonitors per le istanze CNPG usando un set di regole di registrazione predefinite, archiviate nel repository di esempi GitHub CNPG. In un ambiente di produzione queste regole verranno modificate in base alle esigenze.

  1. Aggiungere il repository Helm della community Prometheus usando il comando helm repo add.

    helm repo add prometheus-community \
        https://prometheus-community.github.io/helm-charts
    
  2. Aggiornare il repository Helm della community Prometheus e installarlo nel cluster primario usando il comando helm upgrade con il flag --install.

    helm upgrade --install \
        --namespace $PG_NAMESPACE \
        -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/docs/src/samples/monitoring/kube-stack-config.yaml \
        prometheus-community \
        prometheus-community/kube-prometheus-stack \
        --kube-context=$AKS_PRIMARY_CLUSTER_NAME
    

Creare una credenziale federata

In questa sezione, crei una credenziale di identità federata per il backup di PostgreSQL, per consentire a CNPG di utilizzare l'identità del carico di lavoro di AKS per autenticarsi alla destinazione dell'account di archiviazione per i backup. L'operatore CNPG crea un account di servizio Kubernetes con lo stesso nome del cluster specificato nel manifesto di distribuzione del cluster CNPG.

  1. Ottenere l'URL dell'autorità di certificazione OIDC del cluster usando il comando az aks show.

    export AKS_PRIMARY_CLUSTER_OIDC_ISSUER="$(az aks show \
        --name $AKS_PRIMARY_CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP_NAME \
        --query "oidcIssuerProfile.issuerUrl" \
        --output tsv)"
    
  2. Creare una credenziale di identità federata tramite il comando az identity federated-credential create.

    az identity federated-credential create \
        --name $AKS_PRIMARY_CLUSTER_FED_CREDENTIAL_NAME \
        --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}" \
        --audience api://AzureADTokenExchange
    

Distribuire un cluster PostgreSQL a disponibilità elevata

In questa sezione viene distribuito un cluster PostgreSQL a disponibilità elevata usando la definizione di risorsa personalizzata (CRD) del cluster CNPG.

Parametri CRD del cluster

Nella tabella seguente sono riportate le proprietà principali definite nel manifesto di distribuzione YAML per il CRD del Cluster.

Proprietà Definizione
inheritedMetadata Specifico dell'operatore CNPG. I metadati vengono ereditati da tutti gli oggetti correlati al cluster.
annotations: service.beta.kubernetes.io/azure-dns-label-name Etichetta DNS da usare quando si espongono gli endpoint del cluster Postgres di lettura/scrittura e di sola lettura.
labels: azure.workload.identity/use: "true" Indica che il servizio Azure Kubernetes deve inserire le dipendenze dell'identità del carico di lavoro nei pod che ospitano le istanze del cluster PostgreSQL.
topologySpreadConstraints Richiedere zone e nodi diversi con etichetta "workload=postgres".
resources Configura una classe QoS (Quality of Service) Garantita. In un ambiente di produzione, questi valori sono fondamentali per ottimizzare l'utilizzo della macchina virtuale del nodo sottostante e variare in base allo SKU della macchina virtuale di Azure usato.
bootstrap Specifico dell'operatore CNPG. Inizializza con un database dell'app vuoto.
storage / walStorage Specifico dell'operatore CNPG. Definisce i modelli di archiviazione per i PVC (PersistentVolumeClaims) per l'archiviazione di dati e log. È inoltre possibile specificare lo spazio di archiviazione per gli spazi di tabella da partizionare per aumentare le operazioni di I/O.
replicationSlots Specifico dell'operatore CNPG. Abilita gli slot di replica per la disponibilità elevata.
postgresql Specifico dell'operatore CNPG. Mappa le impostazioni per postgresql.conf, pg_hba.conf e pg_ident.conf config.
serviceAccountTemplate Contiene il modello necessario per generare gli account del servizio ed eseguire il mapping delle credenziali dell'identità federata del servizio Azure Kubernetes all'UAMI per abilitare l'autenticazione dell'identità del carico di lavoro del servizio Azure Kubernetes dai pod che ospitano le istanze di PostgreSQL per risorse di Azure esterne.
barmanObjectStore Specifico dell'operatore CNPG. Configura la suite di strumenti barman-cloud usando l'identità del carico di lavoro del servizio Azure Kubernetes per l'autenticazione nell'archivio oggetti di Archiviazione BLOB di Azure.

Parametri delle prestazioni di PostgreSQL

Le prestazioni di PostgreSQL dipendono in modo pesante dalle risorse sottostanti del cluster. La tabella seguente fornisce alcuni suggerimenti su come calcolare i parametri chiave per prestazioni elevate:

Proprietà Valore consigliato Definizione
wal_compression lz4 Comprime le scritture a pagina intera scritte nel file WAL con il metodo specificato
max_wal_size 6 GB Imposta le dimensioni WAL che attivano un punto di controllo
checkpoint_timeout 15 minuti Imposta il tempo massimo tra punti di controllo WAL automatici
checkpoint_flush_after 2 MB Numero di pagine dopo le quali le scritture eseguite in precedenza vengono scaricate su disco
wal_writer_flush_after 2 MB Quantità di WAL scritta dal writer WAL che attiva uno scaricamento
min_wal_size 4 GB Imposta le dimensioni minime per ridurre il WAL.
shared_buffers 25% della memoria del nodo Imposta il numero di buffer di memoria condivisa utilizzati dal server
effective_cache_size 75% della memoria del nodo Imposta il presupposto della pianificazione sulle dimensioni totali delle cache dei dati
work_mem 1/256 della memoria del nodo Imposta la memoria massima da usare per le aree di lavoro di query
maintenance_work_mem 6,25% della memoria del nodo Imposta la memoria massima da utilizzare per le operazioni di manutenzione
autovacuum_vacuum_cost_limit 2400 Importo costo vuoto disponibile prima del napping per autovacuum
random_page_cost 1.1 Imposta la stima della pianificazione del costo di una pagina disco recuperata in modo non sequenziale
effective_io_concurrency 64 Numero di richieste simultanee che possono essere gestite in modo efficiente dal sottosistema del disco
maintenance_io_concurrency 64 Variante di "effective_io_concurrency" usata per il lavoro di manutenzione

Distribuzione di PostgreSQL

  1. Distribuire il cluster PostgreSQL con il Cluster CRD usando il comando kubectl apply.

    cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -v 9 -f -
    apiVersion: postgresql.cnpg.io/v1
    kind: Cluster
    metadata:
      name: $PG_PRIMARY_CLUSTER_NAME
    spec:
      inheritedMetadata:
        annotations:
          service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX
          acstor.azure.com/accept-ephemeral-storage: "true"
        labels:
          azure.workload.identity/use: "true"
    
      instances: 3
      startDelay: 30
      stopDelay: 30
      minSyncReplicas: 1
      maxSyncReplicas: 1
      replicationSlots:
        highAvailability:
          enabled: true
        updateInterval: 30
    
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            cnpg.io/cluster: $PG_PRIMARY_CLUSTER_NAME
    
      affinity:
        nodeSelector:
          workload: postgres
    
      resources:
        requests:
          memory: '8Gi'
          cpu: 2
        limits:
          memory: '8Gi'
          cpu: 2
    
      bootstrap:
        initdb:
          database: appdb
          owner: app
          secret:
            name: db-user-pass
          dataChecksums: true
    
      storage:
        size: 32Gi
        pvcTemplate:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 32Gi
          storageClassName: $POSTGRES_STORAGE_CLASS
    
      walStorage:
        size: 32Gi
        pvcTemplate:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 32Gi
          storageClassName: $POSTGRES_STORAGE_CLASS
    
      monitoring:
        enablePodMonitor: true
    
      postgresql:
        parameters:
          wal_compression: lz4
          max_wal_size: 6GB
          checkpoint_timeout: 15min
          checkpoint_flush_after: 2MB
          wal_writer_flush_after: 2MB
          min_wal_size: 4GB
          shared_buffers: 4GB
          effective_cache_size: 12GB
          work_mem: 62MB
          maintenance_work_mem: 1GB
          autovacuum_vacuum_cost_limit: "2400"
          random_page_cost: "1.1"
          effective_io_concurrency: "64"
          maintenance_io_concurrency: "64"
        pg_hba:
          - host all all all scram-sha-256
    
      serviceAccountTemplate:
        metadata:
          annotations:
            azure.workload.identity/client-id: "$AKS_UAMI_WORKLOAD_CLIENTID"
          labels:
            azure.workload.identity/use: "true"
    
      backup:
        barmanObjectStore:
          destinationPath: "https://${PG_PRIMARY_STORAGE_ACCOUNT_NAME}.blob.core.windows.net/backups"
          azureCredentials:
            inheritFromAzureAD: true
        retentionPolicy: '7d'
    EOF
    
  2. Verificare che il cluster PostgreSQL primario sia stato creato correttamente usando il comando kubectl get. CRD cluster CNPG ha specificato tre istanze, che possono essere convalidate visualizzando i pod in esecuzione una volta che ogni istanza viene aperta e unita per la replica. Abbiate pazienza, poiché potrebbe essere necessario del tempo prima che tutte e tre le istanze siano online e si uniscano al cluster.

    kubectl get pods --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME
    

    Output di esempio

    NAME                         READY   STATUS    RESTARTS   AGE
    pg-primary-cnpg-r8c7unrw-1   1/1     Running   0          4m25s
    pg-primary-cnpg-r8c7unrw-2   1/1     Running   0          3m33s
    pg-primary-cnpg-r8c7unrw-3   1/1     Running   0          2m49s
    

Importante

Se si usa NVMe locale con l'archiviazione di Azure Container e il pod è bloccato nello stato init con un errore multi-attach, è probabile che la ricerca del volume in un nodo perso sia ancora in corso. Dopo l'avvio del pod, entrerà nello stato CrashLoopBackOff perché è stata creata una nuova replica nel nuovo nodo senza dati e CNPG non riesce a trovare la directory pgdata. Per risolvere questo problema, è necessario eliminare definitivamente l'istanza interessata e visualizzare una nuova istanza. Eseguire il comando seguente:

kubectl cnpg destroy [cnpg-cluster-name] [instance-number]  

Verificare che PodMonitor Prometheus sia in esecuzione

L'operatore CNPG crea automaticamente un PodMonitor per l'istanza primaria usando le regole di registrazione create durante l'installazione della community Prometheus.

  1. Verificare che PodMonitor sia in esecuzione usando il comando kubectl get.

    kubectl --namespace $PG_NAMESPACE \
        --context $AKS_PRIMARY_CLUSTER_NAME \
        get podmonitors.monitoring.coreos.com \
        $PG_PRIMARY_CLUSTER_NAME \
        --output yaml
    

    Output di esempio

     kind: PodMonitor
     metadata:
      annotations:
        cnpg.io/operatorVersion: 1.23.1
    ...
    

Se si usa Monitoraggio di Azure per Prometheus gestito, sarà necessario aggiungere un altro monitoraggio pod usando il nome del gruppo personalizzato. Prometheus gestito non preleva le definizioni di risorse personalizzate (CRD) dalla community Prometheus. A parte il nome del gruppo, i CRD sono gli stessi. In questo modo, i monitoraggi dei pod per Prometheus gestito possono essere affiancati a quelli che usano il monitoraggio dei pod della community. Se non si usa Prometheus gestito, si possono ignorare queste indicazioni. Creare un nuovo monitoraggio pod:

cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -f -
apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: cnpg-cluster-metrics-managed-prometheus
  namespace: ${PG_NAMESPACE}
  labels:
    azure.workload.identity/use: "true"
    cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
spec:
  selector:
    matchLabels:
      azure.workload.identity/use: "true"
      cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME}
  podMetricsEndpoints:
    - port: metrics
EOF

Verificare che il monitoraggio pod sia stato creato (si noti la differenza nel nome del gruppo).

kubectl --namespace $PG_NAMESPACE \
    --context $AKS_PRIMARY_CLUSTER_NAME \
    get podmonitors.azmonitoring.coreos.com \
    -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME \
    -o yaml

Opzione A - Area di lavoro di Monitoraggio di Azure

Dopo aver distribuito il cluster Postgres e il monitoraggio dei pod, è possibile visualizzare le metriche usando il portale di Azure in un'area di lavoro di Monitoraggio di Azure.

Screenshot che mostra le metriche in un'area di lavoro di Monitoraggio di Azure.

Opzione B - Grafana gestito

In alternativa, dopo aver distribuito il cluster Postgres e i monitoraggi dei pod, è possibile creare un dashboard delle metriche nell'istanza di Grafana gestita creata dallo script di distribuzione per visualizzare le metriche esportate nell'area di lavoro di Monitoraggio di Azure. È possibile accedere a Grafana gestito tramite il portale di Azure. Passare all'istanza di Grafana gestita creata dallo script di distribuzione e fare clic sul collegamento Endpoint come illustrato qui:

Screenshot che mostra un'istanza di Grafana con gestione Azure.

Facendo clic sul collegamento Endpoint verrà aperta una nuova finestra del browser in cui è possibile creare dashboard nell'istanza di Grafana gestito. Seguendo le istruzioni per configurare un'origine dati di Monitoraggio di Azure, è possibile aggiungere visualizzazioni per creare un dashboard di metriche dal cluster Postgres. Dopo aver configurato la connessione all'origine dati, dal menu principale cliccare sull'opzione Origini dati e verrà visualizzato un set di opzioni per l'origine dati per la connessione all'origine dati, come illustrato di seguito:

Screenshot che mostra le opzioni per l’origine dati.

Nell'opzione Prometheus gestito cliccare sull'opzione di creazione di un dashboard per aprire l'editor del dashboard. Dopo aver aperto la finestra dell'editor, fare clic sull'opzione Aggiungi visualizzazione, quindi fare clic sull'opzione Prometheus gestito per esplorare le metriche dal cluster Postgres. Dopo aver selezionato la metrica da visualizzare, fare clic sul pulsante Esegui query per recuperare i dati per la visualizzazione, come illustrato di seguito:

Screenshot che mostra il dashboard del costrutto.

Cliccare sul pulsante Salva per aggiungere il pannello al dashboard. È possibile aggiungere altri pannelli facendo clic sul pulsante Aggiungi nell'editor del dashboard e ripetendo questo processo per visualizzare altre metriche. L'aggiunta delle visualizzazioni delle metriche dovrebbe avere un aspetto simile al seguente:

Screenshot che mostra il dashboard di salvataggio.

Cliccare sull'icona Salva per salvare il dashboard.


Passaggi successivi

Collaboratori

Microsoft gestisce questo articolo. I collaboratori seguenti l'hanno originariamente scritto:

  • Ken Kilty | Responsabile TPM
  • Russell de Pina | Responsabile TPM
  • Adrian Joian | Senior Customer Engineer
  • Jenny Hayes | Sviluppatore di contenuti senior
  • Carol Smith | Sviluppatore di contenuti senior
  • Erin Schaffer | Sviluppatore di contenuti 2
  • Adam Sharif | Ingegnere del Cliente 2