はじめに
説明
Cloud Native PostgreSQL(CNP)とはEDB社の提供しているPostgreSQLのKubernates Operatorになります。Kubernates Operatorを初耳の方も多いと思いますが、一言で申しますとクラスタ管理・構築ツールになります。
今回は1.50から加わったpg_basebackupを使ってVMからベースバックアップを取得し、CNPを構築させる方法を記載します。
構築所要時間
30分程度を想定しております。
前提
CNPの構築や操作は最低限の記載となりますので、詳しくは「Cloud Native PostgreSQLを構築してログインにチャレンジ」のブログを参考にして下さい。
CNPをインストール
下記を参考にcluster-exampleというクラスタを作成します。
$ kubectl apply -f \ https://get.enterprisedb.io/cnp/postgresql-operator-1.7.1.yaml $ cat cluster-example.yaml apiVersion: postgresql.k8s.enterprisedb.io/v1 kind: Cluster metadata: name: cluster-example spec: instances: 2 primaryUpdateStrategy: unsupervised storage: size: 1Gi $ kubectl apply -f cluster-example.yaml
作成されたことを確認します。
$ kubectl get pod NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 42m cluster-example-2 1/1 Running 0 42m
テスト用のテーブルを作成し、データを入れます。
$ kubectl exec -it cluster-example-1 -- /binb/ash $ psql pqsl# create table japan ( id serial primary key, pref text, city text ); pqsl# INSERT INTO japan ( pref , city ) VALUES ( '東京都', '八王子市' ), ( '東京都', '立川市' ), ( '東京都', '武蔵野市' ), ( '東京都', '三鷹市' ), ( '東京都', '青梅市' ), ( '東京都', '府中市' ), ( '東京都', '昭島市' ), ( '東京都', '調布市' ), ( '東京都', '小金井市' ), ( '東京都', '小平市' ), ( '東京都', '日野市' ), ( '東京都', '東村山市' ), ( '東京都', '国分寺市' ), ( '東京都', '国立市' ), ( '東京都', '福生市' ), ( '東京都', '狛江市' ), ( '東京都', '東大和市' ), ( '東京都', '清瀬市' ), ( '東京都', '東久留米市' ), ( '東京都', '武蔵村山市' ), ( '東京都', '多摩市' ), ( '東京都', '稲城市' ), ( '東京都', '羽村市' ), ( '東京都', 'あきる野市' ), ( '東京都', '西東京都市' );
接続ユーザを設定します。
$ psql# CREATE ROLE streaming_replica LOGIN REPLICATION PASSWORD 'password'; pqsl# \q
今回pg_hba.confを編集しないのは、CNPの場合はデフォルトで設定されているためです。また、この設定のため証明書が必須となっております。
cat /var/lib/postgresql/data/pgdata/pg_hba.conf # Grant local access local all all peer map=local # Require client certificate authentication for the streaming_replica user hostssl postgres streaming_replica all cert clientcert=1 hostssl replication streaming_replica all cert clientcert=1 hostssl app app all md5 # Otherwise use md5 authentication host all all all md5
証明書準備
まずシークレット一覧を確認します。
$ kubectl get secret NAME TYPE DATA AGE cluster-example-app kubernetes.io/basic-auth 3 43m cluster-example-ca Opaque 2 43m cluster-example-replication kubernetes.io/tls 2 43m cluster-example-server kubernetes.io/tls 2 43m cluster-example-superuser kubernetes.io/basic-auth 3 43m cluster-example-token-4mbv7 kubernetes.io/service-account-token 3 43m default-token-9k729 kubernetes.io/service-account-token 3 4h18m
シークレットの中身を確認し、証明書が設定されていることを確認します。
$ kubectl get secret cluster-example-replication -o yaml apiVersion: v1 data: tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJuRENDQVVLZ0F3SUJBZ0lRWHZJcUcydmhJOEdpeDFsRG5WUFdRakFLQmdncWhrak9QUVFEQWpBc01SQXcKRGdZRFZRUUxFd2RrWldaaGRXeDBNUmd3RmdZRFZRUURFdzlqYkhWemRHVnlMV1Y0WVcxd2JHVXdIaGNOTWpFdwpPREUzTVRFeE1USTNXaGNOTWpFeE1URTFNVEV4TVRJM1dqQWNNUm93R0FZRFZRUUREQkZ6ZEhKbFlXMXBibWRmCmNtVndiR2xqWVRCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkU4cEVtK1dOSk84bTZJRjUxZTUKVEw2azAxOHRmLzRsV3hPclB3KytuT1lSeGNLRVYvUzdBYnVKV1RRa2FrRkZwb2N6MkdLMTl2OWkrSnNoUnFWOApnMG1qVmpCVU1BNEdBMVVkRHdFQi93UUVBd0lEaURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQU1CZ05WCkhSTUJBZjhFQWpBQU1COEdBMVVkSXdRWU1CYUFGSlJJZ2dYdlBaVVBWdXVIajRQdUVPWDFoVVBlTUFvR0NDcUcKU000OUJBTUNBMGdBTUVVQ0lGN0J6Z1gvN2VDSHBFRHBqN0FEVk0vczdPVmUxSmJTSXVMRWdwbVdNWlhOQWlFQQpxUlBweksyR0w4QXdiakszNEg2UjUvY3BIdzhMVnBRRnNZZlJiaCtLTFFVPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== tls.key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUVLOTBndzM3ajJpb2xBMi9YSmNqYjNPcHdlcWlzaTBrNEZVZ25VeEQvbEZvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFVHlrU2I1WTBrN3lib2dYblY3bE12cVRUWHkxLy9pVmJFNnMvRDc2YzVoSEZ3b1JYOUxzQgp1NGxaTkNScVFVV21oelBZWXJYMi8yTDRteUZHcFh5RFNRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= kind: Secret metadata: creationTimestamp: "2021-08-17T11:16:27Z" name: cluster-example-replication namespace: default ownerReferences: - apiVersion: postgresql.k8s.enterprisedb.io/v1 controller: true kind: Cluster name: cluster-example uid: c4eced4b-4387-49ec-a74e-5adb0f636faf resourceVersion: "37816" uid: 134cea5f-fe5f-4a91-b372-2548e4cc6e53 type: kubernetes.io/tls
今回は既存のシークレットを使用しますが、新規で作成する場合は後述のclone.yaml通りですと下記コマンドで設定を行います。
$ kubectl create secret generic cluster-example-replication \ --from-literal=tls.key=xxxxxxx \ --from-literal=tls.crt=xxxxxxx
接続用のパスワードを設定します。
$ kubectl create secret generic source-db-replica-user \ --from-literal=password=password
レプリケーションによる複製作成
設定ファイルを作成します。
$ cat clone.yaml apiVersion: postgresql.k8s.enterprisedb.io/v1 kind: Cluster metadata: name: cluster-restore spec: instances: 2 primaryUpdateStrategy: unsupervised bootstrap: pg_basebackup: source: cluster-example storage: size: 5Gi externalClusters: - name: cluster-example connectionParameters: host: cluster-example-rw user: streaming_replica sslmode: require password: name: source-db-replica-user key: password sslKey: name: cluster-example-replication key: tls.key sslCert: name: cluster-example-replication key: tls.crt
設定を反映し、Podが遷移するのを確認します。エラーの場合は、kubectl logs cluster-restore-1-pgbasebackup-hwllzのように確認していきます。
$ kubectl apply -f clone.yaml $ kubectl get pod NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 145m cluster-example-2 1/1 Running 0 144m cluster-restore-1-pgbasebackup-hwllz 0/1 Init:0/1 0 7s $ kubectl get pod NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 146m cluster-example-2 1/1 Running 0 145m cluster-restore-1 0/1 Init:0/1 0 9s cluster-restore-1-pgbasebackup-hwllz 0/1 Completed 0 35s
無事、通常の起動と同じになれば完了です。
$ kubectl get pod NAME READY STATUS RESTARTS AGE cluster-example-1 1/1 Running 0 147m cluster-example-2 1/1 Running 0 146m cluster-restore-1 1/1 Running 0 71s cluster-restore-2 1/1 Running 0 25s
動作確認
DBが複製されていることを確認します。
$ kubectl exec -it cluster-restore-1 -- /bin/bash $ psql psql# select * from japan; id | pref | city ----+-----------+----------------- 1 | 東京都 | 八王子市 2 | 東京都 | 立川市 3 | 東京都 | 武蔵野市 4 | 東京都 | 三鷹市 5 | 東京都 | 青梅市 6 | 東京都 | 府中市 7 | 東京都 | 昭島市 8 | 東京都 | 調布市 9 | 東京都 | 小金井市 10 | 東京都 | 小平市 11 | 東京都 | 日野市 12 | 東京都 | 東村山市 13 | 東京都 | 国分寺市 14 | 東京都 | 国立市 15 | 東京都 | 福生市 16 | 東京都 | 狛江市 17 | 東京都 | 東大和市 18 | 東京都 | 清瀬市 19 | 東京都 | 東久留米市 20 | 東京都 | 武蔵村山市 21 | 東京都 | 多摩市 22 | 東京都 | 稲城市 23 | 東京都 | 羽村市 24 | 東京都 | あきる野市 25 | 東京都 | 西東京都市 (25 rows)
あとがき
CNPはPodでPostgreSQLの設定を変更しても戻ってしまうため、pg_basebackupの方法が提供されているのはうれいしいですね。
ここまでお読みいただき、ありがとうございました!