Kubegresで任意のユーザ・データベースを作成しておく方法


Kubegresはコンテナ管理を自動化するKubernetesのOperatorのひとつで、PostgreSQLのHAクラスタを構築できるものです。

Kubegresを使ってPodをデフォルト設定で立ち上げると、管理者権限のpostgresユーザとpostgresデータベースが作成された状態でPostgreSQLが起動されます。

本記事では、Podの立ち上げ時に任意の一般ユーザ(user1)およびデータベース(testdb)を作成する方法を紹介します。

また、minikubeで以前にKubegresを立ち上げたことがあると、前回の状態が影響して期待通りに動作しなかったので、その対処方法についても「環境の準備」のところで触れています。

環境の準備

環境は前回の記事と同様にminikubeを使用していて、Kubernetesクラスタを作り直しました。
初めての場合は、「$ minikube start --driver=none」のところから行ってください。

$ minikube delete

Kubegresは初回起動時(データベースディレクトリが存在しない場合)のみ初期化スクリプトが実行される作りになっていて、初期化スクリプトで任意のユーザ・データベースを作成しています。

前回の起動でPersistent Volumeがホストマシン上にマウントされていて、そのデータベースファイルがホストマシン上に残っている場合、それを削除しておく必要があります。そうしないと、初期化スクリプトが動きません。

私の場合は /tmp/hostpath-provisioner ディレクトリ以下にファイルがあったので、それを削除しました。

$ sudo rm -fr /tmp/hostpath-provisioner

どこにマウントされるかはこちらで確認することができます。

その後、minikubeを起動し、Operatorをインストールします。

$ minikube start --driver=none
$ kubectl apply -f https://raw.githubusercontent.com/reactive-tech/kubegres/v1.1/kubegres.yaml

設定ファイルの全体概要

デフォルト設定(あるいは前回記事)では、認証情報を設定するmy-postgres-secret.yamlファイルと、PotgreSQLのインスタンスを設定するmy-postgres.yamlファイルを作成しました。

それに加えて、カスタムの設定を行うmy-postgres-config.yamlファイルを作成します。

デフォルトの設定からこの設定を読み込むようにmy-postgres.yamlを編集し、新たな認証情報はmy-postgres-secret.yamlファイルに追記します。

認証情報の設定ファイルの編集と適用

my-postgres-secret.yamlファイルを編集し、追加するユーザのパスワードを記載します。
編集前のファイルは、こちらの「2) Create a Secret resource」に記載のものを使用します。

末尾にmyDbUserPassword: user1Pswを追記しました。今回作成するユーザのパスワードはuser1Pswということになります。

ファイル内容は以下になります。

apiVersion: v1
kind: Secret
metadata:
  name: mypostgres-secret
  namespace: default
type: Opaque
stringData:
  superUserPassword: postgresSuperUserPsw
  replicationUserPassword: postgresReplicaPsw
  myDbUserPassword: user1Psw

編集後、適用します。

$ kubectl apply -f my-postgres-secret.yaml

カスタム設定ファイルの作成と適用

新たにmy-postgres-config.yamlファイルを作成して適用します。

初期化スクリプトprimary_init_script.shをオーバーライドするものなのですが、このスクリプトの中で、作成するデータベース名testdbとユーザ名user1を指定します。

  1. まず、こちらの「Override primary_init_script.sh」を参考にファイルを作成します。
  2. 次に、customDatabaseNamecustomUserNameの行を編集して、今回作成するデータベース(testdb)とユーザ(user1)を指定します。
  3. さらに、これまで使用してきたnamespaceはdefaultなので、customの部分をdefaultに変更します。

ファイル内容は以下になります。

apiVersion: v1
kind: ConfigMap
metadata:
  name: mypostgres-conf
  namespace: default

