在本文中,您將針對新部署的 PostgreSQL 資料庫執行各種測試和驗證步驟。
- 如果您尚未部署 PostgreSQL,請依照使用 Azure CLI 在 AKS 上部署高可用性 PostgreSQL 資料庫 中的步驟進行設定,然後返回本文。
這很重要
整個 AKS 文件和範例都會提及開放原始碼的軟體。 您部署的軟體會從 AKS 服務等級協定、有限保固和 Azure 支援 中排除。 當您搭配 AKS 使用開放原始碼技術時,請參閱個別社群和專案維護人員所提供的支援選項,以開發計畫。
例如, Ray GitHub 存放庫 描述數個因回應時間、用途和支援層級而異的平臺。
Microsoft負責建置我們在 AKS 上部署的開放原始碼套件。 該責任包括擁有組建、掃描、簽署、驗證和 Hotfix 程式的完整擁有權,以及控制容器映像中的二進位檔。 如需詳細資訊,請參閱 AKS 弱點管理和 AKS 支援涵蓋範圍。
檢查已部署的 PostgreSQL 叢集
使用 kubectl get
命令來擷取 AKS 節點詳細資料,以驗證 PostgreSQL 是否分散到多個可用性區域。
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"}'
您的輸出應該類似下列範例輸出,並顯示每個節點的可用性區域:
{
"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"
}
連線至 PostgreSQL 並建立範例資料集
在本節中,您會建立資料表,並將一些資料插入您稍早部署之 CNPG 叢集 CRD 中建立的應用程式資料庫中。 您可以使用此資料來驗證 PostgreSQL 叢集的備份和還原作業。
使用下列命令,建立資料表並將資料插入應用程式資料庫中:
kubectl cnpg psql $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE
# Run the following PSQL commands to create a small dataset # postgres=# 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; # Type \q to exit psql
您的輸出應該類似下列範例輸出:
CREATE TABLE INSERT 0 1 INSERT 0 1 INSERT 0 1 count ------- 3 (1 row)
連線到 PostgreSQL 唯讀複本
連線到 PostgreSQL 唯讀複本,並使用下列命令驗證範例資料集:
kubectl cnpg psql --replica $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE
#postgres=# SELECT pg_is_in_recovery();
範例輸出
# pg_is_in_recovery #------------------- # t #(1 row)
#postgres=# SELECT COUNT(*) FROM datasample;
範例輸出
# count #------- # 3 #(1 row) # Type \q to exit psql
使用 Barman 設定隨選和排程的 PostgreSQL 備份
使用下列命令驗證 PostgreSQL 叢集是否可以存取 CNPG 叢集 CRD 中指定的 Azure 儲存體帳戶,以及
Working WAL archiving
是否報告為OK
:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE
範例輸出
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: -
使用 YAML 檔案搭配
kubectl apply
命令,將隨選備份部署至使用 AKS 工作負載身分識別整合的 Azure 儲存體。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 EOF
使用
kubectl describe
命令驗證隨選備份的狀態。kubectl describe backup $BACKUP_ONDEMAND_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE
範例輸出
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 completed
使用下列命令驗證叢集具有第一個可復原性點:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE
範例輸出
Continuous Backup status First Point of Recoverability: 2024-06-05T13:47:18Z Working WAL archiving: OK
使用 YAML 檔案搭配 命令,設定
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 EOF
使用
kubectl describe
命令驗證排程備份的狀態。kubectl describe scheduledbackup $BACKUP_SCHEDULED_NAME \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE
使用
az storage blob list
命令,檢視主要叢集儲存在 Azure Blob 儲存體上的備份檔案。az storage blob list \ --account-name $PG_PRIMARY_STORAGE_ACCOUNT_NAME \ --container-name backups \ --query "[*].name" \ --only-show-errors
您的輸出應該類似下列範例輸出,驗證備份成功:
[ "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" ]
將隨選備份還原至新的 PostgreSQL 叢集
在本節中,您會使用 CNPG 運算子將稍早使用 CNPG 運算子建立的隨選備份還原到使用啟動程序叢集 CRD 的新執行個體。 單一執行個體叢集是為了簡單起見而使用。 請記住,AKS 工作負載身分識別 (透過 CNPG inheritFromAzureAD) 會存取備份檔案,並使用復原叢集名稱來產生復原叢集專屬的新 Kubernetes 服務帳戶。
您也會建立第二個同盟認證,將新的復原叢集服務帳戶對應至具有 Blob 儲存體上備份檔案之「儲存體 Blob 資料參與者」存取權的現有 UAMI。
使用
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://AzureADTokenExchange
使用叢集 CRD 搭配
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 EOF
連接到已復原的執行個體,然後使用下列命令,驗證在建立完整備份的原始叢集上建立的資料集是否存在:
kubectl cnpg psql $PG_PRIMARY_CLUSTER_NAME_RECOVERED --namespace $PG_NAMESPACE
postgres=# SELECT COUNT(*) FROM datasample;
範例輸出
# count #------- # 3 #(1 row) # Type \q to exit psql
使用下列命令刪除復原的叢集:
kubectl cnpg destroy $PG_PRIMARY_CLUSTER_NAME_RECOVERED 1 \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE
使用
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
使用公用負載平衡器公開 PostgreSQL 叢集
在本節中,您會設定必要的基礎結構,以公開 PostgreSQL 讀寫和唯讀端點,並將 IP 來源限制公開至用戶端工作站的公用 IP 位址。
您也會從叢集 IP 服務擷取下列端點:
- 以 結尾的
*-rw
主要讀寫端點。 -
零到 N (視複本數目而定) 以
*-ro
結尾的唯讀端點。 - 以 結尾的
*-r
複寫端點。
使用
kubectl get
命令取得叢集 IP 服務詳細資料。kubectl get services \ --context $AKS_PRIMARY_CLUSTER_NAME \ --namespace $PG_NAMESPACE \ -l cnpg.io/cluster=$PG_PRIMARY_CLUSTER_NAME
範例輸出
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 3h57m
備註
有三個服務:
namespace/cluster-name-ro
對應至連接埠 5433、namespace/cluster-name-rw
以及對應至連結埠 5433 的namespace/cluster-name-r
。 請務必避免使用與 PostgreSQL 資料庫叢集讀取/寫入節點相同的連接埠。 如果您想要讓應用程式只存取 PostgreSQL 資料庫叢集的唯讀複本,請將它們導向連接埠 5433。 最終服務通常用於資料備份,但也可作為唯讀節點。使用
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_SERVICE
使用
kubectl apply
命令,以下列 YAML 檔案設定負載平衡器服務。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" EOF
使用
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
驗證公用 PostgreSQL 端點
在本節中,您會使用您稍早建立的靜態 IP,以及將連線路由傳送至主要讀寫和唯讀複本,並使用 psql CLI 連線至這兩者,來驗證 Azure Load Balancer 是否已正確設定。
請記住,主要讀寫端點會對應至 TCP 連接埠 5432,而唯讀複本端點會對應至連接埠 5433,以允許讀取器和寫入器使用相同的 PostgreSQL DNS 名稱。
備註
您需要稍早產生並儲存在 $PG_DATABASE_APPUSER_SECRET
環境變數中 PostgreSQL 基本身分驗證的應用程式使用者密碼值。
使用下列
psql
命令來驗證公用 PostgreSQL 端點: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();"
範例輸出
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();"
範例輸出
# Example output pg_is_in_recovery ------------------- t (1 row)
成功連線到主要讀寫端點時,PostgreSQL 函式會傳回
f
(如果為 false),指出目前的連線是可寫入的。連接到複本時,函式會針對
t
傳回 ,表示資料庫處於復原狀態且唯讀。
模擬非計劃性容錯移轉
在本節中,您會刪除執行主要複本的 Pod 來觸發突然失敗,以模擬裝載 PostgreSQL 主要節點的突然當機或網路連線中斷。
使用下列命令檢查執行中 Pod 執行個體的狀態:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE
範例輸出
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
使用
kubectl delete
命令刪除主要 Pod。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_NAMESPACE
使用下列命令驗證
pg-primary-cnpg-sryti1qf-2
Pod 執行個體現在是主要執行個體:kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE
範例輸出
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-vmss000002
使用下列命令,將
pg-primary-cnpg-sryti1qf-1
Pod 執行個體重設為主要執行個體:kubectl cnpg promote $PG_PRIMARY_CLUSTER_NAME 1 --namespace $PG_NAMESPACE
使用下列命令,驗證 Pod 執行個體在非計劃性容錯移轉測試之前已回到其原始狀態:
kubectl cnpg status $PG_PRIMARY_CLUSTER_NAME --namespace $PG_NAMESPACE
範例輸出
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
清理資源
完成部署檢閱之後,請使用
az group delete
命令,刪除本指南中建立的所有資源。az group delete --resource-group $RESOURCE_GROUP_NAME --no-wait --yes
後續步驟
在此操作指南中,您已了解如何:
- 使用 Azure CLI 建立多區域 AKS 叢集。
- 使用 CNPG 運算子 部署高可用性 PostgreSQL 叢集和資料庫。
- 使用 Prometheus 和 Grafana 設定 PostgreSQL 的監視。
- 將範例資料集部署至 PostgreSQL 資料庫。
- 模擬叢集中斷和 PostgreSQL 複本容錯移轉。
- 執行 PostgreSQL 資料庫的備份和還原。
若要深入瞭解如何為您的工作負載運用 AKS,請參閱 什麼是 Azure Kubernetes Service (AKS)? 若要深入瞭解適用於 PostgreSQL 的 Azure 資料庫,請參閱什麼是適用於 PostgreSQL 的 Azure 資料庫?
貢獻者們
本文由 Microsoft 維護。 原始撰寫此內容的貢獻者如下:
- Ken Kilty | 首席 TPM
- Russell de Pina | 首席 TPM
- Adrian Joian |資深客戶工程師
- Jenny Hayes | 資深內容開發人員
- Carol Smith | 資深內容開發人員
- Erin Schaffer |內容開發人員 2
- Adam Sharif |客戶工程師 2