PostgreSQL は、信頼性とデータの整合性で有名なオープンソースのオブジェクト リレーショナル データベースです。ACID に準拠し、外部キー、結合、ビュー、トリガー、ストアド プロシージャをサポートしています。
このドキュメントは、高可用性 PostgreSQL トポロジを Google Kubernetes Engine にデプロイすることに関心があるデータベース管理者、クラウド アーキテクト、運用の担当者を対象としています。
目標
このチュートリアルの学習内容は次のとおりです。- Terraform を使用して GKE のリージョン クラスタを作成する。
- 高可用性 PostgreSQL データベースをデプロイする。
- PostgreSQL アプリケーションのモニタリングを設定する。
- PostgreSQL データベースと GKE クラスタのアップグレードを実行する。
- クラスタの中断と PostgreSQL レプリカのフェイルオーバーをシミュレートする。
- PostgreSQL データベースのバックアップと復元を行う。
アーキテクチャ
このセクションでは、このチュートリアルで構築するソリューションのアーキテクチャについて説明します。
2 つの GKE クラスタを異なるリージョン(プライマリ クラスタとバックアップ クラスタ)にプロビジョニングします。このチュートリアルでは、プライマリ クラスタは us-central1
リージョンにあり、バックアップ クラスタは us-west1
リージョンにあります。このアーキテクチャでは、このチュートリアルで後述するように、高可用性 PostgreSQL データベースをプロビジョニングし、障害復旧をテストできます。
ソースクラスタの場合は、Helm チャート(bitnami/postgresql-ha
)を使用して、高可用性 PostgreSQL クラスタを設定します。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
プロジェクトを設定する
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Google Kubernetes Engine, Backup for GKE, Artifact Registry, Compute Engine, and IAM APIs.
ロールを設定する
-
Grant roles to your user account. Run the following command once for each of the following IAM roles:
role/storage.objectViewer, role/logging.logWriter, role/artifactregistry.Admin, roles/container.clusterAdmin, role/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin
$ gcloud projects add-iam-policy-binding PROJECT_ID --member="USER_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
- Replace
環境を設定する
このチュートリアルでは、Cloud Shell を使用して Google Cloud でホストされるリソースを管理します。Cloud Shell には、Docker、kubectl
、gcloud CLI、Helm、Terraform を含む、このチュートリアルに必要なソフトウェアがプリインストールされています。
Cloud Shell を使用して環境を設定する方法は次のとおりです。
Google Cloud コンソールで「Cloud Shell をアクティブにする」アイコン をクリックして、Google Cloud コンソールから Cloud Shell セッションを起動します。これにより、Google Cloud コンソールの下部ペインでセッションが起動します。
環境変数を設定します。
export PROJECT_ID=PROJECT_ID export SOURCE_CLUSTER=cluster-db1 export REGION=us-central1
次の値を置き換えます。
- PROJECT_ID: Google Cloud のプロジェクト ID。
デフォルトの環境変数を設定します。
gcloud config set project PROJECT_ID
コード リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
作業ディレクトリを変更します。
cd kubernetes-engine-samples/databases/gke-stateful-postgres
クラスタ インフラストラクチャを作成する
このセクションでは、Terraform スクリプトを実行して、カスタム Virtual Private Cloud(VPC)、PostgreSQL イメージを保存する Artifact Registry リポジトリ、および 2 つの GKE リージョン クラスタを作成します。1 つ目のクラスタは us-central1
にデプロイされ、バックアップ用の 2 つ目のクラスタは us-west1
にデプロイされます。
クラスタの作成手順は次のとおりです。
Autopilot
Cloud Shell で、次のコマンドを実行します。
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply -var project_id=$PROJECT_ID
プロンプトが表示されたら、「yes
」と入力します。
Terraform の構成を理解する
Terraform 構成ファイルは、次のリソースを作成して、インフラストラクチャをデプロイします。
- Docker イメージを保存するための Artifact Registry リポジトリを作成します。
- VM のネットワーク インターフェース用に VPC ネットワークとサブネットを作成します。
プライマリ GKE クラスタを作成します。
Terraform は
us-central1
リージョンに限定公開クラスタを作成し、Backup for GKE で障害復旧を、Managed Service for Prometheus でクラスタのモニタリングを有効にします。Managed Service for Prometheus は、GKE バージョン 1.25 以降を実行している Autopilot クラスタでのみサポートされます。
障害復旧のために
us-west1
リージョンにバックアップ クラスタを作成します。
Standard
Cloud Shell で、次のコマンドを実行します。
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply -var project_id=$PROJECT_ID
プロンプトが表示されたら、「yes
」と入力します。
Terraform の構成を理解する
Terraform 構成ファイルは、次のリソースを作成して、インフラストラクチャをデプロイします。
- Docker イメージを保存するための Artifact Registry リポジトリを作成します。
- VM のネットワーク インターフェース用に VPC ネットワークとサブネットを作成します。
プライマリ GKE クラスタを作成します。
Terraform は
us-central1
リージョンに限定公開クラスタを作成し、Backup for GKE で障害復旧を、Managed Service for Prometheus でクラスタのモニタリングを有効にします。障害復旧のために
us-west1
リージョンにバックアップ クラスタを作成します。
PostgreSQL をクラスタにデプロイする
このセクションでは、Helm チャートを使用して、PostgreSQL データベース インスタンスをデプロイして、GKE で実行します。
PostgreSQL をインストールする
クラスタに PostgreSQL をインストールするには、次の手順で操作します。
Docker アクセスを構成します。
gcloud auth configure-docker us-docker.pkg.dev
必要な PostgreSQL Docker イメージを Artifact Registry に入力します。
./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r0 ./scripts/gcr.sh bitnami/postgres-exporter 0.11.1-debian-11-r27 ./scripts/gcr.sh bitnami/pgpool 4.3.3-debian-11-r28
スクリプトにより、次の Bitnami イメージが Helm 用の Artifact Registry に push され、インストールされます。
postgresql-repmgr
: この PostgreSQL クラスタ ソリューションには、PostgreSQL クラスタでのレプリケーションとフェイルオーバーを管理するためのオープンソース ツールである PostgreSQL レプリケーション マネージャー(repmgr)が含まれています。postgres-exporter
: PostgreSQL Exporter は、Prometheus の使用に必要な PostgreSQL 指標を収集します。pgpool
: Pgpool-II は PostgreSQL プロキシです。接続プーリングとロード バランシングを提供します。
正しいイメージがリポジトリに保存されていることを確認します。
gcloud artifacts docker images list us-docker.pkg.dev/$PROJECT_ID/main \ --format="flattened(package)"
出力は次のようになります。
--- image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/pgpool --- image: us-docker.pkg.dev/[PROJECT_ID]/main/bitnami/postgres-exporter --- image: us-docker.pkg.dev/h[PROJECT_ID]/main/bitnami/postgresql-repmgr
プライマリ クラスタへの
kubectl
コマンドライン アクセスを構成します。gcloud container clusters get-credentials $SOURCE_CLUSTER \ --region=$REGION --project=$PROJECT_ID
Namespace を作成します。
export NAMESPACE=postgresql kubectl create namespace $NAMESPACE
Autopilot クラスタにデプロイする場合は、3 つのゾーンにわたるノード プロビジョニングを構成します。Standard クラスタにデプロイする場合は、この手順をスキップしてください。
デフォルトでは、Autopilot は 2 つのゾーンにのみリソースをプロビジョニングします。
prepareforha.yaml
で定義された Deployment により、Autopilot は次の値を設定して、クラスタ内の 3 つのゾーンにノードをプロビジョニングします。replicas:3
requiredDuringSchedulingIgnoredDuringExecution
とtopologyKey: "topology.kubernetes.io/zone"
を指定したpodAntiAffinity
kubectl -n $NAMESPACE apply -f scripts/prepareforha.yaml
Helm の依存関係を更新します。
cd helm/postgresql-bootstrap helm dependency update
Helm によってインストールされるチャートを調べて確認します。
helm -n postgresql template postgresql . \ --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
Helm チャートをインストールします。
helm -n postgresql upgrade --install postgresql . \ --set global.imageRegistry="us-docker.pkg.dev/$PROJECT_ID/main"
出力は次のようになります。
NAMESPACE: postgresql STATUS: deployed REVISION: 1 TEST SUITE: None
PostgreSQL のレプリカが動作していることを確認します。
kubectl get all -n $NAMESPACE
出力は次のようになります。
NAME READY STATUS RESTARTS AGE pod/postgresql-postgresql-bootstrap-pgpool-75664444cb-dkl24 1/1 Running 0 8m39s pod/postgresql-postgresql-ha-pgpool-6d86bf9b58-ff2bg 1/1 Running 0 8m39s pod/postgresql-postgresql-ha-postgresql-0 2/2 Running 0 8m39s pod/postgresql-postgresql-ha-postgresql-1 2/2 Running 0 8m39s pod/postgresql-postgresql-ha-postgresql-2 2/2 Running 0 8m38s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/postgresql-postgresql-ha-pgpool ClusterIP 192.168.99.236 <none> 5432/TCP 8m39s service/postgresql-postgresql-ha-postgresql ClusterIP 192.168.90.20 <none> 5432/TCP 8m39s service/postgresql-postgresql-ha-postgresql-headless ClusterIP None <none> 5432/TCP 8m39s service/postgresql-postgresql-ha-postgresql-metrics ClusterIP 192.168.127.198 <none> 9187/TCP 8m39s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/postgresql-postgresql-bootstrap-pgpool 1/1 1 1 8m39s deployment.apps/postgresql-postgresql-ha-pgpool 1/1 1 1 8m39s NAME DESIRED CURRENT READY AGE replicaset.apps/postgresql-postgresql-bootstrap-pgpool-75664444cb 1 1 1 8m39s replicaset.apps/postgresql-postgresql-ha-pgpool-6d86bf9b58 1 1 1 8m39s NAME READY AGE statefulset.apps/postgresql-postgresql-ha-postgresql 3/3 8m39s
テスト データセットを作成する
このセクションでは、データベースとサンプル値を含むテーブルを作成します。データベースは、このチュートリアルの後半でテストするフェイルオーバー プロセスのテスト データセットとして機能します。
PostgreSQL インスタンスに接続します。
cd ../../ ./scripts/launch-client.sh
出力は次のようになります。
Launching Pod pg-client in the namespace postgresql ... pod/pg-client created waiting for the Pod to be ready Copying script files to the target Pod pg-client ... Pod: pg-client is healthy
シェル セッションを開始します。
kubectl exec -it pg-client -n postgresql -- /bin/bash
データベースとテーブルを作成し、いくつかのテスト行を挿入します。
psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/generate-db.sql
各テーブルの行数を確認します。
psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql
出力は次のようになります。
select COUNT(*) from tb01; count -------- 300000 (1 row) select COUNT(*) from tb02; count -------- 300000 (1 row)
テストデータを生成します。
export DB=postgres pgbench -i -h $HOST_PGPOOL -U postgres $DB -s 50
出力は次のようになります。
dropping old tables... creating tables... generating data (client-side)... 5000000 of 5000000 tuples (100%) done (elapsed 29.85 s, remaining 0.00 s) vacuuming... creating primary keys... done in 36.86 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 31.10 s, vacuum 1.88 s, primary keys 3.86 s).
postgres クライアント Pod を終了します。
exit
PostgreSQL をモニタリングする
このセクションでは、PostgreSQL インスタンス用の指標を表示して、アラートを設定します。Google Cloud Managed Service for Prometheus を使用して、モニタリングとアラートを実行します。
指標を表示する
PostgreSQL の Deployment には、postgresql-exporter
サイドカー コンテナが含まれています。このコンテナは /metrics
エンドポイントを公開します。Google Cloud Managed Service for Prometheus は、このエンドポイントで PostgreSQL Pod をモニタリングするように構成されています。これらの指標は、Google Cloud コンソールのダッシュボードで確認できます。
Google Cloud コンソールには、ダッシュボードの構成を作成して保存する方法がいくつか用意されています。
- 作成とエクスポート: Google Cloud コンソールでダッシュボードを直接作成してから、コード リポジトリにそれらをエクスポートして保存できます。それには、ダッシュボードのツールバーで JSON エディタを開き、ダッシュボードの JSON ファイルをダウンロードします。
- ストレージとインポート: JSON ファイルからダッシュボードをインポートできます。それには、[+ ダッシュボードの作成] をクリックし、JSON エディタのメニューを使用して、ダッシュボードの JSON コンテンツをアップロードします。
PostgreSQL アプリケーションと GKE クラスタからのデータを可視化する手順は次のとおりです。
次のダッシュボードを作成します。
cd monitoring gcloud monitoring dashboards create \ --config-from-file=dashboard/postgresql-overview.json \ --project=$PROJECT_ID gcloud monitoring dashboards create \ --config-from-file dashboard/gke-postgresql.json \ --project $PROJECT_ID
Google Cloud コンソールで、Cloud Monitoring ダッシュボードに移動します。Cloud Monitoring ダッシュボードに移動
ダッシュボードのリストから [カスタム] を選択します。次のダッシュボードが表示されます。
- PostgreSQL の概要: PostgreSQL アプリケーションの指標(データベースの稼働時間、データベースのサイズ、トランザクションのレイテンシなど)を表示します。
- GKE PostgreSQL クラスタ: PostgreSQL が実行されている GKE クラスタの指標(CPU 使用率、メモリ使用量、ボリューム使用率など)を表示します。
各リンクをクリックして、生成されたダッシュボードを調べます。
アラートを設定する
アラートを使用すると、アプリケーションの問題をタイムリーに認識できるため、問題をすばやく解決できます。アラート ポリシーを作成して、アラートを受け取る状況と通知方法を指定できます。通知チャンネルを作成して、アラートの送信先を選択することもできます。
このセクションでは、Terraform を使用して次の例のアラートを構成します。
db_max_transaction
: トランザクションの最大ラグを秒単位でモニタリングします。値が 10 より大きい場合は、アラートがトリガーされます。db_node_up
: データベース Pod のステータスをモニタリングします。0 は、Pod がダウンしていることを意味し、アラートがトリガーされます。
アラートを設定する手順は次のとおりです。
Terraform を使用してアラートを構成します。
EMAIL=YOUR_EMAIL cd alerting/terraform terraform init terraform plan -var project_id=$PROJECT_ID -var email_address=$EMAIL terraform apply -var project_id=$PROJECT_ID -var email_address=$EMAIL
次の値を置き換えます。
- YOUR_EMAIL: メールアドレス。
出力は次のようになります。
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
クライアント Pod に接続します。
cd ../../../ kubectl exec -it --namespace postgresql pg-client -- /bin/bash
負荷テストを生成して、
db_max_transaction
アラートをテストします。pgbench -i -h $HOST_PGPOOL -U postgres -s 200 postgres
出力は次のようになります。
dropping old tables... creating tables... generating data (client-side)... 20000000 of 20000000 tuples (100%) done (elapsed 163.22 s, remaining 0.00 s) vacuuming... creating primary keys... done in 191.30 s (drop tables 0.14 s, create tables 0.01 s, client-side generate 165.62 s, vacuum 4.52 s, primary keys 21.00 s).
アラートがトリガーされると、件名が「[ALERT] Max Lag of transaction」で始まるメールが YOUR_EMAIL に送信されます。
Google Cloud コンソールで、[アラート ポリシー] ページに移動します。
リスト内のポリシーから
db_max_transaction
を選択します。チャートから、Prometheus 指標pg_stat_activity_max_tx_duration/gauge
のしきい値の 10 を超える負荷テストの急増が確認できます。postgres クライアント Pod を終了します。
exit
PostgreSQL と GKE のアップグレードを管理する
PostgreSQL と Kubernetes の両方のバージョンの更新は定期的なスケジュールでリリースされます。運用に関するベスト プラクティスに沿って、ソフトウェア環境を定期的に更新します。デフォルトでは、GKE ではクラスタとノードプールのアップグレードが自動的に管理されます。
PostgreSQL をアップグレードする
このセクションでは、PostgreSQL のバージョン アップグレードを行う方法について説明します。このチュートリアルでは、どの時点でもすべての Pod がダウンすることがないように、Pod のアップグレードにローリング アップデート戦略を使用します。
バージョン アップグレードの手順は次のとおりです。
更新されたバージョンの
postgresql-repmgr
イメージを Artifact Registry に push します。新しいバージョンを定義します(例:postgresql-repmgr 15.1.0-debian-11-r1
)。NEW_IMAGE=us-docker.pkg.dev/$PROJECT_ID/main/bitnami/postgresql-repmgr:15.1.0-debian-11-r1 ./scripts/gcr.sh bitnami/postgresql-repmgr 15.1.0-debian-11-r1
kubectl
を使用してローリング アップデートをトリガーします。kubectl set image statefulset -n postgresql postgresql-postgresql-ha-postgresql postgresql=$NEW_IMAGE kubectl rollout restart statefulsets -n postgresql postgresql-postgresql-ha-postgresql kubectl rollout status statefulset -n postgresql postgresql-postgresql-ha-postgresql
StatefulSet により、ローリング アップデートの完了が確認できます(序数の大きいレプリカから小さいものの順)。
出力は次のようになります。
Waiting for 1 pods to be ready... waiting for statefulset rolling update to complete 1 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49... Waiting for 1 pods to be ready... Waiting for 1 pods to be ready... waiting for statefulset rolling update to complete 2 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49... Waiting for 1 pods to be ready... Waiting for 1 pods to be ready... statefulset rolling update complete 3 pods at revision postgresql-postgresql-ha-postgresql-5c566ccf49...
Standard クラスタで GKE のアップグレードを計画する
このセクションは、Standard クラスタを実行している場合に適用されます。ステートフル サービスの実行時に、次のように予防的措置を講じて、リスクを軽減してクラスタのアップグレードをよりスムーズに行うための構成を設定することができます。
クラスタのアップグレードに関する GKE のベスト プラクティスに沿って対応します。適切なアップグレード戦略を選択して、メンテナンスの時間枠の期間内にアップグレードが確実に行われるようにします。
- コストの最適化が重要であり、ワークロードが 60 分未満で正常なシャットダウンを許容できる場合は、サージ アップグレードを選択します。
- ワークロードの中断に対する許容度が低く、リソース使用量の増加によって一時的な費用の増加が許容される場合は、Blue/Green アップグレードを選択します。
詳細については、ステートフル ワークロードを実行するクラスタをアップグレードするをご覧ください。
Recommender サービスを使用して、サービスの中断を避けるために、非推奨の分析情報と推奨事項を確認します。
メンテナンスの時間枠を使用すると、意図したタイミングでアップグレードが行われるようになります。メンテナンスの時間枠の前に、データベースのバックアップが成功していることを確認します。
アップグレードされたノードへのトラフィックを許可する前に、readiness プローブと liveness プローブを使用して、トラフィックの準備ができていることを確認します。
トラフィックの受信前に、レプリケーションが同期しているかどうかを評価するプローブを作成します。プローブの作成は、データベースの複雑さと規模に応じて、カスタム スクリプトを使って行えます。
Standard クラスタのアップグレード中にデータベースの可用性を確認する
このセクションは、Standard クラスタを実行している場合に適用されます。アップグレード中に PostgreSQL の可用性を検証するには、アップグレード処理中に PostgreSQL データベースに対してトラフィックを生成することが一般的な処理です。その後、pgbench
を使用して、データベースが完全に使用可能になったときに比べて、アップグレード中にデータベースがトラフィックのベースライン レベルを処理できることを確認します。
PostgreSQL インスタンスに接続します。
./scripts/launch-client.sh
出力は次のようになります。
Launching Pod pg-client in the namespace postgresql ... pod/pg-client created waiting for the Pod to be ready Copying script files to the target Pod pg-client ... Pod: pg-client is healthy
Cloud Shell で、クライアント Pod にシェルを追加します。
kubectl exec -it -n postgresql pg-client -- /bin/bash
pgbench を初期化します。
pgbench -i -h $HOST_PGPOOL -U postgres postgres
次のコマンドを使用して、アップグレードの時間枠内に PostgreSQL アプリケーションの高可用性が維持されていることを確認するベースラインの結果を取得します。ベースラインの結果を取得するには、30 秒間、マルチジョブ(スレッド)を介したマルチ接続でテストします。
pgbench -h $HOST_PGPOOL -U postgres postgres -c10 -j4 -T 30 -R 200
出力は次のようになります。
pgbench (14.5) starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 4 duration: 30 s number of transactions actually processed: 5980 latency average = 7.613 ms latency stddev = 2.898 ms rate limit schedule lag: avg 0.256 (max 36.613) ms initial connection time = 397.804 ms tps = 201.955497 (without initial connection time)
アップグレード中の可用性を確保するには、データベースに対してある程度の負荷を生成し、PostgreSQL アプリケーションがアップグレード中も一貫した応答率を確実に示すようにします。このテストを行うには、
pgbench
コマンドを使用して、データベースに対するある程度のトラフィックを生成します。次のコマンドは、200 TPS(1 秒あたりのトランザクション数)を目標に、2 秒ごとにリクエスト率を一覧表示しながら、1 時間pgbench
を実行します。pgbench -h $HOST_PGPOOL -U postgres postgres --client=10 --jobs=4 --rate=200 --time=3600 --progress=2 --select-only
各要素の意味は次のとおりです。
--client
: シミュレートされたクライアントの数、つまりデータベース セッションの同時実行数。--jobs
: pgbench 内のワーカー スレッド数。マルチ CPU マシンでは、複数のスレッドの使用が便利です。クライアントは、使用可能なスレッド間でできるだけ均等に分散されます。デフォルトは 1 です。--rate
: レートは 1 秒あたりのトランザクション数で指定します。--progress
: 進行状況レポートを 1 秒ごとに表示します。
出力は次のようになります。
pgbench (14.5) starting vacuum...end. progress: 5.0 s, 354.8 tps, lat 25.222 ms stddev 15.038 progress: 10.0 s, 393.8 tps, lat 25.396 ms stddev 16.459 progress: 15.0 s, 412.8 tps, lat 24.216 ms stddev 14.548 progress: 20.0 s, 405.0 tps, lat 24.656 ms stddev 14.066
Google Cloud コンソールで、Cloud Monitoring の PostgreSQL の概要ダッシュボードに戻ります。DB あたりの接続のグラフと Pod あたりの接続のグラフの急増に注意してください。
クライアント Pod を終了します。
exit
クライアント Pod を削除します。
kubectl delete pod -n postgresql pg-client
PostgreSQL サービスの中断をシミュレートする
このセクションでは、レプリケーション マネージャー サービスを停止して、PostgreSQL レプリカの 1 つでのサービスの中断をシミュレートします。これにより、Pod がピアレプリカにトラフィックを送信できなくなり、liveness プローブも失敗します。
新しい Cloud Shell セッションを開き、プライマリ クラスタへの
kubectl
コマンドライン アクセスを構成します。gcloud container clusters get-credentials $SOURCE_CLUSTER \ --region=$REGION --project=$PROJECT_ID
Kubernetes で出力された PostgreSQL イベントを表示します。
kubectl get events -n postgresql --field-selector=involvedObject.name=postgresql-postgresql-ha-postgresql-0 --watch
以前の Cloud Shell セッションで、PostgreSQL
repmgr
を停止してサービス障害をシミュレートします。セッションをデータベース コンテナにアタッチします。
kubectl exec -it -n $NAMESPACE postgresql-postgresql-ha-postgresql-0 -c postgresql -- /bin/bash
repmgr
を使用してサービスを停止し、チェックポイントとdry-run
引数を削除します。export ENTRY='/opt/bitnami/scripts/postgresql-repmgr/entrypoint.sh' export RCONF='/opt/bitnami/repmgr/conf/repmgr.conf' $ENTRY repmgr -f $RCONF node service --action=stop --checkpoint
PostgreSQL コンテナ用に構成された liveness プローブが開始して 5 秒以内に失敗します。失敗回数がしきい値の 6 回に達するまで、10 秒ごとにこれが繰り返されます。failureThreshold
の値に達すると、コンテナが再起動されます。これらのパラメータを構成して、liveness プローブの許容範囲を下げて、Deployment の SLO 要件を調整できます。
イベント ストリームから、Pod の liveness プローブと readiness プローブが失敗し、コンテナを再起動する必要があるというメッセージが確認できます。出力は次のようになります。
0s Normal Killing pod/postgresql-postgresql-ha-postgresql-0 Container postgresql failed liveness probe, will be restarted
0s Warning Unhealthy pod/postgresql-postgresql-ha-postgresql-0 Readiness probe failed: psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused...
0s Normal Pulled pod/postgresql-postgresql-ha-postgresql-0 Container image "us-docker.pkg.dev/psch-gke-dev/main/bitnami/postgresql-repmgr:14.5.0-debian-11-r10" already present on machine
0s Normal Created pod/postgresql-postgresql-ha-postgresql-0 Created container postgresql
0s Normal Started pod/postgresql-postgresql-ha-postgresql-0 Started container postgresql
障害復旧に備える
サービス中断イベントの発生時に本番環境のワークロードの可用性を確保するには、障害復旧(DR)計画を準備する必要があります。DR 計画の詳細については、障害復旧計画ガイドをご覧ください。
Kubernetes の障害復旧は、次の 2 つのフェーズで実装できます。
- バックアップ。サービス中断イベントの発生前に、状態またはデータの特定の時点のスナップショットを作成します。
- 復旧。障害の発生後に、バックアップ コピーから状態またはデータを復元します。
GKE クラスタでワークロードをバックアップして復元するには、Backup for GKE を使用します。このサービスは、新規および既存のクラスタで有効にできます。これにより、クラスタで実行される Backup for GKE エージェントがデプロイされます。エージェントは、構成とボリュームのバックアップ データの取得と、復旧のオーケストレートを担当します。
バックアップと復元のスコープは、クラスタ全体、Namespace、アプリケーション(matchLabels
などのセレクタで定義)に設定できます。
PostgreSQL のバックアップと復元のシナリオの例
このセクションの例では、ProtectedApplication
カスタム リソースを使用して、アプリケーション スコープでバックアップと復元の操作を行う方法を紹介しています。
次の図は、ProtectedApplication のコンポーネント リソースを示しています。つまり、postgresql-ha
アプリケーションを表す StatefulSet と、同じラベル(app.kubernetes.io/name: postgresql-ha
)を使用する pgpool
の Deployment を示しています。
PostgreSQL ワークロードのバックアップと復元を準備する手順は次のとおりです。
環境変数を設定します。この例では、ProtectedApplication を使用して、PostgreSQL ワークロードとそのボリュームを移行元の GKE クラスタ(
us-central1
)から復元してから、異なるリージョン(us-west1
)の別の GKE クラスタに復元します。export SOURCE_CLUSTER=cluster-db1 export TARGET_CLUSTER=cluster-db2 export REGION=us-central1 export DR_REGION=us-west1 export NAME_PREFIX=g-db-protected-app export BACKUP_PLAN_NAME=$NAME_PREFIX-bkp-plan-01 export BACKUP_NAME=bkp-$BACKUP_PLAN_NAME export RESTORE_PLAN_NAME=$NAME_PREFIX-rest-plan-01 export RESTORE_NAME=rest-$RESTORE_PLAN_NAME
クラスタで Backup for GKE が有効になっていることを確認します。以前に行った Terraform 設定の一部として、すでに有効になっているはずです。
gcloud container clusters describe $SOURCE_CLUSTER \ --project=$PROJECT_ID \ --region=$REGION \ --format='value(addonsConfig.gkeBackupAgentConfig)'
Backup for GKE が有効になっている場合、コマンドの出力に
enabled=True
と表示されます。
バックアップ プランを設定して復元を実行する
Backup for GKE を使用すると、cron ジョブとしてバックアップ プランを作成できます。バックアップ プランには、ソースクラスタ、バックアップするワークロードの選択、このプランで生成したバックアップ アーティファクトが保存されているリージョンなどのバックアップ構成が含まれます。
バックアップと復元を行う手順は次のとおりです。
cluster-db1
で ProtectedApplication のステータスを確認します。kubectl get ProtectedApplication -A
出力は次のようになります。
NAMESPACE NAME READY TO BACKUP postgresql postgresql-ha true
ProtectedApplication のバックアップ プランを作成します。
export NAMESPACE=postgresql export PROTECTED_APP=$(kubectl get ProtectedApplication -n $NAMESPACE | grep -v 'NAME' | awk '{ print $1 }')
gcloud beta container backup-restore backup-plans create $BACKUP_PLAN_NAME \ --project=$PROJECT_ID \ --location=$DR_REGION \ --cluster=projects/$PROJECT_ID/locations/$REGION/clusters/$SOURCE_CLUSTER \ --selected-applications=$NAMESPACE/$PROTECTED_APP \ --include-secrets \ --include-volume-data \ --cron-schedule="0 3 * * *" \ --backup-retain-days=7 \ --backup-delete-lock-days=0
バックアップを手動で作成します。
gcloud beta container backup-restore backups create $BACKUP_NAME \ --project=$PROJECT_ID \ --location=$DR_REGION \ --backup-plan=$BACKUP_PLAN_NAME \ --wait-for-completion
復元プランを設定します。
gcloud beta container backup-restore restore-plans create $RESTORE_PLAN_NAME \ --project=$PROJECT_ID \ --location=$DR_REGION \ --backup-plan=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME \ --cluster=projects/$PROJECT_ID/locations/$DR_REGION/clusters/$TARGET_CLUSTER \ --cluster-resource-conflict-policy=use-existing-version \ --namespaced-resource-restore-mode=delete-and-restore \ --volume-data-restore-policy=restore-volume-data-from-backup \ --selected-applications=$NAMESPACE/$PROTECTED_APP \ --cluster-resource-scope-selected-group-kinds="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"
バックアップから復元します。
gcloud beta container backup-restore restores create $RESTORE_NAME \ --project=$PROJECT_ID \ --location=$DR_REGION \ --restore-plan=$RESTORE_PLAN_NAME \ --backup=projects/$PROJECT_ID/locations/$DR_REGION/backupPlans/$BACKUP_PLAN_NAME/backups/$BACKUP_NAME \ --wait-for-completion
クラスタが復元されていることを確認する
復元されたクラスタに、想定どおりのすべての Pod、PersistentVolume、StorageClass リソースが含まれていることを確認する手順は次のとおりです。
バックアップ クラスタ
cluster-db2
へのkubectl
コマンドライン アクセスを構成します。gcloud container clusters get-credentials $TARGET_CLUSTER --region $DR_REGION --project $PROJECT_ID
3/3 Pod で StatefulSet の準備ができていることを確認します。
kubectl get all -n $NAMESPACE
出力は次のようになります。
NAME READY STATUS RESTARTS AGE pod/postgresql-postgresql-ha-pgpool-778798b5bd-k2q4b 1/1 Running 0 4m49s pod/postgresql-postgresql-ha-postgresql-0 2/2 Running 2 (4m13s ago) 4m49s pod/postgresql-postgresql-ha-postgresql-1 2/2 Running 0 4m49s pod/postgresql-postgresql-ha-postgresql-2 2/2 Running 0 4m49s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/postgresql-postgresql-ha-pgpool ClusterIP 192.168.241.46 <none> 5432/TCP 4m49s service/postgresql-postgresql-ha-postgresql ClusterIP 192.168.220.20 <none> 5432/TCP 4m49s service/postgresql-postgresql-ha-postgresql-headless ClusterIP None <none> 5432/TCP 4m49s service/postgresql-postgresql-ha-postgresql-metrics ClusterIP 192.168.226.235 <none> 9187/TCP 4m49s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/postgresql-postgresql-ha-pgpool 1/1 1 1 4m49s NAME DESIRED CURRENT READY AGE replicaset.apps/postgresql-postgresql-ha-pgpool-778798b5bd 1 1 1 4m49s NAME READY AGE statefulset.apps/postgresql-postgresql-ha-postgresql 3/3 4m49s
postgres
Namespace 内のすべての Pod が動作していることを確認します。kubectl get pods -n $NAMESPACE
出力は次のようになります。
postgresql-postgresql-ha-pgpool-569d7b8dfc-2f9zx 1/1 Running 0 7m56s postgresql-postgresql-ha-postgresql-0 2/2 Running 0 7m56s postgresql-postgresql-ha-postgresql-1 2/2 Running 0 7m56s postgresql-postgresql-ha-postgresql-2 2/2 Running 0 7m56s
PersistentVolume と StorageClass を確認します。復元処理中に、Backup for GKE は、ターゲット ワークロードにプロキシクラスを作成して、ソース ワークロード(サンプル出力の
gce-pd-gkebackup-dn
)でプロビジョニングされた StorageClass を置き換えます。kubectl get pvc -n $NAMESPACE
出力は次のようになります。
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-postgresql-postgresql-ha-postgresql-0 Bound pvc-be91c361e9303f96 8Gi RWO gce-pd-gkebackup-dn 10m data-postgresql-postgresql-ha-postgresql-1 Bound pvc-6523044f8ce927d3 8Gi RWO gce-pd-gkebackup-dn 10m data-postgresql-postgresql-ha-postgresql-2 Bound pvc-c9e71a99ccb99a4c 8Gi RWO gce-pd-gkebackup-dn 10m
想定どおりのデータが復元されていることを確認する
想定どおりのデータが復元されていることを確認する手順は次のとおりです。
PostgreSQL インスタンスに接続します。
./scripts/launch-client.sh kubectl exec -it pg-client -n postgresql -- /bin/bash
各テーブルの行数を確認します。
psql -h $HOST_PGPOOL -U postgres -a -q -f /tmp/scripts/count-rows.sql select COUNT(*) from tb01;
前述のテスト データセットを作成するで書き込んだデータと同様の結果を確認できます。出力は次のようになります。
300000 (1 row)
クライアント Pod を終了します。
exit
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトを削除する
課金を停止する最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
次のステップ
- GKE にデータベースをデプロイするためのベスト プラクティスを学習する。
- 永続ボリュームの詳細を確認する。
- 高可用性 PostgreSQL クラスタでのストリーミング レプリケーションに Pgpool-II を使用する方法の例を確認する。