#8 PostgreSQL on k8sで障害テスト(2) ストレージノード

本記事は[PostgreSQL on Kubernetes Advent Calendar 2018](https://qiita.com/advent-calendar/2018/postgresonk8s)の8日目です。
昨日は「[PostgreSQL on k8sで障害テスト(1) DBノード](https://qiita.com/tzkoba/private/b412ccd0fd3c7f6a4ab4)」ということで、PostgreSQL on Kubernetesの構成でDBノードを落とし、PostgreSQLポッドがどのように扱われるかをテストしてみました。

本日は他の障害ポイントについて、テストをしていきたいと思います。

#TL;DR

+ PostgreSQL on k8sではストレージ（Ceph）障害でもデータベースレイヤに影響はないよ。
+ ストレージノードが起動すれば、Cephが冗長化構成に自動復旧してくれるよ。

#（再掲）障害パターン
昨日と同じ表を載せておきます。
DBノードの障害ケースは昨日整理しましたので、今日はストレージノードの障害から見ていきます。

| 障害分類 | 障害部位      | 想定する動き |
|:-:      |:-:           |:--|
|ノード    |~~DBノード~~      | ~~サービス継続、PostgreSQLフェイルオーバ~~|
|         |ストレージノード| サービス継続、Ceph縮退  |
|ポッド    |PostgreSQL    | サービス停止、PostgreSQLポッド再起動|
|         |Rook.operator | サービス継続、Rookポッド再起動 |
|         |Rook.Agent    | サービス継続、Rookポッド再起動 |
|         |Ceph.MON      | サービス継続、Cephポッド再起動 |
|         |Ceph.OSD      | サービス継続、Cephポッド再起動 |


# テスト(2) ストレージノード障害
今回のPostgreSQL on Kubernetes構成では、分散ストレージのCephをブロックデバイスとして使って3重化によりデータを保護しています。
1台のストレージノード停止でデータを失わないことはもちろん、停止時にPostgreSQLには瞬断等の影響を与えないことがポイントになります。

テスト手順は以下の通りです。

1. pgbenchで3分程度のベンチマークを流す。
2. ストレージサーバ3台のうち、1台を停止。
3. pgbenchは継続されていることを確認。
4. Cephが縮退されている状況を確認。
5. 2.で停止したストレージサーバを起動。
6. Cephが分散ストレージをリカバリする状況を確認

## pgbenchの結果確認
ストレージノード障害のケースは想定どおり、PostgreSQLのサービス継続、Cephレイヤで見ると縮退という状況が確認できました。

まず、pgbenchはベンチ実行中にストレージノードを落としたにもかかわらず、エラーを吐かずに実行を完了しています。

```shell

$ kubectl exec -it pgtools-75fb6bdb95-l859w -c pgbench -- /usr/pgsql-10/bin/pgbench -h pg-rook-sf.default.svc -U bench -c 2 -C -T 180 -l bench
Password:
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 2
number of threads: 1
duration: 180 s
number of transactions actually processed: 15371
latency average = 23.422 ms
tps = 85.388705 (including connections establishing)
tps = 116.845334 (excluding connections establishing)
```


同条件でストレージノードが3台の状態でテストした際は以下の結果でしたので、このベンチマークでは縮退時も大きな差は出ていないように見えます。
詳細な性能については別途検証をしたいと思います。

```shell

# 通常ベンチ(1)
latency average = 21.647 ms
tps = 92.392468 (including connections establishing)
tps = 128.755455 (excluding connections establishing)

# 通常ベンチ(2)
latency average = 22.661 ms
tps = 88.256808 (including connections establishing)
tps = 122.791851 (excluding connections establishing)
```
## Ceph縮退、復旧状況の確認
次にストレージノードを停止した際にCephレイヤではどのように動いていたかを確認しましょう。

### ストレージサーバ1台の停止、Ceph縮退
ceph statusコマンドで状況を確認します。

```shell:ストレージノードの停止中
$ kubectl exec -it -n rook-ceph rook-ceph-tools-57f88967f4-kvvkl ceph status
  cluster:
    id:     4d1dd83e-1735-4241-9c2b-ba91e3e36bd5
    health: HEALTH_WARN
            1 osds down
            1 host (1 osds) down
            no active mgr
            1/3 mons down, quorum b,a
  services:
    mon: 3 daemons, quorum b,a, out of quorum: c
    mgr: no daemons active
    osd: 3 osds: 2 up, 3 in
  data:
    pools:   1 pools, 100 pgs
    objects: 750  objects, 2.6 GiB
    usage:   35 GiB used, 105 GiB / 140 GiB avail
    pgs:     100 active+clean
  io:
    client:   276 KiB/s rd, 2.0 MiB/s wr, 12 op/s rd, 188 op/s wr
```

1つのosd、1つのmon、そしてmgrが停止しています。（mgrが稼動していたノードを落としたため）

また、data: pgsにも注目していきましょう。

### ストレージサーバの起動、リカバリ
では、この状態でストレージサーバを起動するとどうなるでしょうか。
想定する動きとしては、停止していたOSDに必要なデータが同期され、3台構成に完全復帰するはずです。

まず、こちらがストレージノードを起動した直後にceph statusした結果です。
monは3台に復帰、mgrも起動していますが、osdは3台と見えてているものの2up,2inと正常な3台構成にはなっていません。
これはCephクラスタ内でデータをレプリカしているPlacement Group（PG）で異常が見つかっているためです。
（詳しくは[この記事](http://www.atmarkit.co.jp/ait/articles/1412/24/news006_2.html)などを参照）

``` shell:起動・リカバリ直後
$ kubectl exec -it -n rook-ceph rook-ceph-tools-57f88967f4-kvvkl ceph status
  cluster:
    id:     4d1dd83e-1735-4241-9c2b-ba91e3e36bd5
    health: HEALTH_WARN
            Degraded data redundancy: 753/2259 objects degraded (33.333%), 99 pgs degraded, 100 pgs undersized
  services:
    mon: 3 daemons, quorum b,d,a
    mgr: a(active)
    osd: 3 osds: 2 up, 2 in
  data:
    pools:   1 pools, 100 pgs
    objects: 753  objects, 2.6 GiB
    usage:   22 GiB used, 58 GiB / 80 GiB avail
    pgs:     753/2259 objects degraded (33.333%)
             99 active+undersized+degraded
             1  active+undersized
```

しばらく待って再度ceph statusを実行すると、以下のように表示内容が変わりました。
ここでは全てのPGが復旧され、HEALTH_OKとなっています。

```shell:リカバリ完了後
$ kubectl exec -it -n rook-ceph rook-ceph-tools-57f88967f4-kvvkl ceph status
  cluster:
    id:     4d1dd83e-1735-4241-9c2b-ba91e3e36bd5
    health: HEALTH_OK
  services:
    mon: 3 daemons, quorum b,d,a
    mgr: a(active)
    osd: 3 osds: 3 up, 3 in
  data:
    pools:   1 pools, 100 pgs
    objects: 753  objects, 2.6 GiB
    usage:   34 GiB used, 106 GiB / 140 GiB avail
    pgs:     100 active+clean
  io:
    client:   682 B/s wr, 0 op/s rd, 0 op/s wr
    recovery: 1.1 MiB/s, 0 objects/s
```

これでストレージノードの復旧は完了です。

#まとめ
本日は、ストレージノードの障害時にKubernetes on PostgreSQLがどのように動くかをテストしてみました。
DBノードの障害と異なり、こちらは想定どおりの動作となっており、ひとまずは安心です。

検証記事は書くのに時間がかかり、毎日投稿するのは骨が折れるのですが、明日は各ポッドレベルでの障害ケースを見てみたいと思います。

よろしくお願いします。