#4 PostgreSQL on Kubernetesのインストール

本記事は[PostgreSQL on Kubernetes Advent Calendar 2018](https://qiita.com/advent-calendar/2018/postgresonk8s)の4日目です。
昨日は「["Rook" Up & Running](https://qiita.com/tzkoba/private/0c2d6f92bc18c6549117)」ということで、分散ストレージRookの環境を構築してみました。

既にお気付きの通り、今回の**PostgreSQL on Kubernetes 2018（全部俺）**はいわば連載モノです。
そのため、前回のように単発で見ると「PostgreSQL関係ないじゃん！」という回もあったりしますが、前後を通して見てみると何をしているのか理解して頂けるかと思います。

# TL;DR
+ 公式のpostgresイメージを使って、Rook上にデータベースを構築してみる。
+ RookのStorageClassを使って、PVは動的に割り当てよう。

# PostgreSQL on Kubernetesの構成
昨日は下図の下半分部分、Rookの環境構築をしてみました。
![pg-rook-archi.PNG](https://qiita-image-store.s3.amazonaws.com/0/54853/7ca6f87a-02f6-c121-c2e4-f4a0040df52f.png)

本日は上半分のPostgreSQLのStatefulSetを構築していきます。
改めてKubernetesクラスタ内に以下の6ノードが必要です。

+ 2台のDBサーバ。Kubernetes上でラベルとして、type=node.db.postgres が付いていること
+ 3台のストレージサーバ。Kubernetes上でラベルとして、type=node.st.rook が付いていること
+ 1台のツール用サーバ。Kubernetes上でラベルとして、type=node.mon.bench が付いていること

## PostgreSQLのインストール
[#3](https://qiita.com/tzkoba/private/0c2d6f92bc18c6549117#up--running)でクローンしたものと同じリポジトリを使い、pg-rookのディレクトリに移動します。

```
$ cd ./postgres-on-k8s/postgres-install/pg-rook
```

### ConfigMapの作成
今回は[公式のPostgreSQLのDockerイメージ](https://hub.docker.com/_/postgres/)を使っています。
リンク先にあるとおり、起動時の環境変数が設定できますがConfigMapで以下を指定してます。

+ POSTGRES_USER
+ POSTGRES_PASSWORD
+ POSTGRES_DB

さらにpostgresql.confを外部から与えるためにもう一つのConfigMap(pg-rook-postgresql_conf.yaml)を作成してあります。
では、2つのConfigMapを作成しましょう。

```
$ kubectl apply -f pg-rook-configmap.yaml
configmap/postgres-config created
$ kubectl apply -f pg-rook-postgresql_conf.yaml
configmap/postgres-conf configured
```
pg-rook-configmap.yamlはパスワードを含んでいますのでSecretsのほうが良いと思いますが、今回はお試しということで。

### Persistent Volume Claimの作成
PostgreSQL on Rookの構成ではPersistent Volumeの作成はRookに任せるため、PVCでは第3回で作成したStorageClassを使います。
今回はデータディレクトリ（PGDATA）とアーカイブログ用のディレクトリを別のPVとして作成しています。

```
$ kubectl apply -f pg-rook-sf-pvc.yaml
persistentvolumeclaim/pvc-pg-rook-sf created
persistentvolumeclaim/pvc-pg-rook-sf-xlog created

$ kubectl get pvc
NAME                  STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
pvc-pg-rook-sf        Bound     pvc-bdbc6e53-f6e9-11e8-b0d9-02f062df6b48   3Gi        RWO            rook-ceph-block   14m
pvc-pg-rook-sf-xlog   Bound     pvc-bdbf23a5-f6e9-11e8-b0d9-02f062df6b48   2Gi        RWO            rook-ceph-block   14m

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                          STORAGECLASS      REASON    AGE
pvc-bdbc6e53-f6e9-11e8-b0d9-02f062df6b48   3Gi        RWO            Delete           Bound     default/pvc-pg-rook-sf         rook-ceph-block             14m
pvc-bdbf23a5-f6e9-11e8-b0d9-02f062df6b48   2Gi        RWO            Delete           Bound     default/pvc-pg-rook-sf-xlog    rook-ceph-block             14m
```

### StatefulSetの作成
最後にPostgreSQLのStatefulSetを作成します。
当構成ではPostgreSQLのReplicasは1のため、用いる意味はない気もするのですが、Headless Serviceも作成しておきます。

```
$ kubectl apply -f pg-rook-sf.yaml
statefulset.apps/pg-rook-sf created

$ kubectl apply -f pg-rook-sf-service.yaml
service/pg-rook-sf created
```

構築作業はこれでおしまいです。

### 何が構築されたか？
今回検証するPostgreSQL on RookはActive-Standby構成をStatefulSetで実現しようとしていますので、起動されるPostgreSQLのポッドは常に一つです。
また、PostgreSQLのバージョンは10.4を指定しています。

```
$ kubectl get sts,pod -o wide
NAME                          DESIRED   CURRENT   AGE       CONTAINERS   IMAGES
statefulset.apps/pg-rook-sf   1         1         40m       pg-rook-sf   postgres:10.4

NAME                           READY     STATUS    RESTARTS   AGE       IP           NODE
pod/pg-rook-sf-0               1/1       Running   0          40m       10.42.5.56   ip-172-31-15-204
```

さらにCeph側から見るとPVに対応したイメージが作成されていることも分かります。

```
$ kubectl exec -it -n rook-ceph rook-ceph-tools-57f88967f4-kvvkl rbd ls replicapool
pvc-bdbc6e53-f6e9-11e8-b0d9-02f062df6b48
pvc-bdbf23a5-f6e9-11e8-b0d9-02f062df6b48

$ kubectl exec -it -n rook-ceph rook-ceph-tools-57f88967f4-kvvkl rbd info replicapool/pvc-bdbc6e53-f6e9-11e8-b0d9-02f062df6b48
rbd image 'pvc-bdbc6e53-f6e9-11e8-b0d9-02f062df6b48':
        size 3 GiB in 768 objects
        order 22 (4 MiB objects)
        id: 115926b8b4567
        block_name_prefix: rbd_data.115926b8b4567
        format: 2
        features: layering
        op_features:
        flags:
        create_timestamp: Mon Dec  3 10:54:00 2018
```

rbd ls コマンドで表示されるのはイメージ名ですが、それが上でkubectl get pvで確認したVOLUME名と同じになっていますね。

# まとめ
第3回で構築した分散ストレージの上にPostgreSQLをインストールしました。

今後の検証でCephのコマンドを使う機会も多くあるため、あえてRook/Cephレベルでの確認内容も多く取り入れてみましたがどうだったでしょうか。

明日以降はこれまでに構築したPostgreSQLに接続し、様々なユースケースを想定した操作を試していきます。
よろしくお願いします。