以前の記事 Crunchy Postgres Operatorの紹介 では、バージョン 4 を対象に Crunchy Postgres Operator のインストール方法、主な機能について紹介しました。2021 年にリリースされた バージョン 5 (v5) では、インストールや管理方法が大幅に変更され、より簡単に構築・運用できるようになりました。
本記事では、 Crunchy Postgres Operator (PGO) v5 のインストール方法と主な機能の使い方について紹介します。
Operator を使う理由や Crunchy Postgres Operator の概要については以前の記事 Kubernetes PostgreSQL Operatorの紹介、Crunchy Postgres Operatorの紹介 を参照してください。
PGO v5 の主な変更点
以前 v4 で紹介した以下の機能は、v5 でも引き続き利用できます。利用する際の設定方法は v4 までと異なるので、詳しい設定方法については後述します。
- PostgreSQL HA クラスタのデプロイ・管理
- ストリーミングレプリケーション (同期・非同期)
- フェイルオーバー
- バックアップ
- WALアーカイブ
- リストア・PITR
- アップグレード
- コネクションプール
- モニタリング
PGO v5 における構築・運用の主な変更点は以下の通りです。
- PGO v5 では、Kustomize または Helm を利用し、PGO をインストールします。v4 までの方法に比べて、より簡単にインストールできるようになりました。
- PGO v4 では基本的に pgo クライアントコマンドを利用して各種操作を行っていましたが、PGO v5 では pgo クライアントコマンドが廃止されました。PGO v5では、Kubernetes で一般的によく使われるコマンドラインツール kubectl を利用して PostgreSQL の構築および管理を行います。
- PostgreSQL インスタンスは StatefulSet を使用するようになりました。
- PGO v4 までは PostgreSQL のマイナーバージョンアップを行うために、「PGO 自身のアップデート」と「PostgreSQL のアップデート」の2段階のアップデートを実行する必要がありましたが、PGO v5 では、PGO のバージョンを更新せず、PostgreSQL のイメージをアップデートするだけでマイナーバージョンアップができるようになりました。
その他の改良や変更点についてはPGO 5.0.0 のリリースノートを参照してください。
PGO v5 の動作環境
本記事執筆時点 (2022 年 3 月) では、以下の環境で動作確認が行われています。
- Kubernetes 1.19 以降
- OpenShift 4.6 以降
- Rancher
- Google Kubernetes Engine (GKE), Anthos を含む
- Amazon EKS
- Microsoft AKS
- VMware Tanzu
検証環境およびバージョン情報
本記事では Kubernetes のマネージドサービスである Amazon EKS 上で PGO v5 のデプロイ・動作確認を行います。
環境の構成およびバージョン情報は以下のとおりです。各ソフトウェアは 2022 年 3 月時点での最新バージョンを利用しています。
- PGO 5.0.5
- Amazon EKS
- Kubernetes バージョン: 1.21
- ノード数: 3ノード
- ノードタイプ: t3.medium
- オブジェクトストレージ: Amazon S3
- ローカル作業環境: CentOS 7.9 (VirtualBox 上の VM)
検証内容
本記事では、PGO v5 を用いて PostgreSQL クラスタを構築し、以下の機能について動作確認を行います。
- PGO のデプロイ
- PostgreSQL クラスタの作成
- psql による接続確認
- PostgreSQL の設定
- フェイルオーバー
- スケーリング
- ボリュームサイズの拡張
- バックアップ
- リストア・PITR
- モニタリング
前提条件
PGO をデプロイする前に、次の準備が完了していることが前提となります。
PGO のデプロイ
PGO v5 以降、PGO のデプロイは Kustomize または Helm を使うことになりました。本記事では、Kustomize を用いて PGO をデプロイします。
各種サンプル設定ファイルを含むpostgres-operator-examplesリポジトリを作業環境に複製します。
$ git clone https://github.com/CrunchyData/postgres-operator-examples.git $ cd postgres-operator-examples/
PGO をデプロイします。
$ kubectl apply -k kustomize/install
上記コマンドを実行すると、postgres-operator という名前空間が作成され、PGO のデプロイに必要なすべてのオブジェクトがこの名前空間に作成されます。
$ kubectl get pods -n postgres-operator NAME READY STATUS RESTARTS AGE pgo-59c4f987b6-cd6pn 1/1 Running 0 29s
ストレージクラスの作成
Amazon EKS ではデフォルトで gp2 という名前のストレージクラスが作成されていますが、本記事では以下の属性を持つ PGO 専用のストレージクラスを作成します。
allowVolumeExpansion: ボリュームの拡張を許可するように true を設定する。reclaimPolicy: PVC が削除された際に PV を残すように Retain を設定する。
$ cat > ~/pgo-sc.yaml <<EOF apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: pgo provisioner: kubernetes.io/aws-ebs parameters: type: gp2 fsType: ext4 allowVolumeExpansion: true reclaimPolicy: Retain EOF $ kubectl apply -f ~/pgo-sc.yaml
作成したストレージクラス pgo を確認します。
$ kubectl get sc pgo NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE pgo kubernetes.io/aws-ebs Retain Immediate true 6m36s
PostgreSQL クラスタの作成
PostgreSQL クラスタをデプロイします。
今回は以下のような構成の PostgreSQL クラスタを作成します。
- master 1台、replica 2台
- 同期レプリケーション
- 自動フェイルオーバー (デフォルト)
- WAL アーカイブ (デフォルト)
- 永続ボリュームと Amazon S3 にバックアップと WAL アーカイブを保存
取得したバックアップや WAL アーカイブは永続ボリュームのほか、S3 や GCS、Azure Blob Storage などのオブジェクトストレージにも保存できます。今回は、Amazon S3 を使います。GCS や Azure Blob Storage の設定については、こちらを参照してください。
postgres-operator-examples リポジトリに各種構成のサンプル設定ファイルが用意されているので、それらのファイルを元に設定ファイルを作成します。今回は S3 を利用するために、kustomize/s3 配下のサンプルファイルをコピーし、必要に応じて編集します。
$ cp -r kustomize/s3 kustomize/my-postgres
PGO v5 では PostgresCluster リソース (CRD) を使って、PostgreSQL クラスタのデプロイ・管理を行います。 PostgresCluster 設定のサンプルは postgres.yaml ファイルに記述されているので、必要に応じて編集します。
今回は以下のような YAML ファイルを利用して PostgresCluster をデプロイします。
$ cat kustomize/my-postgres/postgres.yaml
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: my-postgres
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-14.2-0
postgresVersion: 14
instances:
- name: pg-1
replicas: 3
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 10Gi
storageClassName: pgo
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:centos8-2.36-1
configuration:
- secret:
name: pgo-s3-creds
global:
repo2-path: /pgbackrest/postgres-operator/my-postgres/repo2
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 10Gi
storageClassName: pgo
- name: repo2
s3:
bucket: "my-postgres"
endpoint: "s3.us-west-2.amazonaws.com"
region: "us-west-2"
patroni:
dynamicConfiguration:
synchronous_mode: true
users:
- name: postgres
- name: testuser
databases:
- testdb
パラメータの意味は以下のとおりです。
spec.instances.replicas: レプリカの数を指定します。上記設定では、master 1台、replica 2台の PostgreSQL クラスタが作成されます。spec.backups.pgbackrest.repos.name: バックアップと WAL アーカイブの保存先を設定します。repoN 形式で複数の保存先を指定可能です。上記設定では、永続ボリュームを repo1、S3 を repo2 と設定しています。spec.backups.pgbackrest.repos.s3: Amazon S3 バケット情報を設定します。今回は前述の「前提条件」であらかじめ作成したバケットを利用します。spec.instances.dataVolumeClaimSpec: PostgreSQL データ保存用の PVC を設定します。spec.backups.pgbackrest.repos.volume.volumeClaimSpec: バックアップと WAL アーカイブ保存用の PVC を設定します。spec.patroni.dynamicConfiguration.synchronous_mode: 同期レプリケーションを利用するか否かを true/false で設定します。spec.users: デプロイ時に作成する PostgreSQL ユーザとデータベースを指定します。上記設定では、postgres と testuser ユーザ、testdb データベースが作成され、testuser に testdb へのアクセス権限が付与されます。
次に、Amazon S3 にアクセスするためのクレデンシャルを登録します。repoN には、上記 postgres.yaml に設定した S3 のリポジトリ名を指定します。
$ cp kustomize/my-postgres/s3.conf{.example,}
$ vi kustomize/my-postgres/s3.conf
[global]
repo2-s3-key=<アクセスキー>
repo2-s3-key-secret=<シークレットアクセスキー>
マニフェストの設定が完了したら、PostgreSQL クラスタをデプロイします。
$ kubectl apply -k kustomize/my-postgres/
PostgreSQL クラスタの状態を確認します。3つの Pod が作成されます。各 Pod が master か replica かはラベルで確認できます。
$ kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/instance-set \ -L postgres-operator.crunchydata.com/role NAME READY STATUS RESTARTS AGE ROLE my-postgres-pg-1-45cl-0 3/3 Running 0 7m14s master my-postgres-pg-1-ctj8-0 3/3 Running 0 7m14s replica my-postgres-pg-1-rgc4-0 3/3 Running 0 7m14s replica
psql による接続確認
Kubernetes クラスタ内のノードから、または他の Pod からは上記の PostgreSQL の Pod に接続できますが、作業環境から psql でアクセスしたい場合は kubectl の port-forward 機能を利用します。
ここでは master Pod の 5432 ポートをローカルの 5432 へポートフォワードを行います。
※ PG_CLUSTER_MASTER_POD には master の Pod 名が入ります。
$ PG_CLUSTER_MASTER_POD=$(kubectl get pod -n postgres-operator -o name -l postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/role=master)
$ kubectl -n postgres-operator port-forward "${PG_CLUSTER_MASTER_POD}" 5432:5432 &
psql で接続します。testuser ユーザの情報を格納する Secret からデータベースの接続情報を取得します。
$ PG_CLUSTER_USER_SECRET_NAME=my-postgres-pguser-testuser
$ PGPASSWORD=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.password | base64decode}}') \
PGUSER=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.user | base64decode}}') \
PGDATABASE=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.dbname | base64decode}}') \
psql -h localhost
Handling connection for 5432
psql (14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-ECDSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
testdb=> \du+
List of roles
Role name | Attributes | Member of | Description
--------------+------------------------------------------------------------+-----------+-------------
_crunchyrepl | Replication | {} |
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} |
testuser | | {} |
次に、postgres スーパーユーザで接続し、レプリケーションの状態を確認します。
$ PG_CLUSTER_USER_SECRET_NAME=my-postgres-pguser-postgres
$ PGPASSWORD=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.password | base64decode}}') \
PGUSER=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.user | base64decode}}') \
psql -h localhost
Handling connection for 5432
psql (14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-ECDSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=# select application_name, state, sync_state from pg_stat_replication;
application_name | state | sync_state
-------------------------+-----------+------------
my-postgres-pg-1-rgc4-0 | streaming | sync
my-postgres-pg-1-ctj8-0 | streaming | async
(2 rows)
PostgreSQL の設定
PostgreSQL のパラメータは spec.patroni.dynamicConfiguration.postgresql.parameters で設定します。
例えば、log_statement: all の設定を追加して適用すると、自動的に PostgreSQL に反映されます。
vi kustomize/my-postgres/postgres.yaml
(以下を追加)
spec:
patroni:
dynamicConfiguration:
synchronous_mode: true
postgresql:
parameters:
log_statement: all
$ kubectl apply -k kustomize/my-postgres/
設定値が変更されていることを確認します。
$ PG_CLUSTER_MASTER_POD=$(kubectl get pod -n postgres-operator -o name -l postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/role=master)
$ kubectl exec ${PG_CLUSTER_MASTER_POD} -n postgres-operator -it -- psql
Handling connection for 5432
psql (14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-ECDSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=# show log_statement;
log_statement
---------------
all
(1 row)
ただし、PostgreSQL の Pod の再起動が必要になるパラメータもあります。
例えば、max_connections の設定値を変更した場合、Pod の再起動が必要になります。
以下のコマンドを実行し、アノテーションを編集することで、PGO が自動的に変更を検出し、1つずつ Pod の再起動を行います。
$ kubectl patch postgrescluster/my-postgres -n postgres-operator --type merge \
--patch '{"spec":{"metadata":{"annotations":{"restarted":"'"$(date)"'"}}}}'
フェイルオーバー
PostgreSQL の master Pod に故障が発生した場合は、自動的にフェイルオーバーしていずれかの replica が master に昇格します。また、定義した「あるべき状態」を満たすために、新たな replica が起動します。この節では、PGO のフェイルオーバーの動作を検証してみます。
まず、master Pod を削除します。
$ PG_CLUSTER_MASTER_POD=$(kubectl get pod -n postgres-operator -o name -l postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/role=master)
$ kubectl delete ${PG_CLUSTER_MASTER_POD} -n postgres-operator
pod "my-postgres-pg-1-45cl-0" deleted
すると、replica Pod「my-postgres-pg-1-ctj8-0」が master に昇格し、旧 master Pod が replica として再起動されることを確認できます。
$ kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/instance-set \ -L postgres-operator.crunchydata.com/role NAME READY STATUS RESTARTS AGE ROLE my-postgres-pg-1-45cl-0 3/3 Running 0 74s replica my-postgres-pg-1-ctj8-0 3/3 Running 0 52m master my-postgres-pg-1-rgc4-0 3/3 Running 0 52m replica
スケーリング
スケーリングとは、replica を追加または削除することです。
PostgreSQL クラスタに replica を追加することをクラスタのスケールアップ、クラスタから replica を削除することをクラスタのスケールダウンといいます。
スケーリングすることにより、データベースの負荷分散や耐障害性の向上を実現できます。
YAML ファイルの replicas の数を変更し、適用するだけで、簡単にクラスタのスケールアップ/スケールダウンを行えます。
以下のように replicas の数を 3 から 4 に変更して適用すると、新しい replica Pod が起動します。
$ vi kustomize/my-postgres/postgres.yaml
(replicas を 3 から 4 に変更)
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: my-postgres
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-14.2-0
postgresVersion: 14
instances:
- name: pg-1
replicas: 4
(省略)
$ kubectl apply -k kustomize/my-postgres/
新しい replica が起動することを確認します。
$ kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/instance-set \
-L postgres-operator.crunchydata.com/role
NAME READY STATUS RESTARTS AGE ROLE
my-postgres-pg-1-2fzw-0 3/3 Running 0 27s replica
my-postgres-pg-1-45cl-0 3/3 Running 0 8m14s replica
my-postgres-pg-1-ctj8-0 3/3 Running 0 59m master
my-postgres-pg-1-rgc4-0 3/3 Running 0 59m replica
$ PG_CLUSTER_MASTER_POD=$(kubectl get pod -n postgres-operator -o name -l postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/role=master)
$ kubectl exec ${PG_CLUSTER_MASTER_POD} -n postgres-operator -it -- psql
Handling connection for 5432
psql (14.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-ECDSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=# select application_name, state, sync_state from pg_stat_replication;
application_name | state | sync_state
-------------------------+-----------+------------
my-postgres-pg-1-45cl-0 | streaming | async
my-postgres-pg-1-rgc4-0 | streaming | sync
my-postgres-pg-1-2fzw-0 | streaming | async
(3 rows)
元の設定に戻したい場合には、replicas の数を 4 から 3 に減らすと、いずれかの replica Pod が削除されます。
$ vi kustomize/my-postgres/postgres.yaml
(replicas を 4 から 3 に変更)
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: my-postgres
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-14.2-0
postgresVersion: 14
instances:
- name: pg-1
replicas: 3
(省略)
$ kubectl apply -k kustomize/my-postgres/
replica Pod が削除されていることを確認します。
$ kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/instance-set \ -L postgres-operator.crunchydata.com/role NAME READY STATUS RESTARTS AGE ROLE my-postgres-pg-1-45cl-0 3/3 Running 0 15m replica my-postgres-pg-1-ctj8-0 3/3 Running 0 67m master my-postgres-pg-1-rgc4-0 3/3 Running 0 67m replica
ボリュームサイズの拡張
Kubernetes では、ボリュームの拡張が許可される場合のみ、既存の永続ボリューム (PV) のサイズを拡張できます。ボリュームの拡張を許可するかはストレージクラスの allowVolumeExpansion 属性で設定します。
ボリュームの拡張を行う前に、デプロイ済みの PostgreSQL クラスタが利用しているストレージクラスの allowVolumeExpansion の設定値が true であることを確認します。
$ kubectl get sc pgo NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE pgo kubernetes.io/aws-ebs Retain Immediate true 97m
PV と PVC のサイズを確認します。
$ kubectl get pv,pvc -n postgres-operator NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-04060f68-9590-4af1-a341-2dd8e1b42055 10Gi RWO Delete Bound postgres-operator/my-postgres-repo1 pgo 91m persistentvolume/pvc-1e13602d-1455-46b7-bfb0-7dee549ac70f 10Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-rgc4-pgdata pgo 91m persistentvolume/pvc-4dde75fe-c392-4f75-b483-326dcd6e5d46 10Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-45cl-pgdata pgo 91m persistentvolume/pvc-ff62508e-e743-482d-a67b-19726c075c2c 10Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-ctj8-pgdata pgo 91m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/my-postgres-pg-1-45cl-pgdata Bound pvc-4dde75fe-c392-4f75-b483-326dcd6e5d46 10Gi RWO pgo 91m persistentvolumeclaim/my-postgres-pg-1-ctj8-pgdata Bound pvc-ff62508e-e743-482d-a67b-19726c075c2c 10Gi RWO pgo 91m persistentvolumeclaim/my-postgres-pg-1-rgc4-pgdata Bound pvc-1e13602d-1455-46b7-bfb0-7dee549ac70f 10Gi RWO pgo 91m persistentvolumeclaim/my-postgres-repo1 Bound pvc-04060f68-9590-4af1-a341-2dd8e1b42055 10Gi RWO pgo 91m
PostgreSQL のデータ保存用の PVC とバックアップ保存用の PVC の要求サイズを 20GB に変更してみます。
$ vi kustomize/my-postgres/postgres.yaml
(省略)
spec:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:centos8-14.2-0
postgresVersion: 14
instances:
- name: pg-1
replicas: 3
dataVolumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 20Gi
storageClassName: pgo
backups:
pgbackrest:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 20Gi
storageClassName: pgo
(省略)
$ kubectl apply -k kustomize/my-postgres/
PVC と PV のサイズが拡張されていることを確認します。
$ kubectl get pv,pvc -n postgres-operator NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-04060f68-9590-4af1-a341-2dd8e1b42055 20Gi RWO Delete Bound postgres-operator/my-postgres-repo1 pgo 103m persistentvolume/pvc-1e13602d-1455-46b7-bfb0-7dee549ac70f 20Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-rgc4-pgdata pgo 103m persistentvolume/pvc-4dde75fe-c392-4f75-b483-326dcd6e5d46 20Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-45cl-pgdata pgo 103m persistentvolume/pvc-ff62508e-e743-482d-a67b-19726c075c2c 20Gi RWO Delete Bound postgres-operator/my-postgres-pg-1-ctj8-pgdata pgo 103m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/my-postgres-pg-1-45cl-pgdata Bound pvc-4dde75fe-c392-4f75-b483-326dcd6e5d46 20Gi RWO pgo 103m persistentvolumeclaim/my-postgres-pg-1-ctj8-pgdata Bound pvc-ff62508e-e743-482d-a67b-19726c075c2c 20Gi RWO pgo 103m persistentvolumeclaim/my-postgres-pg-1-rgc4-pgdata Bound pvc-1e13602d-1455-46b7-bfb0-7dee549ac70f 20Gi RWO pgo 103m persistentvolumeclaim/my-postgres-repo1 Bound pvc-04060f68-9590-4af1-a341-2dd8e1b42055 20Gi RWO pgo 103m
allowVolumeExpansion 機能に対応していないストレージでは、既存の永続ボリュームのサイズを拡張できないため、ボリュームサイズが大きい、新しい PostgreSQL クラスタを作成し、既存のクラスタと同期させる必要があります。詳細についてはこちらを参照してください。
バックアップ
PGO のバックアップ/リストアは内部的に pgBackRest のバックアップ/リストアユーティリティを利用しています。定期的にフルバックアップまたは差分バックアップを取得することができます。バックアップのスケジュールは cron 表記で指定します。
定期バックアップのスケジュールは spec.backups.pgbackrest.repos.schedules で設定します。
例えば、以下のように設定すると、毎日午前1時にフルバックアップ、4時間ごとに差分バックアップを実行するようになります。
$ vi kustomize/my-postgres/postgres.yaml
(省略)
spec:
backups:
pgbackrest:
image: registry.developers.crunchydata.com/crunchydata/crunchy-pgbackrest:centos8-2.36-1
configuration:
- secret:
name: pgo-s3-creds
global:
repo2-path: /pgbackrest/postgres-operator/my-postgres/repo2
repos:
- name: repo1
volume:
volumeClaimSpec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: 10Gi
- name: repo2
schedules:
full: "0 1 * * *"
incremental: "0 */4 * * *"
s3:
bucket: "crunchy-pg-backup"
endpoint: "s3.us-west-2.amazonaws.com"
region: "us-west-2"
(省略)
リストア
PostgreSQL クラスタの複製
PGO v5 では、既存の PostgreSQL クラスタを複製できます。
既存のクラスタを複製するには、spec.dataSource.postgresCluster にコピー元のクラスタ名、バックアップの格納先のリポジトリ名を指定します。
spec:
dataSource:
postgresCluster:
clusterName: my-postgres
repoName: repo2
デフォルトでは最新のデータにリストアしますが、spec.dataSource.postgresCluster.options を指定して、特定の時点までリストア可能です。
spec:
dataSource:
postgresCluster:
clusterName: my-postgres
repoName: repo2
options:
- --type=time
- --target="2022-03-16 14:00:00+09"
既存の PostgreSQL クラスタの PITR
起動中の PostgreSQL クラスタを以前の時点にリストアするには spec.backups.pgbackrest.restore を設定します。既存のデータディレクトリでリストアを実行するので、クラスタが一旦停止され、作成しなおされます。
例えば、2022-03-16 14:00:00 時点までリストアする場合は、以下の手順を実行します。
まず、PostgresCluster リソースを設定する YAML ファイル postgres.yaml を編集し、適用します。
※この時点ではリストアが実行されません。
$ vi kustomize/my-postgres/postgres.yaml
(省略)
spec:
backups:
pgbackrest:
restore:
enabled: true
repoName: repo2
options:
- --type=time
- --target="2022-03-16 14:00:00+09"
(省略)
$ kubectl apply -k kustomize/my-postgres/
次に、PostgresCluster のアノテーションを設定します。
PostgresCluster のアノテーションを設定すると、リストアが実行されます。
$ kubectl annotate postgrescluster my-postgres -n postgres-operator --overwrite \ postgres-operator.crunchydata.com/pgbackrest-restore=id1
リストア完了後、リストアの設定を無効にしておきます。
$ vi kustomize/my-postgres/postgres.yaml
(省略)
spec:
backups:
pgbackrest:
restore:
enabled: false
(省略)
$ kubectl apply -k kustomize/my-postgres/
モニタリング
PGO は Prometheus によるモニタリング機能を提供しています。Kubernetes では Prometheus を利用した監視がよく使われています。Prometheus がクラスタの各種メトリクスを収集し、Grafana と連携して、Grafana のダッシュボードで Kubernetes クラスタと PostgreSQL を監視することができます。
モニタリング機能を利用するために、まず、各 Pod に Exporter サイドカーを追加する必要があります。
$ vi kustomize/my-postgres/postgres.yaml
(省略)
spec:
monitoring:
pgmonitor:
exporter:
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-5.0.5-0
(省略)
$ kubectl apply -k kustomize/my-postgres
$ kubectl get pods -n postgres-operator --selector=postgres-operator.crunchydata.com/cluster=my-postgres,postgres-operator.crunchydata.com/instance-set \
-L postgres-operator.crunchydata.com/role
NAME READY STATUS RESTARTS AGE ROLE
my-postgres-pg-1-45cl-0 4/4 Running 0 3m4s master
my-postgres-pg-1-ctj8-0 4/4 Running 0 3m35s replica
my-postgres-pg-1-rgc4-0 4/4 Running 0 2m14s replica
次に、監視アプリケーション Prometheus、Grafana、Alertmanager をデプロイします。
Amazon EKS のデフォルトのストレージクラス gp2 を利用しても良いですが、今回は前述の手順で作成したストレージクラスを利用します。Prometheus、Grafana、Alertmanager の PVC を定義する YAML ファイルを編集します。
※ デフォルトのストレージクラスを利用する場合は編集不要です。
$ vi kustomize/monitoring/pvcs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app.kubernetes.io/name: pgo-monitoring
vendor: crunchydata
name: alertmanagerdata
spec:
(省略)
storageClassName: pgo
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app.kubernetes.io/name: pgo-monitoring
vendor: crunchydata
name: grafanadata
spec:
(省略)
storageClassName: pgo
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app.kubernetes.io/name: pgo-monitoring
vendor: crunchydata
name: prometheusdata
spec:
(省略)
storageClassName: pgo
Prometheus、Grafana、Alertmanager をデプロイします。
$ kubectl apply -k kustomize/monitoring
Prometheus、Grafana、Alertmanager の Pod が起動していることを確認できます。
$ kubectl get pods -n postgres-operator --selector=app.kubernetes.io/name=postgres-operator-monitoring NAME READY STATUS RESTARTS AGE crunchy-alertmanager-f7b79cbd8-lfv7s 1/1 Running 0 4m47s crunchy-grafana-548446d646-lqw4l 1/1 Running 0 4m45s crunchy-prometheus-556f754797-98lcn 1/1 Running 0 4m44s
作業環境のブラウザから Grafana にアクセスするために、Grafana Pod の 3000 ポートをローカルの 3000 へポートフォワードを行います。
$ GRAFANA_POD=$(kubectl get pod -n postgres-operator -o name -l app.kubernetes.io/name=postgres-operator-monitoring,name=crunchy-grafana)
$ kubectl -n postgres-operator port-forward ${GRAFANA_POD} 3000:3000 &
ブラウザで http://localhost:3000 にアクセスすると、Grafana のログイン画面が表示されます。Grafana のログインユーザ名とパスワードは以下のコマンドで確認できます。
$ kubectl get secret grafana-secret -n postgres-operator -ojsonpath='{.data.username}' | base64 --decode ; echo
$ kubectl get secret grafana-secret -n postgres-operator -ojsonpath='{.data.password}' | base64 --decode ; echo
Grafana にログインし、ダッシュボードで Kubernetes クラスタや PostgreSQL の稼働状況を確認できます。

おわりに
今回は Crunchy Postgres Operator v5 について紹介しました。
インストールや管理方法が大幅に変更され、kubectl が使用できるようになり、以前のバージョンより構築・管理がさらに容易になりました。さらに詳しく知りたい方は、公式ドキュメントをご覧ください。