オンプレ、VMからCNPへのレプリケーションによる複製作成(パスワード編)方法

はじめに

説明

Cloud Native PostgreSQL(CNP)とはEDB社の提供しているPostgreSQLのKubernates Operatorになります。Kubernates Operatorを初耳の方も多いと思いますが、一言で申しますとクラスタ管理・構築ツールになります。

今回は1.50から加わったpg_basebackupを使ってVMからベースバックアップを取得し、CNPを構築させる方法を記載します。

構築所要時間

30~60分程度を想定しております。

前提

CNPの構築や操作は最低限の記載となりますので、詳しくは「Cloud Native PostgreSQLを構築してログインにチャレンジ」のブログを参考にして下さい。

VMにPostgreSQLを構築

インストール

VMにPostgreSQLをインストールします。RHEL系は下記より手順を入手すると楽です。

$ dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
$ dnf -qy module disable postgresql
$ dnf install -y postgresql13-server

環境構築

リストア用のRoleを作成します。

$ sudo su - postgres
$ psql
psql# CREATE ROLE streaming_replica LOGIN REPLICATION PASSWORD 'password';

テスト用のテーブルを作成し、データを入れます。CNPに合わせてappユーザにしてます。

psql#  CREATE ROLE app LOGIN REPLICATION CREATEDB PASSWORD 'password';
psql# create database app;
psql# \q
$ exit
$ psql -U app -h 127.0.0.1
app# create table japan ( id serial primary key, pref text, city text );
app# INSERT INTO japan
  ( pref , city ) 
VALUES
  ( '東京都', '八王子市' ),
  ( '東京都', '立川市' ),
  ( '東京都', '武蔵野市' ),
  ( '東京都', '三鷹市' ),
  ( '東京都', '青梅市' ),
  ( '東京都', '府中市' ),
  ( '東京都', '昭島市' ),
  ( '東京都', '調布市' ),
  ( '東京都', '小金井市' ),
  ( '東京都', '小平市' ),
  ( '東京都', '日野市' ),
  ( '東京都', '東村山市' ),
  ( '東京都', '国分寺市' ),
  ( '東京都', '国立市' ),
  ( '東京都', '福生市' ),
  ( '東京都', '狛江市' ),
  ( '東京都', '東大和市' ),
  ( '東京都', '清瀬市' ),
  ( '東京都', '東久留米市' ),
  ( '東京都', '武蔵村山市' ),
  ( '東京都', '多摩市' ),
  ( '東京都', '稲城市' ),
  ( '東京都', '羽村市' ),
  ( '東京都', 'あきる野市' ),
  ( '東京都', '西東京都市' );
app# \q

接続用にpg_hbaファイルを編集します。md5が標準の場合などは都度変更されて下さい。

$ echo host replication all all scram-sha-256 >> /var/lib/pgsql/13/data/pg_hba.conf
$ echo host all app all scram-sha-256 >> /var/lib/pgsql/13/data/pg_hba.conf
$ cat /var/lib/pgsql/13/data/pg_hba.conf

設定ファイルを編集、確認します。

$ vi /var/lib/pgsql/13/data/postgresql.conf
listen_addresses = '*'

wal_level = replica
$ exit

PostgreSQLの設定を反映し、接続のIPと待受ポートを確認します。

$ sudo systemctl restart postgresql-13
$ ip a
$ ss -natp

CNPを構築

CNPをインストール

ここからはk8s側の操作になります。下記を参考にインストールを行います。

$ kubectl apply -f \
  https://get.enterprisedb.io/cnp/postgresql-operator-1.7.1.yaml

接続ユーザのパスワードを設定します。

$ kubectl create secret generic source-db-replica-user \
  --from-literal=password=password

レプリケーションによる複製作成

ストリーミングレプリケーションによるコピー用のyamlを設定します。

{“level”:”info”,”ts”:1629194105.9210694,”msg”:”DB not available, will retry”,”err”:”pq: SSL is not enabled on the server”}

上記のエラーが発生する場合後日記載するSSL設定で接続するか、sslmode: disableを有効にして下さい。

$ cat clone.yaml
apiVersion: postgresql.k8s.enterprisedb.io/v1
kind: Cluster
metadata:
  # 起動するクラスタ名
  name: cluster-restore 
spec:
  instances: 2
  primaryUpdateStrategy: unsupervised

  bootstrap:
    pg_basebackup:
      # externalClusters:と同じ名前であれば自由
      source: cluster

  storage:
    size: 5Gi

  externalClusters:
  - name: cluster
    connectionParameters:
      host: 接続先IPないしはホスト名
      user: 接続ユーザ名
      #sslmode: disable
    password:
      # 1つ前の手順で設定したsecret名
      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-9s9kxのように確認していきます。

$ kubectl apply -f clone.yaml
$ kubectl get pod
NAME                                   READY   STATUS     RESTARTS   AGE
cluster-restore-1-pgbasebackup-9s9kx   0/1     Init:0/1   0          10s
$ kubectl get pod
NAME                                   READY   STATUS      RESTARTS   AGE
cluster-restore-1                      0/1     Init:0/1    0          1s
cluster-restore-1-pgbasebackup-9s9kx   0/1     Completed   0          43s

無事、通常の起動と同じになれば完了です。

$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
cluster-restore-1   1/1     Running   0          30m
cluster-restore-2   1/1     Running   0          29m

動作確認

DBが複製されていることを確認します。

$ kubectl exec -it cluster-restore-1 -- /bin/bash
$ psql                                 
postgres=# \c app
app=# \dt
       List of relations
 Schema | Name  | Type  | Owner
--------+-------+-------+-------
 public | japan | table | app
(1 row)
app=# 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の方法が提供されているのはうれいしいですね。次回の内容は証明書を使った複製を行います。

ここまでお読みいただき、ありがとうございました!