data:

  primary_init_script.sh: |
    #!/bin/bash
    set -e

    # This script assumes that the env-var $POSTGRES_MY_DB_PASSWORD contains the password of the custom user to create.
    # You can add any env-var in your Kubegres resource config YAML.

    dt=$(date '+%d/%m/%Y %H:%M:%S');
    echo "$dt - Running init script the 1st time Primary PostgreSql container is created...";

    customDatabaseName="testdb"
    customUserName="user1"

    echo "$dt - Running: psql -v ON_ERROR_STOP=1 --username $POSTGRES_USER --dbname $POSTGRES_DB ...";

    psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE DATABASE $customDatabaseName;
    CREATE USER $customUserName WITH PASSWORD '$POSTGRES_MY_DB_PASSWORD';
    GRANT ALL PRIVILEGES ON DATABASE "$customDatabaseName" to $customUserName;
    EOSQL

    echo "$dt - Init script is completed";

作成後、適用します。

$ kubectl apply -f my-postgres-config.yaml

PotgreSQLインスタンスの設定ファイルの編集と適用

my-postgres.yamlファイルを編集し、これまで行った設定を読み込むようにします。

編集前のファイルは、こちらの「3) Create a cluster of PostgreSql instances」に記載のものを使用します。

2箇所追記します。spec.customConfigの指定と、環境変数POSTGRES_MY_DB_PASSWORDの設定です。以下の内容を追記します。

   customConfig: mypostgres-conf

customConfigの値はmy-postgres-config.yamlファイルで作成したConfigMapオブジェクトの名前mypostgres-confを指定します。

      - name: POSTGRES_MY_DB_PASSWORD
        valueFrom:
           secretKeyRef:
              name: mypostgres-secret
              key: myDbUserPassword

nameにはmy-postgres-secret.yamlファイルで作成したSecretオブジェクトの名前mypostgres-secretを、Keyにはmy-postgres-secret.yamlファイルで追記した項目のキー名myDbUserPasswordを指定します。

最終的にファイル全体の内容は以下になります。

apiVersion: kubegres.reactive-tech.io/v1
kind: Kubegres
metadata:
  name: mypostgres
  namespace: default

spec:

   replicas: 3
   image: postgres:13.2

   database:
      size: 200Mi
      storageClassName: standard

   customConfig: mypostgres-conf

   env:
      - name: POSTGRES_PASSWORD
        valueFrom:
           secretKeyRef:
              name: mypostgres-secret
              key: superUserPassword
      - name: POSTGRES_REPLICATION_PASSWORD
        valueFrom:
           secretKeyRef:
              name: mypostgres-secret
              key: replicationUserPassword
      - name: POSTGRES_MY_DB_PASSWORD
        valueFrom:
           secretKeyRef:
              name: mypostgres-secret
              key: myDbUserPassword

作成後、適用します。

$ kubectl apply -f my-postgres.yaml

これで設定は終わりです。

確認

PostgreSQLに接続してみましょう。

以下のコマンドを実行してPodの状態がRunningになっていることを確認しておきます。

$ kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
mypostgres-1-0   1/1     Running   0          3m      172.17.0.6   hostname   <none>           <none>
mypostgres-2-0   1/1     Running   0          2m46s   172.17.0.7   hostname   <none>           <none>
mypostgres-3-0   1/1     Running   0          2m34s   172.17.0.8   hostname   <none>           <none>

前回の記事同様、アクセス用のPodからpsqlでアクセスしてみます。psqlの引数でユーザ(user1)とデータベース(testdb)を指定します。

$ kubectl exec -it psql-pod -- psql -h mypostgres -U user1 testdb

ここでパスワードを聞かれるので、my-postgres-secret.yamlファイルで追加設定したuser1Pswを入力します。
接続できればOKです。

また、以下のとおりPod内に入って確認することもできます。

$ kubectl exec -it mypostgres-1-0 -- /bin/bash
root@mypostgres-1-0:/# psql -U user1 testdb

おわりに

KubegresでPod立ち上げ時にPostgreSQLの一般ユーザおよびデータベースを作成する方法を紹介しました。

同様の方法でpostgres.confやpg_hba.confを上書きしてPostgreSQLの設定を変更できるので、こちらを参考にしてください。

参考文献

https://www.kubegres.io/
https://kubernetes.io/
https://minikube.sigs.k8s.io/