LoginSignup
1
1

More than 3 years have passed since last update.

StatefulSet の Production 運用における Tips

Last updated at Posted at 2020-08-13

はじめに

k8sに関する記事や事例は、かなり多くなりました。
しかし、StatefulSet 、Databaseを自前で運用する的な情報は、少ないと思いますので、弊社のStatefulSet の運用について書きます。
まず、これまでの経緯と現在の構成を書きます。
システムは、オンプレをリフトシフトしました。
単純なStraight Conversionでリフトし、その後、Cloudの要素を取り込んでいく、というのがよく言われるBest Practiceだと思います。
しかし、私たちは、リフトシフトを選択しました。
k8sに乗せる、DatabaseをStatefulSetにするというTaskが発生しました。
また、Databaseを、monolithicから数百個のStatefulSetに分散させたことで、逆に巨大なmonolithが誕生しました。

ヘルスチェックは必須

ご存知の通り、Databaseは、とてもSensitiveなので、applyしたから、起動するものではありません。
私たちのシステムも例にもれず、起動(READY)にすることに非常に苦労しました。

  • Daemonが上がっていない
  • Diskのattachmentに失敗している

といったことが頻発しました。数百あるStatefulSetを状態を保つ、という苦悩に。
ここで、ヘルスチェックが必要になってきます。
Databaseが正常に起動しているか、起動していなければshellを起動するという感じで。
プラス、Lifecycleの定義をする。postStartで必ずdaemonを起動させる。

statefulset
        readinessProbe:
          exec:
            command: ["sh", "-c", "/home/readness.sh"]
          initialDelaySeconds: 180
          timeoutSeconds: 2
          failureThreshold: 3
          successThreshold: 2
          periodSeconds: 60
        livenessProbe:
          exec:
            command: ["sh", "-c", "/home/liveness.sh"]
          initialDelaySeconds: 180
          timeoutSeconds: 2
          failureThreshold: 3
          periodSeconds: 60
statefulset
        lifecycle:
          postStart:
            exec:
              command:
              - bash
              - "-c"
              - |
                /home/postStart.sh
          preStop:
            exec:
              command: ["sh", "-c", "/home/preStop.sh;"]

数百のStatefulSetをapplyする

GitOpsは、宣言的に設定することが必要です。
しかし、定期的にAdd/Deleteが発生するStatefulSetを宣言的に管理することは、トイルになります。
そこで、私たちは、Helm ChartsでStateな情報(数百の組織)を管理し、StatefulSetをジェネレートすることにしました。

  1. 組織が増える
  2. values.yamlに組織を追加する

という感じで。
Go言語のTemplate機能でloopする。

Diskの容量を管理する

必要最低限の課金を目指すと思います。
その場合、Disk Fullにならないよう、bufferを考慮して、Diskをcreateする必要があります。
そこで、Prometheusの出番です。予測的に監視することができるため、閾値に入った場合、Slackに通知する。
また、GCPでは、Diskの拡張は、出来ません。従って、Diskの中身を移すため、マイグレーションのpipelineを構築する必要があります。
Argo wfも検討しましたが、ここは、runnerで対応しました。途中で中断した場合に、そこから再開できる点が大きいです。

query
kubelet_volume_stats_used_bytes{instance=~".*pool-a.*"}/1000000000

BCP

ご存知の通り、CloudにおいてもIncidentは、発生します。
東京Regionが使えない、大阪Regionに移す、といったことを想定する必要があります。
ここで大きな問題になるのが、Diskです。
GCPでは、Diskは、zoneごとにcreateするため、RegionでIncidentが発生すると、別のRegionでDiskを用意する必要があります。
ここまで書いてきて、皆さんがDatabaseをStatefulSetを運用しない理由を納得できます。
とにかく、トイルが多い。
対策は、

  • スナップショット
  • Replicationする
  • Object Strageに保存

になると思います。

皆さんの参考になれば幸いです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1