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, realizará varios pasos de prueba y validación en una base de datos postgreSQL implementada en AKS. Esto incluye comprobar la implementación, conectarse a la base de datos y probar escenarios de conmutación por error.
- Si aún no ha implementado PostgreSQL, siga los pasos descritos en Implementación de una base de datos postgreSQL de alta disponibilidad en AKS con la CLI de Azure para configurar y, a continuación, puede volver a este artículo.
Importante
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 ser plenamente responsable del proceso de compilación, escaneo, firma, validación y corrección rápida, junto con el control de los binarios en las imágenes de contenedor. Para obtener más información, consulte Administración de vulnerabilidades para AKS y Cobertura del soporte técnico de AKS.
Inspección del clúster de PostgreSQL implementado
Compruebe que PostgreSQL se distribuye entre varias zonas de disponibilidad mediante la recuperación de los detalles del nodo de AKS mediante el 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"}'
La salida debe ser similar a la siguiente salida de ejemplo con la zona de disponibilidad que se muestra para cada nodo:
{
"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"
}
Conexión a PostgreSQL y creación de un conjunto de datos de ejemplo
En esta sección, creará una tabla e insertará algunos datos en la base de datos de la aplicación que se creó en el CRD del clúster CNPG que implementó anteriormente. Use estos datos para validar las operaciones de copia de seguridad y restauración del clúster de PostgreSQL.
Cree una tabla e inserte datos en la base de datos de la aplicación mediante los siguientes 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;Escriba
\qpara salir de psql cuando termine.La salida debería ser similar a la salida de ejemplo siguiente:
CREATE TABLE INSERT 0 1 INSERT 0 1 INSERT 0 1 count ------- 3 (1 row)
Conexión a réplicas de solo lectura de PostgreSQL
Conéctese a las réplicas de solo lectura de PostgreSQL y valide el conjunto de datos de ejemplo mediante los siguientes comandos:
kubectl cnpg psql --replica $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACESELECT pg_is_in_recovery();Salida de ejemplo
pg_is_in_recovery ------------------- t (1 row)SELECT COUNT(*) FROM datasample;Salida de ejemplo
count ------- 3 (1 row)
Configuración de copias de seguridad de PostgreSQL a petición y programadas mediante Barman
Nota:
Se espera que CloudNativePG desuse el soporte nativo de Barman Cloud en favor del complemento Barman Cloud en una próxima versión 1.29. Los pasos de esta guía siguen funcionando hoy, pero planea migrar al complemento una vez que se estabiliza.
Compruebe que el clúster de PostgreSQL puede acceder a la cuenta de almacenamiento de Azure especificada en el CRD del clúster CNPG y que
Working WAL archivingnotifica comoOKmediante el comando siguiente:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACESalida de ejemplo
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: -Implemente una copia de seguridad a petición en Azure Storage, que usa la integración de identidades de carga de trabajo de AKS mediante el archivo YAML con el comando
kubectl apply.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 el estado de la copia de seguridad a petición mediante el comando
kubectl describe.kubectl describe backup $BACKUP_ONDEMAND_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACESalida de ejemplo
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 completedCompruebe que el clúster tiene un primer punto de capacidad de recuperación mediante el siguiente comando:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACESalida de ejemplo
Continuous Backup status First Point of Recoverability: 2024-06-05T13:47:18Z Working WAL archiving: OKConfigure una copia de seguridad programada para cada hora a 15 minutos después de la hora mediante el archivo YAML con el comando
kubectl apply.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 el estado de la copia de seguridad programada mediante el comando
kubectl describe.kubectl describe scheduledbackup $BACKUP_SCHEDULED_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEVea los archivos de copia de seguridad almacenados en Azure Blob Storage para el clúster principal mediante el comando
az storage blob list.az storage blob list \ --account-name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \ --container-name backups \ --query "[*].name" \ --only-show-errorsLa salida debe ser similar a la siguiente salida de ejemplo, lo que valida que la copia de seguridad se realizó correctamente:
[ "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" ]
Restauración de la copia de seguridad a petición en un nuevo clúster de PostgreSQL
En esta sección, restaurará la copia de seguridad a petición que creó anteriormente mediante el operador CNPG en una nueva instancia mediante el CRD de clúster de arranque. Se usa un único clúster de instancia para simplificar. Recuerde que la identidad de carga de trabajo de AKS (a través de inheritFromAzureAD de CNPG) tiene acceso a los archivos de copia de seguridad y que el nombre del clúster de recuperación se usa para generar una nueva cuenta de servicio de Kubernetes específica del clúster de recuperación.
También se crea una segunda credencial federada para asignar la nueva cuenta de servicio de clúster de recuperación a la UAMI existente que tiene acceso de "Colaborador de datos de blobs de almacenamiento" a los archivos de copia de seguridad en Blob Storage.
Cree una segunda credencial de identidad federada mediante el comando
az identity federated-credential create.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 la copia de seguridad a petición mediante el CRD de clúster con el 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 EOFConéctese a la instancia recuperada y, a continuación, compruebe que el conjunto de datos creado en el clúster original donde se realizó la copia de seguridad completa está presente mediante el siguiente comando:
kubectl cnpg psql $PG_PRIMARY_CLUSTER_NAME_RECOVERED --namespace $PG_NAMESPACESELECT COUNT(*) FROM datasample;Salida de ejemplo
count ------- 3 (1 row) Type \q to exit psqlElimine el clúster recuperado mediante el comando siguiente:
kubectl cnpg destroy $PG_PRIMARY_CLUSTER_NAME_RECOVERED 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACEElimine la credencial de identidad federada mediante el comando
az identity federated-credential delete.az identity federated-credential delete \ --name $PG_PRIMARY_CLUSTER_NAME_RECOVERED \ --identity-name $AKS_UAMI_CLUSTER_IDENTITY_NAME \ --resource-group $RESOURCE_GROUP_NAME \ --yes
Exposición del clúster de PostgreSQL mediante un equilibrador de carga público
En esta sección, configurará la infraestructura necesaria para exponer públicamente los puntos de conexión de lectura y escritura de PostgreSQL y de solo lectura con restricciones de origen de IP a la dirección IP pública de la estación de trabajo cliente.
También se recuperan los siguientes puntos de conexión del servicio IP del clúster:
-
Un punto de conexión de lectura y escritura principal que termina con
*-rw. -
Cero a N (dependiendo del número de réplicas) puntos de conexión de solo lectura que terminan con
*-ro. -
Un punto de conexión de replicación que termina con
*-r.
Obtenga los detalles del servicio IP del clúster mediante el comando
kubectl get.kubectl get services \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE \ -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAMESalida de ejemplo
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 3h57mNota:
Hay tres servicios:
namespace/cluster-name-roasignados al puerto 5433,namespace/cluster-name-rwynamespace/cluster-name-rasignados al puerto 5433. Es importante evitar el uso del mismo puerto que el nodo de lectura y escritura del clúster de base de datos PostgreSQL. Si desea que las aplicaciones accedan solo a la réplica de solo lectura del clúster de base de datos de PostgreSQL, apúntelas al puerto 5433. El servicio final se usa normalmente para las copias de seguridad de datos, pero también puede funcionar como un nodo de solo lectura.Obtenga los detalles del servicio mediante el comando
kubectl get.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 el servicio de equilibrador de carga con los siguientes archivos YAML mediante el comando
kubectl apply.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" EOFObtenga los detalles del servicio mediante el comando
kubectl describe.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
Validación de puntos de conexión públicos de PostgreSQL
En esta sección, validará que Azure Load Balancer está configurado correctamente mediante la dirección IP estática que creó anteriormente y enrutar conexiones a las réplicas principales de lectura y escritura y de solo lectura y usar la CLI de psql para conectarse a ambas.
Recuerde que el punto de conexión principal de lectura y escritura se asigna al puerto TCP 5432 y los puntos de conexión de réplica de solo lectura se asignan al puerto 5433 para permitir que se use el mismo nombre DNS de PostgreSQL para lectores y escritores.
Nota:
Necesita el valor de la contraseña de usuario de la aplicación para la autenticación básica de PostgreSQL que se generó anteriormente y se almacenó en la variable de entorno $PG_DATABASE_APPUSER_SECRET.
Valide los puntos de conexión públicos de PostgreSQL mediante los siguientes comandos
psql: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();"Salida de ejemplo
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();"Salida de ejemplo
# Example output pg_is_in_recovery ------------------- t (1 row)Cuando se conecta correctamente al punto de conexión de lectura y escritura principal, la función PostgreSQL devuelve
fpara false, lo que indica que la conexión actual se puede escribir.Cuando se conecta a una réplica, la función devuelve
tpara true, lo que indica que la base de datos está en recuperación y de solo lectura.
Simular una conmutación por error no planeada
En esta sección, desencadenará un error repentino eliminando el pod que ejecuta la principal, lo que simula un bloqueo repentino o una pérdida de conectividad de red al nodo que hospeda la base de datos principal de PostgreSQL.
Compruebe el estado de las instancias de pod en ejecución mediante el comando siguiente:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACESalida de ejemplo
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-vmss000002Elimine el pod principal mediante el comando
kubectl delete.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_NAMESPACECompruebe que la instancia de pod
pg-primary-cnpg-sryti1qf-2es ahora la principal mediante el siguiente comando:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACESalida de ejemplo
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-vmss000002Restablezca la instancia de pod
pg-primary-cnpg-sryti1qf-1como principal mediante el comando siguiente:kubectl cnpg promote $PG_PRIMARY_CLUSTER_NAME 1 --namespace $PG_NAMESPACECompruebe que las instancias de pod se han devuelto a su estado original antes de la prueba de conmutación por error no planeada mediante el siguiente comando:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACESalida de ejemplo
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
Limpieza de recursos
Una vez que haya terminado de revisar la implementación, elimine todos los recursos que creó en esta guía mediante el comando
az group delete.az group delete --resource-group $RESOURCE_GROUP_NAME --no-wait --yes
Pasos siguientes
En esta guía paso a paso, ha aprendido lo siguiente:
- Use la CLI de Azure para crear un clúster de AKS de varias zonas.
- Implemente un clúster y una base de datos de PostgreSQL de alta disponibilidad mediante el operador CNPG.
- Configure la supervisión de PostgreSQL mediante Prometheus y Grafana.
- Implemente un conjunto de datos de ejemplo en la base de datos PostgreSQL.
- Simulación de una interrupción del clúster y conmutación por error de réplica de PostgreSQL.
- Realice una copia de seguridad y restauración de la base de datos PostgreSQL.
Para más información sobre cómo puede usar AKS para las cargas de trabajo, consulte ¿Qué es Azure Kubernetes Service (AKS)? Para más información sobre Azure Database for PostgreSQL, consulte ¿Qué es Azure Database for PostgreSQL?
Colaboradores
Microsoft mantiene este artículo. Originalmente lo escribieron los siguientes colaboradores:
- Ken Kilty | Responsable principal de gestión técnica de programas
- 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.