#21 EBSでも出来るよ-PostgreSQL on k8s-


本記事はPostgreSQL on Kubernetes Advent Calendar 2018の21日目です。

#20として「RancherでKubernetesクラスタ構築」を投稿しましたが、内容に誤りがありました(現在も修正中)。RancherとKubernetes、そしてAWSの関係を理解するに至っておらず、恥ずかしい限りです。

前回の内容は本日のPostgreSQL on EBSをやる準備だったのですが、想定よりも随分シンプルに出来ることが分かったのは大きな収穫でした。改めて、@t-umeさんに感謝致します。

TL;DR

  • PostgreSQL on k8sはEBSでも十分に構築できる。
  • むしろそっちのほうが簡単?
  • 当然ポッドをフェイルオーバさせると、EBSの追随するよ。

PostgreSQL on Kubernetes(EBS)の構成

Rookに変わってEBSをストレージとして使っても、PostgreSQL on Kubernetesのコンセプト自体は変わりません。#2で触れたようにストレージ・レイヤでデータ冗長化を担保するシンプルなDBクラスタ、です。

実はこれ、クラウドストレージを使ってしまえば簡単に出来るのです。
下図はEC2インスタンス上のPostgreSQLコンテナからEBSをマウントした構成になっていますが、図にあるように現在のKubernetesではPodの動きにEBSが追随してくれます。

当然EBSのデータは単一ディスクへの書き込みではありませんし、簡単に消えるということもないため、冗長化もここで担保されます。

前提条件

前回記したようにRancherを使ってKubernetesクラスタを構築しています。そのため、@t-umeさんのこちらの記事を参考にCloud Providerの設定を終えておく必要があります。

更にActive-StandbyのDBクラスタとなりますので、DBノードは2台必要、ストレージノードはEBSなので不要です。

  • DBノード2台、ラベルとしてtype=node.db.postgresを作成しておく

以降では今回のPostgreSQL on Kubernetes(EBS)の構成をPg-EBSと表記してますので、その前提でお読み下さい。

Pg-EBSのインストール

このAdvent Calenderを書きながらgithubもどんどん更新してますので、まずgit cloneしてPg-EBSのディレクトリに移動します。

git cloneとディレクトリ移動
$ git clone https://github.com/tzkoba/postgres-on-k8s.git
$ cd postgres-on-k8s/postgres-install/pg-ebs/

ConfigMapを2つ作成します。

ConfigMapの作成
$ kubectl apply -f pg-ebs-configmap.yaml
$ kubectl apply -f pg-ebs-postgres_conf.yaml

次にEBSを使うためのStorageClassとPersistent Volume Claimを作成して確認します。こちらでRook利用の構成でも書いたように、データ・ディレクトリとアーカイブログ・ディレクトリ用に2つのボリュームを作成しています。

StorageClassとPVCの作成
$ kubectl apply -f pg-ebs-storageclass.yaml
$ kubectl apply -f pg-ebs-sf-pvc.yaml

# 作成状況の確認
$ kubectl get sc,pvc
NAME                                          PROVISIONER             AGE
storageclass.storage.k8s.io/rook-ceph-block   ceph.rook.io/block      1d
storageclass.storage.k8s.io/sc-ebs-001        kubernetes.io/aws-ebs   1d

NAME                                       STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc-pg-ebs-sf        Bound     pvc-ee233cc4-04df-11e9-9405-02ef0b761764   3Gi        RWO            sc-ebs-001     1d
persistentvolumeclaim/pvc-pg-ebs-sf-xlog   Bound     pvc-ee261ebd-04df-11e9-9405-02ef0b761764   2Gi        RWO            sc-ebs-001     1d

上記のStorageClassは中身も見ておきましょう。

pg-ebs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sc-ebs-001
parameters:
  encrypted: "false"
  type: gp2
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Delete

これだけです。provisionerとしてkubernetes.io/aws-ebsを指定し、固有のパラメータを渡しています。

ボリュームの準備が出来ましたので、PostgreSQLのStatefulSetとServiceを作って構築完了です。

StatefulSetとServiceの作成
$ kubectl apply -f pg-ebs-sf.yaml
$ kubectl apply -f pg-ebs-sf-service.yaml

$ kubectl get pod,sts
NAME              READY     STATUS    RESTARTS   AGE
pod/pg-ebs-sf-0   1/1       Running   0          1d

NAME                         DESIRED   CURRENT   AGE
statefulset.apps/pg-ebs-sf   1         1         1d

フェイルオーバさせてみる

では、このDBクラスタがどのように動くかを確認しておきましょう。

最初にStatefulSetによるポッドのデプロイ状況を確認しておきます。

$ kubectl get pod -o wide
NAME          READY     STATUS    RESTARTS   AGE       IP          NODE
pg-ebs-sf-0   1/1       Running   0          1d        10.42.2.2   rke_worker_db02i

AWSのボリュームのマウント状況は以下のようになっており、KubernetesからプロビジョニングされたEBSがrke_worker_db02iというノードにアタッチされています。

では、このポッドをフェールオーバしてStandbyノードに移動させて見ましょう。検証には#15で書いたようにkubectl drainコマンドを使います。

kubectl drainと結果確認
$ kubectl drain rke_worker_db02i --force --ignore-daemonsets
rke_worker_db02i cordoned
WARNING: Ignoring DaemonSet-managed pods: cattle-node-agent-ptr6m, nginx-ingress-controller-sk8j2, canal-nnmlp, rook-ceph-agent-p4qmc, rook-discover-px5n7
pod/pg-ebs-sf-0 evicted

# ポッドが移動したことを確認する
$ kubectl get pod -o wide
NAME          READY     STATUS    RESTARTS   AGE       IP          NODE
pg-ebs-sf-0   1/1       Running   0          3m        10.42.1.7   rke_worker_db01i

ポッドはStandyノード、この際はrke_worker_01iで正常に稼動しています。AWS側でもEBSのアタッチ状況を確認すると以下のようになっています。

PostgreSQLインスタンスの移動に伴って、EBSボリュームが自動的にデタッチ/アタッチされていることが分かるかと思います。

まとめ

これまではPostgreSQL on Kubernetesでは分散ストレージのRookを使った構成を試してきました。今日はEBSを使ったPostgreSQLインスタンスを構築しましたが、これを使って明日は簡単なベンチマージ句を実行し、性能比較をしてみたいと思います。

よろしくお願いします。