はじめに
説明
Cloud Native PostgreSQL(CNP)とはEDB社の提供しているPostgreSQLのKubernates Operatorになります。
Kubernates Operatorを初耳の方も多いと思いますが、一言で申しますとクラスタ管理・構築ツールになります。
今回は1.50から加わったpg_basebackupを使ってVMからベースバックアップを取得し、CNPを構築させる方法を記載します
構築所要時間
30分程度を想定しております。
前提
CNPの構築や操作は最低限の記載となりますので、詳しくは初回の記事を参考にして下さい。
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の方法が提供されているのはうれいしいですね。
ここまでお読みいただき、ありがとうございました!