この記事では、新しくデプロイされた PostgreSQL データベースに対して、さまざまなテストと検証の手順を実行します。
- PostgreSQL をまだデプロイしていない場合は、「Azure CLI を使用して AKS に高可用性 PostgreSQL データベースをデプロイ する」の手順に従ってセットアップを行い、この記事に戻ることができます。
重要
オープンソース ソフトウェアは、AKS のドキュメントとサンプル全体で説明されています。 デプロイするソフトウェアは、AKS サービス レベル アグリーメント、限定保証、Azure サポートから除外されます。 AKS と共にオープンソース テクノロジを使用する場合は、それぞれのコミュニティとプロジェクト保守担当者から受けられるサポート オプションを調べ、計画を策定してください。
たとえば、Ray の GitHub リポジトリでは、応答時間、目的、サポート レベルが異なる複数のプラットフォームについて説明しています。
Microsoft は、AKS 上に展開するオープンソース パッケージを構築する責任を負います。 その責任には、ビルド、スキャン、署名、検証、修正プログラム プロセスの完全な所有権と、コンテナー イメージ内のバイナリの制御権が伴います。 詳細については、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: -
kubectl apply
コマンドで YAML ファイルを使用して、AKS ワークロード ID 統合を使用するオンデマンド バックアップを Azure Storage にデプロイします。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 ファイルを使用して" 毎時 15 分に" スケジュールされたバックアップを構成します。
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 Storage に格納されているバックアップ ファイルを表示します。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 オペレーターを使用して以前に作成したオンデマンド バックアップを、ブートストラップ クラスター CRD を使用して新しいインスタンスに復元します。 わかりやすくするために、1 つのインスタンス クラスターを使用します。 AKS ワークロード ID (CNPG inheritFromAzureAD 経由) は、バックアップ ファイルにアクセスし、リカバリ クラスター名を使用してリカバリ クラスターに固有の新しい Kubernetes サービス アカウントを生成することを忘れないでください。
また、2 つ目のフェデレーション資格情報を作成して、新しいリカバリ クラスター サービス アカウントを、Blob Storage 上のバックアップ ファイルへの "ストレージ BLOB データ共同作成者" アクセス権を持つ既存の UAMI にマップします。
az identity federated-credential create
コマンドを使用して、2 番目のフェデレーション ID 資格情報を作成します。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
kubectl apply
コマンドを使用して、クラスター CRD を使用してオンデマンド バックアップを復元します。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
コマンドを使用して、フェデレーション ID 資格情報を作成します。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 クラスターを公開する
このセクションでは、IP ソース制限のある PostgreSQL 読み取り/書き込みおよび読み取り専用エンドポイントをクライアント ワークステーションのパブリック IP にパブリックに公開するために必要なインフラストラクチャを構成します。
クラスター IP サービスから次のエンドポイントも取得します。
- で終わる "1 個" のプライマリ読み取り/書き込みエンドポイント。
*-rw
- で終わる "0 から N 個" (レプリカの数に応じる) の読み取り専用エンドポイント。
*-ro
- で終わる "1 個" のレプリケーション エンドポイント。
*-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
注
3 つのサービスがあり、
namespace/cluster-name-ro
は、ポート 5433 にマップされ、namespace/cluster-name-rw
とnamespace/cluster-name-r
はポート 5433 にマップされます。 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
を表す を返し、現在の接続が書き込み可能であることを示します。レプリカに接続すると、この関数は
t
を表す を返します。これは、データベースが復旧中で、読み取り専用であることを示します。
計画外のフェールオーバーをシミュレートする
このセクションでは、プライマリを実行しているポッドを削除して、突然の障害をトリガーします。これにより、PostgreSQL プライマリをホストしているノードへの突然のクラッシュまたはネットワーク接続の損失がシミュレートされます。
次のコマンドを使用して、実行中のポッド インスタンスの状態を確認します。
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
コマンドを使用してプライマリ ポッドを削除します。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
ポッド インスタンスがプライマリになっていることを確認します。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
ポッド インスタンスをプライマリとしてリセットします。kubectl cnpg promote $PG_PRIMARY_CLUSTER_NAME 1 --namespace $PG_NAMESPACE
次のコマンドを使用して、計画外のフェールオーバー テストの前にポッド インスタンスが元の状態に戻ったことを確認します。
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) とは」を参照してください。Azure Database for PostgreSQL の詳細については、「Azure Database for PostgreSQL とは」を参照してください。
貢献者達
Microsoft では、この記事を保持しています。 当初の寄稿者は次のとおりです。
- Ken Kilty | プリンシパル TPM
- Russell de Pina | プリンシパル TPM
- Adrian Joian | シニア カスタマー エンジニア
- Jenny Hayes | シニア コンテンツ開発者
- Carol Smith | シニア コンテンツ開発者
- Erin Schaffer |コンテンツ開発者 2
- Adam Sharif | カスタマー エンジニア 2
Azure Kubernetes Service