VMware SQL with Postgres for Kubernetes 2.1 をインストールする

# はじめに
VMware SQL with Postgres for Kubernetes は、k8s環境で動作するDBaaS製品。パブリッククラウドのマネージドに近いことをオンプレミス環境で実現できる。

公式Docs
https://docs.vmware.com/en/VMware-SQL-with-Postgres-for-Kubernetes/2.1/vmware-postgres-k8s/GUID-index.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359374/e23a461b-4f1e-9f1b-2522-d79ebd3a9da2.png)
引用元：https://docs.vmware.com/en/VMware-SQL-with-Postgres-for-Kubernetes/2.1/vmware-postgres-k8s/GUID-high-availability.html

# 環境
- vCenter/ESXi：7.0u3
- k8s：v1.27.3
- VMware SQL with Postgres for Kubernetes：2.1

# 事前準備
- Helm3 インストール
    - 公式ドキュメントを参考に https://helm.sh/docs/intro/install/
- Tanzu Network Registry のアカウント作成
- default の StorageClass を作成
    - 今回はNFSを使ったのでこれ [nfs-subdir-external-provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner)


# Postgres Operator インストール
クイックスタートの [operator-install-script.bash](https://docs.vmware.com/en/VMware-SQL-with-Postgres-for-Kubernetes/2.1/vmware-postgres-k8s/GUID-quick-start-script.bash) を使ってインストールした。
最後に`VMware Postgres Operator v2.1.0 installed successfully.`と出力されればインストール完了しているようだ。
作成されたOperatorリソースは以下。
```
[root@k8s-master ~]# kubectl api-resources --api-group=sql.tanzu.vmware.com
NAME                      SHORTNAMES   APIVERSION                NAMESPACED   KIND
postgres                  pg           sql.tanzu.vmware.com/v1   true         Postgres
postgresbackuplocations                sql.tanzu.vmware.com/v1   true         PostgresBackupLocation
postgresbackups                        sql.tanzu.vmware.com/v1   true         PostgresBackup
postgresbackupschedules                sql.tanzu.vmware.com/v1   true         PostgresBackupSchedule
postgresrestores                       sql.tanzu.vmware.com/v1   true         PostgresRestore
postgresversions                       sql.tanzu.vmware.com/v1   false        PostgresVersion
```

# Postgres インスタンスのデプロイ
### Namespace作成
```
[root@k8s-master ~]# kubectl create ns k8s-postgres
namespace/k8s-postgres created

//コンテキストでのデフォルト Namespace を変更する
[root@k8s-master ~]# kubectl config set-context --current --namespace=k8s-postgres
Context "kubernetes-admin@kubernetes" modified.
```

### Secret作成
```
kubectl create secret --namespace=k8s-postgres docker-registry regsecret \
   --docker-server=https://registry.tanzu.vmware.com \
   --docker-username="${USERNAME}" \
   --docker-password="${PASSWORD}"
```

### Postgresインスタンス作成
[Tanzu Network](https://network.tanzu.vmware.com/products/tanzu-sql-postgres) の postgres-for-kubernetes-v2.1.0.tar.gz を展開するとyamlのサンプルがある。デフォルトはシングル構成となっていたが、せっかくなのでHAを有効とするように修正した。

https://gist.github.com/tadashota212/549a379de4e1701af1a466bf964d4ef0

```
[root@k8s-master ~]# kubectl apply -f postgres.yaml
postgres.sql.tanzu.vmware.com/postgres-sample configured
```

インスタンスのステータスをチェックして、正常にインスタンスが作成されたことを確認する。
```
[root@k8s-master ~]# kubectl get postgres/postgres-sample
NAME              STATUS    DB VERSION   BACKUP LOCATION   AGE
postgres-sample   Running   15.3                           37m
```

リソースはこのように作成されている。
```
[root@k8s-master ~]# kubectl get all
NAME                            READY   STATUS    RESTARTS   AGE
pod/postgres-sample-0           5/5     Running   0          38m
pod/postgres-sample-1           5/5     Running   0          31m
pod/postgres-sample-monitor-0   4/4     Running   0          40m

NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/postgres-sample             ClusterIP   10.96.236.16     <none>        5432/TCP   40m
service/postgres-sample-agent       ClusterIP   None             <none>        <none>     40m
service/postgres-sample-read-only   ClusterIP   10.103.214.222   <none>        5432/TCP   40m

NAME                                       READY   AGE
statefulset.apps/postgres-sample           2/2     38m
statefulset.apps/postgres-sample-monitor   1/1     40m

NAME                                            STATUS    DB VERSION   BACKUP LOCATION   AGE
postgres.sql.tanzu.vmware.com/postgres-sample   Running   15.3                           40m
```
構成としてはこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359374/148cd6f4-4383-dc6b-9b81-a0a8d98b2e82.png)

# 動作確認
HA 構成を使用している場合、プライマリ ポッドに接続している。どのポッドがプライマリまたはセカンダリであるかはコマンドで確認できる。
```
[root@k8s-master ~]# kubectl exec pod/postgres-sample-0 -- pg_autoctl show state
  Name |  Node |                                                                   Host:Port |       TLI: LSN |   Connection |      Reported State |      Assigned State
-------+-------+-----------------------------------------------------------------------------+----------------+--------------+---------------------+--------------------
node_1 |     1 | postgres-sample-0.postgres-sample-agent.k8s-postgres.svc.cluster.local:5432 |   1: 0/3000148 |   read-write |             primary |             primary
node_2 |     2 | postgres-sample-1.postgres-sample-agent.k8s-postgres.svc.cluster.local:5432 |   1: 0/3000148 |    read-only |           secondary |           secondary
```
Podへ接続してみる。
```
// psqlで接続
[root@k8s-master ~]# kubectl exec -it postgres-sample-0 -- psql
Defaulted container "pg-container" out of: pg-container, instance-logging, reconfigure-instance, postgres-metrics-exporter, postgres-sidecar
psql (15.3 (VMware Postgres 15.3.0))
Type "help" for help.

postgres=# \l
                                                                          List of databases
      Name       |           Owner           | Encoding | Collate |  Ctype  | ICU Locale | Locale Provider |                    Access privileges
-----------------+---------------------------+----------+---------+---------+------------+-----------------+---------------------------------------------------------
 postgres        | postgres                  | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | postgres=CTc/postgres                                  +
                 |                           |          |         |         |            |                 | pgautofailover_monitor=c/postgres                      +
                 |                           |          |         |         |            |                 | postgres_exporter=c/postgres
 postgres-sample | pgautofailover_replicator | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | pgautofailover_replicator=CTc/pgautofailover_replicator+
                 |                           |          |         |         |            |                 | postgres_exporter=c/pgautofailover_replicator          +
                 |                           |          |         |         |            |                 | pgappuser=CTc/pgautofailover_replicator                +
                 |                           |          |         |         |            |                 | pgrouser=c/pgautofailover_replicator                   +
                 |                           |          |         |         |            |                 | pgrwuser=c/pgautofailover_replicator
 template0       | postgres                  | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres                                            +
                 |                           |          |         |         |            |                 | postgres=CTc/postgres
 template1       | postgres                  | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres                                            +
                 |                           |          |         |         |            |                 | postgres=CTc/postgres
(4 rows)

postgres=#

//コンテナのシェル取得
[root@k8s-master ~]# kubectl get pod postgres-sample-0 -o jsonpath="{.spec.containers[*].name}"
pg-container instance-logging reconfigure-instance postgres-metrics-exporter postgres-sidecar[
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl exec -it postgres-sample-0 -c pg-container -- bash
postgres@postgres-sample-0:/$
postgres@postgres-sample-0:/$ id
uid=1001(postgres) gid=1001(postgres) groups=1001(postgres)
```