Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, implementará una base de datos PostgreSQL de alta disponibilidad en AKS.
- Si todavía necesita crear la infraestructura necesaria para esta implementación, siga los pasos descritos en Creación de una infraestructura para implementar una base de datos postgreSQL de alta disponibilidad en AKS para configurarla y, a continuación, vuelva a este artículo.
Important
El software de código abierto se menciona en toda la documentación y ejemplos de AKS. El software que implemente se excluye de los contratos de nivel de servicio de AKS, la garantía limitada y el Soporte técnico de Azure. A medida que usa la tecnología de código abierto junto con AKS, consulte las opciones de soporte técnico disponibles en las comunidades y los mantenedores de proyectos respectivos para desarrollar un plan.
Microsoft asume la responsabilidad de crear los paquetes de código abierto que implementamos en AKS. Esa responsabilidad incluye tener la propiedad completa del proceso de compilación, examen, firma, validación y revisión, junto con el control sobre los archivos binarios en imágenes de contenedor. Para más información, consulte Administración de vulnerabilidades para AKS y Cobertura de soporte técnico de AKS.
Creación de un secreto para el usuario de la aplicación de arranque
- Genere un secreto para validar la implementación de PostgreSQL mediante el inicio de sesión interactivo de un usuario de aplicación de arranque mediante el comando
kubectl create secret.
Important
Microsoft recomienda usar el flujo de autenticación más seguro disponible. El flujo de autenticación descrito en este procedimiento requiere un alto grado de confianza en la aplicación y conlleva riesgos que no están presentes en otros flujos. Solo debe usar este flujo cuando otros flujos más seguros, como las identidades administradas, no sean viables.
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
Compruebe que el secreto se creó correctamente mediante el comando
kubectl get.kubectl get secret db-user-pass --namespace $PG_NAMESPACE --context $AKS_PRIMARY_CLUSTER_NAME
Establecimiento de variables de entorno para el clúster de PostgreSQL
Implemente un configMap para configurar el operador CNPG mediante el siguiente
kubectl applycomando. Estos valores reemplazan el interruptor heredadoENABLE_AZURE_PVC_UPDATES, que ya no es necesario, y ayudan a escalonar las actualizaciones y acelerar las reconexiones de réplicas. Antes de implementar esta configuración en producción, compruebe que cualquier configuración existenteDRAIN_TAINTSque confíe siga siendo compatible con el entorno de Azure.cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME -n $PG_NAMESPACE -f - apiVersion: v1 kind: ConfigMap metadata: name: cnpg-controller-manager-config data: CLUSTERS_ROLLOUT_DELAY: '120' STANDBY_TCP_USER_TIMEOUT: '10' EOF
Instalación de PodMonitors de Prometheus
Prometheus extrae datos de CNPG mediante las reglas de grabación almacenadas en el repositorio de ejemplos de CNPG en GitHub. Dado que el PodMonitor administrado por el operador está quedando obsoleto, cree y gestione usted mismo el recurso PodMonitor para adaptarlo adecuadamente a su pila de supervisión.
Agregue el repositorio de Helm de la comunidad de Prometheus mediante el comando
helm repo add.helm repo add prometheus-community \ https://prometheus-community.github.io/helm-chartsActualice el repositorio de Helm de la comunidad de Prometheus e instálelo en el clúster principal mediante el comando
helm upgradecon la marca--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_NAMECree un PodMonitor para el clúster. El equipo de CNPG está dejando de usar el PodMonitor gestionado por el operador, por lo que ahora lo gestiona directamente:
cat <<EOF | kubectl apply --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -f - apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: $PG_PRIMARY_CLUSTER_NAME namespace: ${PG_NAMESPACE} labels: cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME} spec: selector: matchLabels: cnpg.io/cluster: ${PG_PRIMARY_CLUSTER_NAME} podMetricsEndpoints: - port: metrics EOF
Creación de una credencial federada
En esta sección, creará una credencial de identidad federada para la copia de seguridad de PostgreSQL para permitir que CNPG use la identidad de carga de trabajo de AKS para autenticarse en el destino de la cuenta de almacenamiento para las copias de seguridad. El operador CNPG crea una cuenta de servicio de Kubernetes con el mismo nombre que el clúster denominado usado en el manifiesto de implementación del clúster CNPG.
Obtenga la dirección URL del emisor de OIDC del clúster mediante el 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)"Cree una credencial de identidad federada mediante el 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
Implementación de un clúster de PostgreSQL de alta disponibilidad
En esta sección, implementará un clúster de PostgreSQL de alta disponibilidad mediante la definición de recursos personalizados (CRD) del clúster CNPG.
Parámetros de CRD de clúster
En la tabla siguiente se describen las propiedades clave establecidas en el manifiesto de implementación de YAML para el CRD de clúster:
| Property | Definition |
|---|---|
imageName |
Apunta a la imagen de contenedor del operando CloudNativePG. Use ghcr.io/cloudnative-pg/postgresql:18-system-trixie con la integración de copia de seguridad en núcleo que se muestra en esta guía o cambie a 18-standard-trixie cuando adopte el complemento Barman Cloud. |
inheritedMetadata |
Específico del operador CNPG. El operador CNPG aplica los metadatos a todos los objetos relacionados con el clúster. |
annotations |
Incluye la etiqueta DNS necesaria al exponer los puntos de conexión del clúster y habilita alpha.cnpg.io/failoverQuorum la conmutación por error basada en cuórum. |
labels: azure.workload.identity/use: "true" |
Indica que AKS debe insertar dependencias de identidad de carga de trabajo en los pods que hospedan las instancias del clúster de PostgreSQL. |
topologySpreadConstraints |
Requerir zonas diferentes y nodos diferentes con la etiqueta "workload=postgres". |
resources |
Configura una clase de calidad de servicio (QoS) de Garantizado. En un entorno de producción, estos valores son clave para maximizar el uso de la máquina virtual del nodo subyacente y variar en función de la SKU de máquina virtual de Azure usada. |
probes |
Reemplaza la configuración heredada startDelay . Los sondeos de inicio y preparación de streaming ayudan a garantizar que las réplicas estén en buen estado antes de atender el tráfico. |
smartShutdownTimeout |
Permite que las transacciones de larga duración finalicen correctamente durante las actualizaciones en lugar de usar retrasos de detención agresivos. |
bootstrap |
Específico del operador CNPG. Inicializa con una base de datos de aplicación vacía. |
storage |
Define los ajustes de PersistentVolume para la base de datos. Con los discos administrados de Azure, la sintaxis simplificada mantiene los datos y WAL en el mismo volumen de 64 GiB, lo que ofrece mejores niveles de rendimiento en discos administrados. Ajuste si necesita volúmenes WAL independientes. |
postgresql.synchronous |
minSyncReplicas
/
maxSyncReplicas Reemplaza y permite especificar el comportamiento de replicación sincrónica mediante el esquema más reciente. |
postgresql.parameters |
Específico del operador CNPG. Asigna la configuración de postgresql.conf, pg_hba.conf y pg_ident.conf. En el ejemplo se resaltan los valores predeterminados de observabilidad y retención de WAL que se adaptan al escenario de identidad de carga de trabajo de AKS, pero que se deben ajustar por carga de trabajo. |
serviceAccountTemplate |
Contiene la plantilla necesaria para generar las cuentas de servicio y asignar la credencial de identidad federada de AKS a la UAMI para habilitar la autenticación de identidad de carga de trabajo de AKS desde los pods que hospedan las instancias de PostgreSQL a recursos externos de Azure. |
barmanObjectStore |
Específico del operador CNPG. Configura el conjunto de herramientas barman-cloud mediante la identidad de carga de trabajo de AKS para la autenticación en el almacén de objetos de Azure Blob Storage. |
Para aislar aún más las cargas de trabajo de PostgreSQL, puede agregar un taint (por ejemplo, node-role.kubernetes.io/postgres=:NoSchedule) a los nodos del plano de datos y reemplazar el ejemplo nodeSelector/tolerations por los valores recomendados por CloudNativePG. Si adopta este enfoque, etiquete los nodos en consecuencia y confirme que las directivas de escalador automático de AKS se alinean con la topología.
Parámetros de rendimiento de PostgreSQL
El rendimiento de PostgreSQL depende en gran medida de los recursos y la carga de trabajo subyacentes del clúster. En la tabla siguiente se proporcionan instrucciones de línea base para un clúster de tres nodos que se ejecutan en nodos estándar D4s v3 (memoria de 16 GiB). Considere estos valores como punto de partida y ajústelos cuando comprenda su perfil de carga de trabajo.
| Property | Valor recomendado | Definition |
|---|---|---|
wal_compression |
lz4 | Comprime las escrituras de página completa escritas en el archivo WAL con el método especificado |
max_wal_size |
6 GB | Establece el tamaño de WAL que desencadena un punto de control |
checkpoint_timeout |
15 minutos | Establece el tiempo máximo entre los puntos de control WAL automáticos. |
checkpoint_completion_target |
0.9 | Equilibra el trabajo del punto de control en la ventana de punto de control |
checkpoint_flush_after |
2 MB | Número de páginas después de las cuales las escrituras realizadas anteriormente se vacían en el disco |
wal_writer_flush_after |
2 MB | Cantidad de WAL escrita por el escritor de WAL que desencadena un vaciado |
min_wal_size |
2 GB | Establece el tamaño mínimo al que reducir WAL |
max_slot_wal_keep_size |
10 GB | Límite superior para ranuras de replicación de WAL para servicio |
shared_buffers |
4 GB | Establece el número de búferes de memoria compartidos usados por el servidor (25% de memoria de nodo en este ejemplo) |
effective_cache_size |
12 GB | Establece la suposición del planificador sobre el tamaño total de las cachés de datos. |
work_mem |
1/256 de memoria de nodo | Establece la memoria máxima que se va a usar para las áreas de trabajo de consulta. |
maintenance_work_mem |
6,25 % de la memoria del nodo | Establece la memoria máxima que se va a usar para las operaciones de mantenimiento. |
autovacuum_vacuum_cost_limit |
2400 | Cantidad de coste de vacío disponible antes de suspensión, para el vaciado automático |
random_page_cost |
1.1 | Establece la estimación del planificador del costo de una página de disco recuperada de forma no secuencial. |
effective_io_concurrency |
64 | Establece cuántas solicitudes simultáneas puede controlar el subsistema de disco de forma eficaz |
maintenance_io_concurrency |
64 | Variante de "effective_io_concurrency" que se usa para el trabajo de mantenimiento |
Implementación de PostgreSQL
Implemente el clúster de PostgreSQL con el CRD de clúster mediante el 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 annotations: alpha.cnpg.io/failoverQuorum: "true" spec: imageName: ghcr.io/cloudnative-pg/postgresql:18-system-trixie inheritedMetadata: annotations: service.beta.kubernetes.io/azure-dns-label-name: $AKS_PRIMARY_CLUSTER_PG_DNSPREFIX labels: azure.workload.identity/use: "true" instances: 3 smartShutdownTimeout: 30 probes: startup: type: streaming maximumLag: 32Mi periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 120 readiness: type: streaming maximumLag: 0 periodSeconds: 10 failureThreshold: 6 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: storageClass: $POSTGRES_STORAGE_CLASS size: 64Gi postgresql: synchronous: method: any number: 1 parameters: wal_compression: lz4 max_wal_size: 6GB max_slot_wal_keep_size: 10GB checkpoint_timeout: 15min checkpoint_completion_target: '0.9' checkpoint_flush_after: 2MB wal_writer_flush_after: 2MB min_wal_size: 2GB 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" log_checkpoints: 'on' log_lock_waits: 'on' log_min_duration_statement: '1000' log_statement: 'ddl' log_temp_files: '1024' log_autovacuum_min_duration: '1s' pg_stat_statements.max: '10000' pg_stat_statements.track: 'all' hot_standby_feedback: 'on' 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
Nota:
El manifiesto de ejemplo usa la imagen ghcr.io/cloudnative-pg/postgresql:18-system-trixie porque está integrado con el núcleo de Barman Cloud, tal y como se muestra más adelante. Cuando esté listo para cambiar al complemento Barman Cloud, actualice spec.imageName a ghcr.io/cloudnative-pg/postgresql:18-standard-trixie y siga las instrucciones de configuración del complemento antes de volver a implementar el clúster.
Important
La entrada de ejemplo pg_hba permite el acceso no TLS. Si mantiene esta configuración, documente las implicaciones de seguridad del equipo y prefiera conexiones cifradas siempre que sea posible.
Compruebe que el clúster de PostgreSQL principal se creó correctamente mediante el comando
kubectl get. La CRD del clúster CNPG especificó tres instancias, que se pueden validar mediante la visualización de pods en ejecución una vez que cada instancia se abre y se une para la replicación. Tenga paciencia, ya que puede tardar algún tiempo en conectarse a las tres instancias y unirse al clúster.kubectl get pods --context $AKS_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAMESalida de ejemplo
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
Important
Si usa NVMe local con Almacenamiento de contenedores de Azure y el pod permanece en estado de inicialización con un error de conexión múltiple, el pod sigue buscando el volumen en un nodo perdido. Una vez que el pod comienza a ejecutarse, entra en un CrashLoopBackOff estado porque CNPG crea una nueva réplica en un nuevo nodo sin datos y no encuentra el pgdata directorio. Para resolver este problema, destruya la instancia afectada y abra una nueva. Ejecute el siguiente comando:
kubectl cnpg destroy [cnpg-cluster-name] [instance-number]
Validar que Prometheus PodMonitor se está ejecutando
El PodMonitor creado manualmente vincula la configuración de extracción kube-prometheus-stack a los pods CNPG que implementó anteriormente.
Valide que PodMonitor se está ejecutando con el comando kubectl get.
kubectl --namespace $PG_NAMESPACE \
--context $AKS_PRIMARY_CLUSTER_NAME \
get podmonitors.monitoring.coreos.com \
$PG_PRIMARY_CLUSTER_NAME \
--output yaml
Salida de ejemplo
kind: PodMonitor
metadata:
labels:
cnpg.io/cluster: pg-primary-cnpg-r8c7unrw
name: pg-primary-cnpg-r8c7unrw
namespace: cnpg-database
spec:
podMetricsEndpoints:
- port: metrics
selector:
matchLabels:
cnpg.io/cluster: pg-primary-cnpg-r8c7unrw
Si usa Azure Monitor para Managed Prometheus, debe agregar otro monitor de pod mediante el nombre del grupo personalizado. Prometheus administrado no recoge las definiciones de recursos personalizados (CRD) de la comunidad de Prometheus. Aparte del nombre del grupo, los CRD son los mismos. Ese diseño permite que los monitores de pod para Prometheus administrado se ejecuten junto con monitores de pod que usan la CRD de la comunidad. Si no usa Prometheus administrado, puede omitir esta sección. Cree un nuevo monitor de 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
Compruebe que se crea el monitor de pods (tenga en cuenta la diferencia en el nombre del grupo).
kubectl --namespace $PG_NAMESPACE \
--context $AKS_PRIMARY_CLUSTER_NAME \
get podmonitors.azmonitoring.coreos.com \
-l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME \
-o yaml
Opción A: área de trabajo de Azure Monitor
Después de implementar el clúster de Postgres y el monitor de pods, puede ver las métricas mediante Azure Portal en un área de trabajo de Azure Monitor.
Opción B: Grafana administrada
Como alternativa, después de implementar los monitores de pod y clúster de Postgres, puede crear un panel de métricas en la instancia de Grafana administrada creada por el script de implementación para visualizar las métricas exportadas al área de trabajo de Azure Monitor. Puede acceder a Grafana administrada a través de Azure Portal. Vaya a la instancia de Grafana administrada creada por el script de implementación y seleccione el enlace endpoint como se indica aquí:
Al seleccionar el vínculo de endpoint, se abre una nueva ventana del navegador donde puede crear paneles en la instancia administrada de Grafana. Siguiendo las instrucciones para configurar un origen de datos de Azure Monitor, puede agregar visualizaciones para crear un panel de métricas desde el clúster de Postgres. Después de configurar la conexión de origen de datos, en el menú principal, seleccione la opción Orígenes de datos. Debería ver un conjunto de opciones de origen de datos para la conexión del origen de datos, como se muestra aquí:
En la opción Managed Prometheus (Prometheus administrado), seleccione la opción para crear un panel para abrir el editor del panel. Una vez que se abra la ventana del editor, seleccione la opción Agregar visualización y, después, seleccione la opción Managed Prometheus para examinar las métricas desde el clúster de Postgres. Después de seleccionar la métrica que desea visualizar, seleccione el botón Ejecutar consultas para capturar los datos de la visualización, como se muestra aquí:
Seleccione el icono Guardar para agregar el panel al tablero. Puede agregar otros paneles seleccionando el botón Agregar en el editor del panel y repitiendo este proceso para visualizar otras métricas. Al agregar las visualizaciones de métricas, debe tener algo similar al siguiente:
Seleccione el icono Guardar para guardar el panel.
Pasos siguientes
Contributors
Microsoft se encarga del mantenimiento de este artículo. Los siguientes colaboradores lo escribieron originalmente:
- Ken Kilty | TPM de entidad de seguridad
- Russell de Pina | TPM de entidad de seguridad
- Adrian Joian | Ingeniero de clientes sénior
- Jenny Hayes | Desarrollador de contenido sénior
- Carol Smith | Desarrollador de contenido sénior
- Erin Schaffer | Desarrollador de contenido 2
- Adam Fabric | Ingeniero de clientes 2
Reconocimiento
Esta documentación se desarrolló conjuntamente con EnterpriseDB, los mantenedores del operador CloudNativePG. Agradecemos a Gabriele Bartolini por revisar los borradores anteriores de este documento y ofrecer mejoras técnicas.