本記事は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 https://github.com/tzkoba/postgres-on-k8s.git
$ cd postgres-on-k8s/postgres-install/pg-ebs/
ConfigMapを2つ作成します。
$ kubectl apply -f pg-ebs-configmap.yaml
$ kubectl apply -f pg-ebs-postgres_conf.yaml
次にEBSを使うためのStorageClassとPersistent Volume Claimを作成して確認します。こちらでRook利用の構成でも書いたように、データ・ディレクトリとアーカイブログ・ディレクトリ用に2つのボリュームを作成しています。
$ 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は中身も見ておきましょう。
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を作って構築完了です。
$ 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 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インスタンスを構築しましたが、これを使って明日は簡単なベンチマージ句を実行し、性能比較をしてみたいと思います。
よろしくお願いします。