PostgreSQL 是開放原始碼的物件關聯式資料庫,以可靠性和資料完整性著稱。它符合 ACID 標準,並支援外鍵、聯結、檢視區塊、觸發程序和預存程序。
本文件適用於有興趣在 Google Kubernetes Engine (GKE) 上部署高可用性 PostgreSQL 拓撲的資料庫管理員、雲端架構師和營運專員。
目標
您在本教學課程中將學習以下內容:- 使用 Terraform 建立區域 GKE 叢集。
- 部署高可用性的 PostgreSQL 資料庫。
- 為 PostgreSQL 應用程式設定監控功能。
- 執行 PostgreSQL 資料庫和 GKE 叢集升級。
- 模擬叢集故障和 PostgreSQL 備用資源容錯移轉。
- 備份及還原 PostgreSQL 資料庫。
架構
本節說明您將在本教學課程中建構的解決方案架構。
您將在不同區域佈建兩個 GKE 叢集:主要叢集和備份叢集。在本教學課程中,主要叢集位於 us-central1
區域,備份叢集則位於 us-west1
區域。這個架構可讓您佈建高可用性的 PostgreSQL 資料庫,並測試災難復原功能,詳情請參閱本教學課程的後續內容。
對於來源叢集,您將使用 Helm 圖表 (bitnami/postgresql-ha
) 設定高可用性 PostgreSQL 叢集。
費用
在本文件中,您會使用 Google Cloud的下列計費元件:
如要根據預測用量估算費用,請使用 Pricing Calculator。
完成本文所述工作後,您可以刪除已建立的資源,避免繼續計費。詳情請參閱清除所用資源一節。
事前準備
設定專案
- 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:
roles/storage.objectViewer, roles/logging.logWriter, roles/artifactregistry.Admin, roles/container.clusterAdmin, roles/container.serviceAgent, roles/serviceusage.serviceUsageAdmin, roles/iam.serviceAccountAdmin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user: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
在 Google Cloud 控制台中,按一下
「Activate Cloud Shell」(啟用 Cloud Shell),即可啟動 Cloud Shell 工作階段。Google Cloud 系統會在 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
設定角色
設定環境
在本教學課程中,您將使用 Cloud Shell 管理託管於Google Cloud的資源。Cloud Shell 已預先安裝本教學課程所需的軟體,包括 Docker、kubectl
、gcloud CLI、Helm 和 Terraform。
如要使用 Cloud Shell 設定環境:
建立叢集基礎架構
在本節中,您將執行 Terraform 指令碼,建立自訂虛擬私有雲 (VPC)、用於儲存 PostgreSQL 映像檔的 Artifact Registry 存放區,以及兩個區域性 GKE 叢集。一個叢集會部署在 us-central1
,另一個備份叢集則會部署在 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 設定檔會建立下列資源,以部署基礎架構:
- 建立 Artifact Registry 存放區,用於儲存 Docker 映像檔。
- 為 VM 的網路介面建立虛擬私有雲網路和子網路。
建立主要 GKE 叢集。
Terraform 會在
us-central1
區域中建立私人叢集,並啟用 GKE 備份功能,以進行災害復原,以及啟用 Managed Service for Prometheus,以監控叢集。只有搭載 GKE 1.25 以上版本的 Autopilot 叢集支援 Managed Service for Prometheus。
在
us-west1
區域建立備份叢集,用於災難復原。
標準
在 Cloud Shell 中執行下列指令:
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply -var project_id=$PROJECT_ID
系統顯示提示訊息時,請輸入 yes
。
瞭解 Terraform 設定
Terraform 設定檔會建立下列資源,以部署基礎架構:
- 建立 Artifact Registry 存放區,用於儲存 Docker 映像檔。
- 為 VM 的網路介面建立虛擬私有雲網路和子網路。
建立主要 GKE 叢集。
Terraform 會在
us-central1
區域中建立私人叢集,並啟用 GKE 備份功能,以進行災難復原,以及啟用 Managed Service for Prometheus,以監控叢集。在
us-west1
區域建立備份叢集,用於災難復原。
在叢集上部署 PostgreSQL
在本節中,您將使用 Helm 圖表部署 PostgreSQL 資料庫執行個體,在 GKE 上執行。
安裝 PostgreSQL
如要在叢集上安裝 PostgreSQL,請按照下列步驟操作。
設定 Docker 存取權。
gcloud auth configure-docker us-docker.pkg.dev
在 Artifact Registry 中填入必要的 PostgreSQL Docker 映像檔。
./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 映像檔推送至 Artifact Registry,供 Helm 安裝:
postgresql-repmgr
: 這個 PostgreSQL 叢集解決方案包含 PostgreSQL 複製管理工具 (repmgr), 這項開放原始碼工具可管理 PostgreSQL 叢集上的複製和容錯移轉作業。postgres-exporter
: PostgreSQL Exporter 會收集 PostgreSQL 指標,供 Prometheus 使用。pgpool
:Pgpool-II 是 PostgreSQL Proxy。並提供連線集區和負載平衡。
確認正確的映像檔儲存在存放區中。
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
建立命名空間。
export NAMESPACE=postgresql kubectl create namespace $NAMESPACE
如果您要部署至 Autopilot 叢集,請在三個區域中設定節點佈建。如果您要部署至標準叢集,可以略過這個步驟。
根據預設,Autopilot 只會在兩個區域中佈建資源。
prepareforha.yaml
中定義的部署作業可確保 Autopilot 在叢集的三個區域中佈建節點,方法是設定下列值:replicas:3
podAntiAffinity
,當中包含requiredDuringSchedulingIgnoredDuringExecution
和topologyKey: "topology.kubernetes.io/zone"
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
啟動 Shell 工作階段。
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 部署作業包含 postgresql-exporter
Sidecar 容器。這個容器會公開 /metrics
端點。
Google Cloud Managed Service for Prometheus 已設定為監控這個端點上的 PostgreSQL Pod。您可以透過 Google Cloud 主控台資訊主頁查看這些指標。
Google Cloud 控制台提供幾種建立及儲存資訊主頁設定的方式:
- 建立及匯出:您可以直接在 Google Cloud console 中建立資訊主頁,然後匯出並儲存在程式碼存放區。如要這麼做,請在資訊主頁工具列中開啟 JSON 編輯器,然後下載資訊主頁 JSON 檔案。
- 儲存和匯入:按一下「+Create Dashboard」(建立資訊主頁),然後使用「JSON editor」(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).
系統會觸發快訊,並傳送電子郵件給 YOUR_EMAIL,主旨行開頭為「[ALERT] Max Lag of transaction」。
在 Google Cloud 控制台中,前往「Alert Policy」(快訊政策) 頁面。
從列出的政策中選取
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。 定義新版本 (例如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 升級作業
如果您執行的是標準叢集,請參閱本節內容。執行有狀態服務時,您可以採取主動措施並設定配置,以降低風險並順利升級叢集,包括:
請遵循升級叢集的 GKE 最佳做法。選擇適當的升級策略,確保升級作業會在維護期間進行:
詳情請參閱「升級執行有狀態工作負載的叢集」。
使用 Recommender 服務檢查淘汰深入分析和建議,避免服務中斷。
使用維護期間,確保升級作業會在您預期的時間進行。在維護時段前,請確認資料庫備份作業是否成功。
允許流量進入升級後的節點前,請先使用完備性和有效性探測,確保節點已準備好處理流量。
建立探查,評估複寫是否同步,再接受流量。視資料庫的複雜度和規模而定,您可以透過自訂指令碼完成這項作業。
在 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
指令,針對資料庫產生一些流量。以下指令會執行pgbench
一小時,目標為每秒 200 筆交易,並每隔 2 秒列出要求率。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
:速率以每秒交易次數表示--progress
:每隔 sec 秒顯示進度報告。
輸出結果會與下列內容相似:
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 Overview」(PostgreSQL 總覽) 資訊主頁。請注意「每個資料庫的連線數」和「每個 Pod 的連線數」圖表中的尖峰。
結束用戶端 Pod。
exit
刪除用戶端 Pod。
kubectl delete pod -n postgresql pg-client
模擬 PostgreSQL 服務中斷
在本節中,您將停止複製管理員服務,模擬其中一個 PostgreSQL 副本發生服務中斷。這會導致 Pod 無法將流量提供給同層級副本,且存活探查會失敗。
開啟新的 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 容器設定的存活探測作業會在五秒內開始失敗。每隔十秒重複一次,直到達到六次失敗的失敗門檻為止。達到 failureThreshold
值後,容器就會重新啟動。您可以設定這些參數,降低存活探查容許值,以調整部署作業的服務水準目標需求。
在事件串流中,您會看到 Pod 的有效性和完備性探測失敗,以及容器需要重新啟動的訊息。輸出結果會與下列內容相似:
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 的災難復原作業可分為兩個階段:
- 備份是指在服務中斷事件發生前,建立狀態或資料的時間點快照。
- 復原是指在發生災害後,從備份副本還原狀態或資料。
如要備份及還原 GKE 叢集中的工作負載,可以使用 GKE 備份服務。您可以在新叢集和現有叢集上啟用這項服務。 這會部署在叢集中執行的 Backup for GKE 代理程式,負責擷取設定和磁碟區備份資料,並協調復原作業。
備份和還原作業的範圍可以是整個叢集、命名空間或應用程式 (由選取器定義,例如 matchLabels
)。
PostgreSQL 備份與還原情境範例
本節的範例說明如何使用 ProtectedApplication
自訂資源,在應用程式範圍內執行備份和還原作業。
下圖顯示 ProtectedApplication 中的元件資源,也就是代表 postgresql-ha
應用程式的 StatefulSet,以及 pgpool
的部署作業,兩者使用相同的標籤 (app.kubernetes.io/name: postgresql-ha
)。
如要準備備份及還原 PostgreSQL 工作負載,請按照下列步驟操作:
設定環境變數。在本範例中,您將使用 ProtectedApplication 從來源 GKE 叢集 (
us-central1
) 還原 PostgreSQL 工作負載及其磁碟區,然後還原至不同區域的另一個 GKE 叢集 (us-west1
)。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
確認叢集已啟用 GKE 備份服務。您先前執行的 Terraform 設定應該已啟用這項服務。
gcloud container clusters describe $SOURCE_CLUSTER \ --project=$PROJECT_ID \ --region=$REGION \ --format='value(addonsConfig.gkeBackupAgentConfig)'
如果已啟用 Backup for GKE,指令輸出內容會顯示
enabled=True
。
設定備份方案並執行還原
您可以透過 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
確認 StatefulSet 已準備就緒,且有 3/3 個 Pod。
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
命名空間中的所有 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。在還原程序中,GKE 備份服務會在目標工作負載中建立 Proxy 類別,以取代來源工作負載中佈建的 StorageClass (範例輸出中的
gce-pd-gkebackup-dn
)。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 上部署資料庫的最佳做法。
- 進一步探索永久磁碟區。
- 如需如何使用 Pgpool-II 進行串流複製的範例,請參閱這篇文章。