Kubernetes上で動くサービスの何を監視すればよいのか

# はじめに

サーバーを安定して運用するためには、システムの状態を正確に把握できる監視システムは欠かせません。
従来はVMインスタンスやベアメタルサーバーのリソース使用状況やデータベース、ネットワーク、アプリケーション固有のメトリクスを監視していました。
しかし、近年ではサーバーをKubernetes上で動かすことが当たり前になっており、Kubernetesの恩恵を受ける反面、これまでよりもサーバーの監視は複雑になっているように思えます。
そこで、本記事ではKubernetes上で動くサービスの何を監視すればよいのかを整理していきます。

# TL;DR

- ユーザーの視点から監視システムを設計する
- ユーザー視点のメトリクスから何か問題が起こっていることを知る
- システム内部のメトリクスから原因を探る

# 監視の目的

システムの監視の目的は、ユーザーに快適なサービスを提供できているか、また今後サービスに影響が出そうな問題が発生していないかを事前に検知することです。
リソース使用状況を美しくグラフにしたり、アラートをいたずらに飛ばすことではありません。

# 何を観るか

快適なサービスを提供できているかという観点から、まず観ておきたいのは、ユーザーがサービスと触れる部分のメトリクス(ユーザー目線のメトリクス）です。この部分のメトリクスに異常値が検出されると、何かはわからないがユーザーに不利益が発生していることがわかります。

一方、事前に問題を検知するという観点やトラブルシューティングのことを考えると、システム内部のメトリクスも観ておく必要がありそうです。例えば、実施予定のプロモーションに対して、現時点のリソースでは足りなさそうであれば、事前のプロビジョニングの判断材料にもなります。

## ユーザー目線のメトリクス

ユーザーがサービスと触れる部分のメトリクスとしては、例えば次のようなものがあります。

- レイテンシ(レスポンス時間）
- エラー率

### レイテンシ（レスポンス時間）

レイテンシが平常時より悪化している場合、UXに悪影響を与える上に、それがリソースの枯渇や非効率なクエリによるものであれば最悪の場合は近いうちにサービスダウンも考えられます。
また、95%ileや99%ileのレイテンシは、サービスの利益にとって重要なユーザーによるものかもしれません。これら外れ値のレイテンシを改善することには一定の効果があります。

### エラー率

ユーザーに不利益が発生していることを示す一番わかりやすい指標がエラー率です。
このエラー率が一定のしきい値を超えた場合にアラートを鳴らすことは有益です。


## システム内部のメトリクス

Kubernetesの監視において、大きく分けて次の4つの項目は観るとよいかと思います。

- Kubernetesのコントロールプレーン
- Kubernetesノード
- Kubernetes Workloads
- コンテナのリソース制限に対する使用率

その他、ネットワークやデータベース、アプリケーション固有のメトリクスは本記事では取り扱いません。

### Kubernetesのコントロールプレーン

Kubernetes上でサービスを動かすのであれば、その大元であるKubernetesのコントロールプレーンを監視するべきでしょう。
例えば次の項目[1]を監視することにより、Kubernetesの恩恵を安定して享受することができます。これらのメトリクスはkube-state-metricsによって簡単に収集することが可能です。

- kube-apiserver
- kube-scheduler
- kube-controller-manager
- etcd

### Kubernetesノード

サーバーのPodを稼働させるのに十分なリソースの余裕があるか、過剰なインフラリソースをプロビジョニングしていないかを把握するために、Kubernetesノードのメトリクスは観るべきです。

### Kubernetes Workloads

DeploymentやDaemonSetなどのWorkloadsが適切にデプロイされているかを把握します。
例えば、WebサーバーのPodが本来100デプロイされているはずが、50しかデプロイされていない状況が長く続いているならば、ノードのリソース不足や設定の不備が考えられます。

### コンテナのリソース制限に対する使用率

コンテナがリソース制限を超えるとOOM KillやCPUスロットリングに直面するため、
リソース制限に対する使用率を監視することは重要です。

#### OOM Kill

例えば、Webサーバーのメモリ利用量に100MiBの制限が設けられていると、
OOMセーフガードが起動しコンテナがKillされ、Podが再起動されます。

また、Podはコンテナのリソース要求に基づいてデプロイされます。
そのため、ノードにデプロイされたPodのメモリのリソース制限の合計が、ノードのメモリ容量を超えることがあります（オーバーコミット）。この場合、Kubernetesは一部のPodをKillしメモリを開放します。

#### CPUスロットリング

メモリと違い、CPUの使用量がリソース制限を超えてもPodがKillされることはなく、CPUスロットリングが発生し、サーバーのパフォーマンスに影響がでます。[2]

# おわりに

DeNA では今年、以下の 3種 のアドベントカレンダーを書いてます！それぞれ違った種類なのでぜひ見てみてください。

- [DeNA Advent Calendar 2020](https://qiita.com/advent-calendar/2020/dena)：DeNA エンジニアによるアドベントカレンダー
- [DeNA 20 新卒 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/dena-20-shinsotsu)：DeNA 20 新卒エンジニアによるアドベントカレンダー
- [DeNA 21 新卒 Advent Calendar 2021](https://qiita.com/advent-calendar/2020/dena-21-shinsotsu)：DeNA 21 内定者エンジニアによるアドベントカレンダー

この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ Twitter や facebook、はてなブックマークにてコメントをお願いします！

また [DeNA 公式 Twitter アカウント @DeNAxTech](https://twitter.com/DeNAxTech) では、 Blog記事だけでなく色々な勉強会での登壇資料も発信してます。ぜひフォローして下さい！
<a href=""https://twitter.com/DeNAxTech?ref_src=twsrc%5Etfw"" class=""twitter-follow-button"" data-size=""large"" data-lang=""ja"" data-show-count=""false"">Follow @DeNAxTech</a><script async src=""https://platform.twitter.com/widgets.js"" charset=""utf-8""></script>

# 参考
[1] Datadog, [kubernetes control plane monitoring](https://www.datadoghq.com/ja/blog/kubernetes-control-plane-monitoring/)
[2] kubernetes.io, [Understanding CPU throttling in Kubernetes to improve application performance](https://speakerdeck.com/daikurosawa/understanding-cpu-throttling-in-kubernetes-to-improve-application-performance-number-k8sjp)