はじめに
こんにちは!
本記事は「本気で学ぶKubernetes」シリーズの第24回です。このシリーズでは、Kubernetesの基礎から実践まで、段階的に学んでいきます。
このシリーズは、第1回から順に読むことで体系的に学べる構成にしています。
まだご覧になっていない方は、ぜひ最初からご覧ください!
今回はSRE(Site Reliability Engineering)の視点からGKE運用における責任分界と信頼性設計について考えていきたいと思います。
この記事は人間がKubernetesの公式ドキュメントやGoogleのSRE Bookを読み漁りながら書いていますのでご安心ください!
TL;DR
忙しい方のために要点だけ図示しておきます!
この記事で扱うこと・扱わないこと
今回は技術的な実装よりも、運用設計の考え方を整理することに重点を置きます。
そのためこれまでのシリーズで触れてきたProbeやHPA、Prometheus/Grafana、GitOpsといった技術をどのように信頼性設計に活かすのかという視点で見ていきます。
またこの記事では組織論やSREチーム論には踏み込みませんので、あくまで「何を自動化し、どこから人が責任を持つのか」という境界線を明確にすることをゴールとします。
SREとは何か
SREはソフトウェアエンジニアリングのアプローチの1つで、ツールを活用しながらアプリケーション監視やシステムの管理を自動化していくというものと広く語られます。
SREの本質は信頼性を運用ではなく機能とみなして設計で担保することにあります。
人間が毎回判断しなくてもよい状態を作り、壊れる前提でシステムを設計するのがSREの考え方です。
KubernetesにおけるSREについて
Kubernetesは複雑なリソースからなる分散システムともいえます。
PodやDeployment、Service、Ingress、HPAなどなどたくさんのリソースが連携して動いています。
Kubernetes「動かす」だけなら知識の組み合わせでできますが、実際に本番環境で安定稼働させるには信頼性を設計する必要があります。これはどんなシステムの運用においても同じだと思います。
今回はその設計の考え方を整理していきたいと思います。
GKEにおける責任分界
まずGKEを使う際「Google Cloudが責任を持つ範囲」と「利用者が責任を持つ範囲」を理解しておくことが何よりも重要になります。
Google Cloudが責任を持つ範囲
GKEでは、Control Plane(API Server、Scheduler、Controller Manager、etcd)の管理をGoogle Cloudが行ってくれます。
具体的には以下のような部分です。
- Control Planeの可用性
- マスターノードの冗長化
- クラスタ自体の健全性
- セキュリティパッチの適用
- Kubernetesバージョンのアップデート対応
自前で全てKubernetesクラスタを構築した場合はControl Planeの冗長化を行なったり、監視やバックアップなどを行う必要があるため、それなりの運用負荷がかかってきます。
これをGoogle Cloudが責任を持って管理してくれるのがGKEを使うメリットともいえます。
利用者が責任を持つ範囲
一方でそれ以外の以下の部分は利用者側の責任になります。
- DeploymentやService自体の設計
- アプリケーションの挙動やバグ、パフォーマンス問題
- RequestsやLimitsなどのリソース設計
- HPA設定などのスケーリング戦略
- SLOの定義と監視
インフラ部分の管理負担は大きく減っていますがアプリケーション層の責任自体は変わりませんので、信頼性設計は利用者自身が行なっていく必要があります。
Autopilot vs Standard の責任分界の違い
AutopilotとStandardではどこまでをGoogle Cloudが管理し、どこから利用者が責任を持つかが大きく異なりますので確認しておきます。
それぞれのモードについては以下の記事でも触れているのでぜひご覧ください!
【本気で学ぶKubernetes】GKE入門 - Google Kubernetes Engineを始める
| 項目 | Autopilot | Standard |
|---|---|---|
| Control Plane | Google Cloud | Google Cloud |
| ノードのプロビジョニング | Google Cloud(自動) | 利用者 |
| ノードのスケーリング | Google Cloud(自動) | 利用者(Cluster Autoscaler設定) |
| ノードのアップグレード | Google Cloud(自動) | 利用者(タイミング選択可) |
| ノード障害時の対応 | Google Cloud(自動交換) | 利用者(設定次第) |
| リソース最適化 | Google Cloud(未使用リソース自動削減) | 利用者 |
| マシンタイプ選択 | 不可(Google Cloudが最適化) | 利用者(自由に選択) |
| Preemptible VM / Spot VM | 不可 | 利用者(選択可能) |
| Pod設計(Requests/Limits) | 利用者 | 利用者 |
| アプリケーション設計 | 利用者 | 利用者 |
| SLO定義と監視 | 利用者 | 利用者 |
Autopilotでは「ノード層」の管理をGoogle Cloudが担当し、Standardでは利用者が責任を持ちます。
そのためAutopilotは「インフラ層の運用負荷を最小化したい」場合に適していて、Standardは「細かくコントロールしたい」「コストを最適化したい」場合に適していることがわかりますね。
Autopilot が向いているケース
- KubernetesやGoogle Cloudのインフラ運用に精通した人がいない
- ノード管理に時間を使いたくない
- アプリケーション開発に集中したい
- GKEの標準的な可用性で十分で、厳密なSLOを求められない
Autopilotではノード障害が起きても自動的に新しいノードが追加されるようになっているため、人が夜中に起こされることはありません。
Standard が向いているケース
- GPU、大容量メモリなど特殊なノード構成が必要
- Preemptible VMやSpot VMの活用などコストを細かく最適化したい
- ノードレベルでのカスタマイズが必要
Standardではノード障害時に自動復旧の設定をしていないと、手動での対応が必要になる場合が出てきます。
Autopilotは運用負荷を減らしつつ信頼性を確保できるが、Standardは細かくコントロールできる分、設定ミスや運用ミスのリスクも増えます。
どちらを選ぶかはチームの運用体制やSLOから逆算して決めるべきかなと思います。
特に初期構築の際にKubernetesに関して十分な知見があるから、「なんとなく」でStandardを選んでしまうと、後々から管理運用で大変になってしまうということも可能性としてはあります。
SLI / SLO / Error Budget をどう考えるか
SRE視点で信頼性を語る上で欠かせないのが、SLI、SLO、Error Budgetの概念になります。
- SLI(Service Level Indicator):何を測定するか
- SLO(Service Level Objective):どこまで許容するか
- Error Budget:どのくらいの障害を許容するか
SLIについて
SLIはサービスの信頼性を測る指標です。
具体的には以下のような指標が測定を行っていきます。
- HTTP成功率:2xxレスポンス
- レイテンシ:50パーセンタイル、95パーセンタイル、99パーセンタイル
- エラーレート:5xxレスポンス
- 可用性:アプリケーションが応答できる状態かどうか
上記に挙げた指標はPrometheusで計測することができます。
以前の記事でPrometheus/Grafanaを導入についてまとめておりますのでぜひご覧ください!
【本気で学ぶKubernetes】PrometheusとGrafanaで始めるメトリクス監視
SLOについて
SLOは「どこまで許容するか」を定めた目標値になります。
これはビジネス要件から逆算して「HTTP成功率99.9%を維持する」「レイテンシのP95が200ms以下」といった形で設定して、その目標を満たすように冗長化やフェイルオーバーの仕組みを導入したりなどを設計していきます。
当然、目標設定が過剰になり過ぎてしまうと開発速度や運用コスト自体にも跳ねてきます。
Error Budgetについて
Error BudgetはSLOから逆算した「許容できる障害の量」です。
例えばSLOが99.9%とした場合、1ヶ月のうち43.2分は障害が許容される計算になります。
この考え方の重要なポイントは、障害ゼロは目標ではないということです。
どんなシステムにおいても障害をゼロにすることはほぼほぼ不可能なため、あらかじめError Budgetを設定しておきます。
許容量に収まっているうちはシステムの改善より新機能開発を優先させたり、逆にError Budgetを使い切った場合は信頼性改善に注力させていきます。
これらが決まることで初めて、ビジネス要件に合致したHPAやProbeなどの設定、冗長化やフェイルオーバーなどのインフラ自体の設計を進めていくことができます。
監視とアラートの考え方
PrometheusやGrafanaで監視を導入したあとは、「どのメトリクスを監視してアラートを出すか」という部分も重要です。
不要なメトリクスまでアラートを設定していまうと大量の通知が来てしまい、本当に重要なアラートを見逃してしまうという可能性も考えられます。
アラートを設定する際の判断軸として以下のものが挙げられます。
- 自動復旧できるものは通知させない
- Podが一時的にクラッシュしてLiveness Probeで再起動された場合(これは自動復旧できているので通知不要)
- SLOを割りそうな場合のみ通知する
- 「エラーレートが5%を超えた」「レイテンシのP95が500msを超えた」といった条件に場合
- アクション可能なアラートだけを設定
- HPAがスケールアウトできずにリソース不足になっている場合
高可用性と冗長化について
Kubernetesはコンテナ環境で自動修復機能を活用しながら安全で安定したシステム運用をしていきたいという、高可用性を求めるユーザーに好まれるプラットフォームとして上位に入る選択肢だと思います。
GKE自体はそもそもリージョナルクラスタで利用できるので標準でマルチAZ構成として運用でき、Control Planeに関していえばGoogle Cloud側が冗長化構成で担保してくれています。
GKE上で動作させるPodのレプリカ数も増やすほど冗長性は高まりますが、コストとトレードオフにあんりますのでSLOに基づいて適切に設計していきましょう。
一般的なシステムで多く求められる「99.9%のSLO」なら、GKEの標準的な冗長化で十分なケースが多いかなと思います。
より厳しく99.9%のSLOが求められる場合に複数リージョンやマルチクラスター構成を検討していけば良いですね。
障害時に人が介入するライン
Kubernetesは強力な自己修復能力を持っていますが、対応し切れない場面もありますのでどこからどこまでを人間が対応すべきなのかはあらかじめ明確にしておく必要があります。
自動で対応するもの
以下のようなケースは、Kubernetesが自動で対応してくれますので基本は人間の介入は不要です。
- Liveness Probeで異常を検知してPodを再起動
- Deployment Controllerが指定されたレプリカ数を維持するためにPodを再作成
- ノードの障害時におけるノード復旧をするか、別のノードにPodが再スケジュールを行う
- HPAによって自動的にPod数を調整
人間が介入するもの
一方、以下のようなケースは人間の判断のもと介入が必要になってきます。
- 自動復旧が追いつかず、ビジネスに影響が出ている場合(SLOを割っている場合)
- 新しいバージョンのデプロイが何度も失敗している
- バグ、メモリリーク、無限ループなどアプリケーション設計起因の障害
- RequestsやLimitsの不適切な設定でリソース不足になっている場合
人間が介入するラインを事前に文書で決めておくことで、無駄なアラートを減らすことができますし、有事の際にも迅速に対応ができるようになると思います。
通知に関しても「Podが1回再起動された」という際は不要ですが、「Podが5分間に3回再起動された」という状況は明らかに問題が発生していそうと推測できるので通知を飛ばすように設定した方が良いですね。
SRE視点で見るGitOpsの価値
前回の記事でGitOpsについて触れましたが、SRE視点で見るとGitOpsは信頼性を守るための仕組みです。
SREではいかにソフトウェアエンジニアリングを活用して、人間の介入する余地を減らして効率化していくかという観点が重要になるので、自動でKubernetes環境に設定を反映していけるGitOpsとは相性が良いと思います。
以前紹介したArgo CDはGitリポジトリとクラスタの実際の状態を比較して差分を検知した上で、自動的にGitリポジトリの状態に戻すと言ったことができます。
【本気で学ぶKubernetes】GitOpsでKubernetesを宣言的に管理する!Argo CDに入門してみる
すべての変更はGitコミットを経由することになるので、いつ誰が変更したかを特定するのが容易ですし、不具合が起きた場合も以前のバージョンに戻すことも容易です。
GitOpsによる変更管理の自動化やレビュープロセス標準化、ロールバック、変更履歴の追跡自体がそのままシステムとしての信頼性を向上させるということにもつながっていきます。
まとめ
今回はSRE視点でGKE運用の責任分界と信頼性設計について整理しました。
GKEを使えばControl Planeの管理負担は大きく減りますが、アプリケーション層の責任は変わりませんので、いかに信頼性を設計していくかという点が重要になります。
ビジネス要件から逆算して、「どこまでを設計や運用で担保し」「どこまでを人間が対応するか」などのラインを明確にしておくことで、より堅牢なシステムを構築することができるのはないでしょうか。
ぜひこれからKubernetesやGKEを運用していく際はSRE観点を意識してください!
次回はシリーズ最終回として、あえてKubernetesを使わない選択肢とは何かというテーマで触れていきたいと思います。
それでは、また次回!
