このガイドでは、CloudNativePG オペレーターを使用して PostgreSQL クラスタを Google Kubernetes Engine(GKE)にデプロイする方法について説明します。
PostgreSQL は、数十年にわたって積極的に開発され、安定したクライアント パフォーマンスを実現するオープンソースのオブジェクト リレーショナル データベースです。レプリケーション、ポイントインタイム リカバリ、セキュリティ機能、拡張性など、幅広い機能を備えています。PostgreSQL は主要なオペレーティング システムと互換性があり、ACID(アトミック性、整合性、独立性、耐久性)標準に完全に準拠しています。
このガイドは、GKE に Postgres クラスタをデプロイすることに関心があるプラットフォーム管理者、クラウド アーキテクト、運用担当者を対象としています。Cloud SQL を使用する代わりに GKE で Postgres を実行すると、経験豊富なデータベース管理者がより柔軟に構成を管理できるようになります。
利点
CloudNativePG は、Apache 2 ライセンスの下で EDB が開発したオープンソースのオペレーターです。これにより、PostgreSQL のデプロイメントに次の機能が追加されます。
- 宣言型および Kubernetes ネイティブの方法による PostgreSQL クラスタの管理と構成
- Volume Snapshots または Cloud Storage を使用したバックアップ管理
- 転送中の暗号化された TLS 接続、独自の認証局を使用する機能、TLS 証明書の自動発行とローテーションのための Certificate Manager とのインテグレーション
- PostgreSQL のマイナー リリースに対するローリング アップデート
- Kubernetes API サーバーを使用して、追加のツールなしで PostgreSQL クラスタのステータス維持と、高可用性のためのフェイルオーバーを実現
- SQL で記述されたユーザー定義指標による組み込みの Prometheus エクスポータ構成
目標
- Postgres 向けに GKE インフラストラクチャを計画して、デプロイする
- Helm を使用して CloudNativePG Postgres オペレーターをデプロイして構成する
- PostgreSQL クラスタをデプロイする
- PostgreSQL の認証とオブザーバビリティを構成する
デプロイ アーキテクチャ
PostgreSQL には、スタンドアロン データベース サーバーからレプリケーションされた高可用性クラスタまで、さまざまなデプロイ オプションがあります。このチュートリアルでは、GKE への高可用性クラスタのデプロイに焦点を当てています。
このデプロイでは、リージョン GKE クラスタ内の複数のアベイラビリティ ゾーンに PostgreSQL クラスタのワークロードが分散され、高可用性と冗長性が確保されます。詳細については、リージョン クラスタをご覧ください。
次の図は、GKE クラスタ内の複数のノードとゾーンで実行されている Postgres クラスタを示しています。
デフォルトの設定には、1 つのメイン PostgreSQL サーバーと、メインサーバーが故障した場合に引き継ぐ準備ができている 2 つのバックアップ サーバーが含まれています。これにより、データベースの可用性が継続的に確保されます。
CloudNativePG オペレーター リソースは、GKE クラスタの別の Namespace を使用してリソースの隔離を強化し、PostgreSQL クラスタごとに 1 つのデータベースという推奨されるマイクロサービス アプローチを遵守します。データベースとそれに対応するユーザー(アプリユーザー)は、クラスタを表す Kubernetes カスタム リソースで定義されます。
ストレージは、データベースについて議論する際に重要な要素となります。ストレージを効率的に実行し、継続的な可用性を確保して、データの整合性を保証する必要があります。このような理由から、SSD ディスクに基づく
premium-rwoストレージ クラスをおすすめします。CloudNativePG オペレーターは、PostgreSQL クラスタの Pod を設定すると、必要に応じてPersistentVolumeClaimsを自動的に作成します。
費用
このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
Cloud Shell には、このチュートリアルに必要なソフトウェア(kubectl、gcloud CLI、Helm、Terraform など)がプリインストールされています。Cloud Shell を使用しない場合は、gcloud CLI をインストールする必要があります。
- 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.
-
Install the Google Cloud CLI.
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します。
gcloud init -
Create or select a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_IDwith a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_IDwith your Google Cloud project name.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com -
Install the Google Cloud CLI.
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します。
gcloud init -
Create or select a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_IDwith a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_IDwith your Google Cloud project name.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine, IAM, GKE, Resource Manager APIs:
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.gcloud services enable compute.googleapis.com
iam.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com -
Grant roles to your user account. Run the following command once for each of the following IAM roles:
roles/compute.securityAdmin, roles/compute.viewer, roles/container.clusterAdmin, roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUsergcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
Replace the following:
PROJECT_ID: Your project ID.USER_IDENTIFIER: The identifier for your user account. For example,myemail@example.com.ROLE: The IAM role that you grant to your user account.
環境変数を設定します。
export PROJECT_ID=PROJECT_ID export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1PROJECT_IDは実際の Google Cloud プロジェクト ID に置き換えます。GitHub リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples作業ディレクトリを変更します。
cd kubernetes-engine-samples/databases/postgresql-cloudnativepg- Kubernetes ノード用の VPC ネットワークとプライベート サブネット
- NAT 経由でインターネットにアクセスするためのルーター
us-central1リージョンの限定公開 GKE クラスタ- 自動スケーリングが有効になっているノードプール(ゾーンあたり 1~2 ノード、最小ゾーンあたり 1 ノード)
- Kubernetes ノード用の VPC ネットワークとプライベート サブネット
- NAT 経由でインターネットにアクセスするためのルーター
us-central1リージョンの限定公開 GKE クラスタ- ロギングとモニタリングの権限を持つ
ServiceAccount - Google Cloud Managed Service for Prometheus(クラスタ モニタリング用)
CloudNativePG オペレーターの Helm チャート リポジトリを追加します。
helm repo add cnpg https://cloudnative-pg.github.io/chartsHelm コマンドライン ツールを使用して CloudNativePG オペレーターをデプロイします。
helm upgrade --install cnpg \ --namespace cnpg-system \ --create-namespace \ cnpg/cloudnative-pg出力は次のようになります。
Release "cnpg" does not exist. Installing it now. NAME: cnpg LAST DEPLOYED: Fri Oct 13 13:52:36 2023 NAMESPACE: cnpg-system STATUS: deployed REVISION: 1 TEST SUITE: None ...spec.instances: クラスタ Pod の数spec.primaryUpdateStrategy: ローリング アップデート戦略。Unsupervised: レプリカノードの後にプライマリ クラスタノードを自律的に更新します。Supervised: プライマリ クラスタノードの手動切り替えが必要です
spec.postgresql:postgres.confファイル パラメータのオーバーライド(pg-hba ルール、LDAP、満たすべき同期レプリカの要件など)。spec.storage: ストレージ関連の設定(ストレージ クラス、Volume のサイズ、write-ahead log の設定など)。spec.bootstrap: クラスタで作成された初期データベースのパラメータ、ユーザー認証情報、データベースの復元オプションspec.resources: クラスタ Pod のリクエストと上限spec.affinity: クラスタ ワークロードのアフィニティと反アフィニティ ルールNamespace を作成します。
kubectl create ns pg-nsカスタム リソースを使用して PostgreSQL クラスタを作成します。
kubectl apply -n pg-ns -f manifests/01-basic-cluster/postgreSQL_cluster.yamlこのコマンドの完了までに数分かかることがあります。
クラスタのステータスを確認します。
kubectl get cluster -n pg-ns --watch出力に
Cluster in healthy stateのステータスが表示されるまで待ってから、次のステップに進みます。NAME AGE INSTANCES READY STATUS PRIMARY gke-pg-cluster 2m53s 3 3 Cluster in healthy state gke-pg-cluster-1- オペレーターが制御する PostgreSQL クラスタを表すクラスタ カスタム リソース
- 対応する永続ボリュームがある PersistentVolumeClaim リソース
- データベースへのアクセスや Postgres ノード間のレプリケーションのためのユーザー認証情報を含むシークレット。
- クラスタに接続する
<name>-rw、<name>-ro、<name>-rの 3 つのデータベース エンドポイント サービス。詳細については、PostgreSQL のアーキテクチャをご覧ください。 クライアント Pod を実行して Postgres クラスタとやり取りします。
kubectl apply -n pg-ns -f manifests/02-auth/pg-client.yamlpg-clientPod でexecコマンドを実行し、gke-pg-cluster-rwService にログインします。kubectl wait --for=condition=Ready -n pg-ns pod/pg-client --timeout=300s kubectl exec -n pg-ns -i -t pg-client -- /bin/shgke-pg-cluster-rwService を使用してデータベースにログインし、読み取り / 書き込み権限で接続を確立します。psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/appターミナルはデータベース名で始まります。
app=>テーブルを作成します。
CREATE TABLE travel_agency_clients ( client VARCHAR ( 50 ) UNIQUE NOT NULL, address VARCHAR ( 50 ) UNIQUE NOT NULL, phone VARCHAR ( 50 ) UNIQUE NOT NULL);テーブルにデータを挿入します。
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('Tom', 'Warsaw', '+55555') RETURNING *;作成したデータを表示します。
SELECT * FROM travel_agency_clients ;出力は次のようになります。
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)現在のデータベース セッションからログアウトします。
exitgke-pg-cluster-roService を使用してデータベースにログインし、読み取り専用アクセス権を確認します。この Service ではデータのクエリは許可されますが、書き込みオペレーションは制限されます。psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-ro.pg-ns/app新しいデータの挿入を試みます。
INSERT INTO travel_agency_clients(client, address, phone) VALUES ('John', 'Paris', '+55555') RETURNING *;出力は次のようになります。
ERROR: cannot execute INSERT in a read-only transactionデータの読み取りを試みます。
SELECT * FROM travel_agency_clients ;出力は次のようになります。
client | address | phone --------+---------+--------- Tom | Warsaw | +55555 (1 row)現在のデータベース セッションからログアウトします。
exitPod のシェルを終了します。
exit- パス
/とポート9187の指標を収集する Postgres Pod - Postgres Pod の指標を処理する Prometheus ベースのコレクタ
- Cloud Monitoring に指標を送信する
PodMonitoringリソース PodMonitoringリソースを作成します。kubectl apply -f manifests/03-observability/pod-monitoring.yaml -n pg-nsGoogle Cloud コンソールで、[Metrics Explorer] のページに移動します。
ダッシュボードにゼロ以外の指標の取り込み率が表示されます。
[指標を選択] で、「Prometheus Target」と入力します。
[有効な指標カテゴリ] セクションで、[Cnpg] を選択します。
ダッシュボードをデプロイします。
gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file manifests/03-observability/gcp-pg.jsonGoogle Cloud コンソールで [ダッシュボード] ページに移動します。
[PostgresQL Prometheus Overview] ダッシュボードを選択します。
ダッシュボードがどのように関数をモニタリングしているかを確認するには、[データベース認証] セクションのアクションを再利用し、データベースに読み取り / 書き込みリクエストを適用した後、収集した指標の可視化をダッシュボードで確認します。
クライアント Pod に接続します。
kubectl exec -n pg-ns -i -t pg-client -- /bin/shランダムなデータを挿入します。
psql postgresql://$CLIENTUSERNAME:$CLIENTPASSWORD@gke-pg-cluster-rw.pg-ns/app -c "CREATE TABLE test (id serial PRIMARY KEY, randomdata VARCHAR ( 50 ) NOT NULL);INSERT INTO test (randomdata) VALUES (generate_series(1, 1000));"ダッシュボードを更新します。グラフは実際の指標で更新されます。
Pod のシェルを終了します。
exit環境変数を設定します。
export PROJECT_ID=${PROJECT_ID} export KUBERNETES_CLUSTER_PREFIX=postgres export REGION=us-central1terraform destroyコマンドを実行します。export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token) terraform -chdir=terraform/FOLDER destroy \ -var project_id=${PROJECT_ID} \ -var region=${REGION} \ -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}FOLDERは、gke-autopilotまたはgke-standardに置き換えます。プロンプトが表示されたら、「
yes」と入力します。アタッチされていないすべてのディスクを検索します。
export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,zone)")ディスクを削除します。
for i in $disk_list; do disk_name=$(echo $i| cut -d'|' -f1) disk_zone=$(echo $i| cut -d'|' -f2|sed 's|.*/||') echo "Deleting $disk_name" gcloud compute disks delete $disk_name --zone $disk_zone --quiet done- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。
環境の設定
環境の設定手順は次のとおりです。
クラスタ インフラストラクチャを作成する
このセクションでは、Terraform スクリプトを実行して、限定公開の高可用性リージョン GKE クラスタを作成します。
オペレーターは、Standard または Autopilot クラスタを使用してインストールできます。
Standard
次の図は、3 つの異なるゾーンにデプロイされた限定公開のリージョン GKE Standard クラスタを示しています。
このインフラストラクチャをデプロイするには、次のコマンドを実行します。
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
プロンプトが表示されたら、「yes」と入力します。このコマンドが完了し、クラスタが準備完了ステータスになるまでに数分かかることがあります。
Terraform が次のリソースを作成します。
出力は次のようになります。
...
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
...
Autopilot
次の図は、限定公開のリージョン GKE Autopilot クラスタを示しています。
このインフラストラクチャをデプロイするには、次のコマンドを実行します。
export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
プロンプトが表示されたら、「yes」と入力します。このコマンドが完了し、クラスタが準備完了ステータスになるまでに数分かかることがあります。
Terraform が次のリソースを作成します。
出力は次のようになります。
...
Apply complete! Resources: 12 added, 0 changed, 0 destroyed.
...
クラスタに接続する
クラスタと通信を行うように kubectl を構成します。
gcloud container clusters get-credentials ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${REGION}
CloudNativePG オペレーターをデプロイする
Helm チャートを使用して、CloudNativePG を Kubernetes クラスタにデプロイします。
Postgres をデプロイする
次のマニフェストは、CloudNativePG オペレーターのカスタム リソースで定義された PostgreSQL クラスタを記述しています。
このマニフェストには次のフィールドがあります。
基本的な Postgres クラスタを作成する
リソースを検査する
GKE がクラスタのリソースを作成したことを確認します。
kubectl get cluster,pod,svc,pvc,pdb,secret,cm -n pg-ns
出力は次のようになります。
NAME AGE INSTANCES READY STATUS PRIMARY
cluster.postgresql.cnpg.io/gke-pg-cluster 32m 3 3 Cluster in healthy state gke-pg-cluster-1
NAME READY STATUS RESTARTS AGE
pod/gke-pg-cluster-1 1/1 Running 0 31m
pod/gke-pg-cluster-2 1/1 Running 0 30m
pod/gke-pg-cluster-3 1/1 Running 0 29m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gke-pg-cluster-r ClusterIP 10.52.11.24 <none> 5432/TCP 32m
service/gke-pg-cluster-ro ClusterIP 10.52.9.233 <none> 5432/TCP 32m
service/gke-pg-cluster-rw ClusterIP 10.52.1.135 <none> 5432/TCP 32m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/gke-pg-cluster-1 Bound pvc-bbdd1cdd-bdd9-4e7c-8f8c-1a14a87e5329 2Gi RWO standard 32m
persistentvolumeclaim/gke-pg-cluster-2 Bound pvc-e7a8b4df-6a3e-43ce-beb0-b54ec1d24011 2Gi RWO standard 31m
persistentvolumeclaim/gke-pg-cluster-3 Bound pvc-dac7f931-6ac5-425f-ac61-0cfc55aae72f 2Gi RWO standard 30m
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
poddisruptionbudget.policy/gke-pg-cluster 1 N/A 1 32m
poddisruptionbudget.policy/gke-pg-cluster-primary 1 N/A 0 32m
NAME TYPE DATA AGE
secret/gke-pg-cluster-app kubernetes.io/basic-auth 3 32m
secret/gke-pg-cluster-ca Opaque 2 32m
secret/gke-pg-cluster-replication kubernetes.io/tls 2 32m
secret/gke-pg-cluster-server kubernetes.io/tls 2 32m
secret/gke-pg-cluster-superuser kubernetes.io/basic-auth 3 32m
NAME DATA AGE
configmap/cnpg-default-monitoring 1 32m
configmap/kube-root-ca.crt 1 135m
オペレーターが次のリソースを作成します。
Postgres に対する認証を行う
PostgreSQL データベースに接続し、オペレーターによって作成されたさまざまなサービス エンドポイントを介してアクセスを確認できます。これを行うには、PostgreSQL クライアントがあり、同期アプリケーション ユーザー認証情報が環境変数としてマウントされた追加の Pod を使用します。
Prometheus が Postgres クラスタの指標を収集する仕組みを理解する
次の図は、Prometheus 指標の収集の仕組みを示しています。
この図では、GKE のプライベート クラスタに次のものが存在します。
Pod から指標を収集できるようにするには、次の手順で操作します。
指標のダッシュボードを作成する
エクスポートされた指標を可視化するには、指標ダッシュボードを作成します。
クリーンアップ
プロジェクトを削除する
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID