cgroupsでの実装から理解するcAdvisorのスロットルメトリクスの読み方

2024-09-03

TL; DR;

  • cgroupでは時間を細分化した単位(period)内でプロセスが使っていい時間(quota)を管理している
  • quotaを超えた分がスロットルと扱われる
  • cAdvisorの各メトリクスは以下のような図に示される定義となっている
各メトリクスの図解

背景

kubernetesで監視を行おうとしたとき、意識せずともcAdvisor由来のメトリクスを見ることになると思います。 例えばCPU使用率はprometheusの場合、container_cpu_usage_seconds_totalといったメトリクスで取得することができます。 これには、kubeletがcAdvisorを内包しているからという理由があります(cf. Metrics For Kubernetes System Components)。

そのようなメトリクスの中にはスロットル関係のメトリクスとして、以下のような説明のCounterタイプメトリクスがあります。

# コンテナが実行可能だったperiodの個数
container_cpu_cfs_periods_total
# コンテナがスロットルされたperiodの個数
container_cpu_cfs_throttled_periods_total
# コンテナがスロットルされた時間(秒)
container_cpu_cfs_throttled_seconds_total

cf. cadvisor/docs/storage/prometheus.md at master · google/cadvisor · GitHub

私はこれを最初に見たとき、ナニコレ?と思ったのでこれらのメトリクスの定義を調べてみました。

メトリクスの取得元

cAdvisorのコードをみてみると、これらのメトリクスは、実際にはgolangのruncモジュールのlibcontainer/cgroupsパッケージのThrottlingData型のフィールドから値を取得しています。1 2 このフィールド自体はコンテナが属するcgroupsのcpu.statファイルから値を取得しているようです。3

結果的に、各メトリクスとcpu.statとの対応は以下のようになります。

  • container_cpu_cfs_periods_total:nr_periods
  • container_cpu_cfs_throttled_periods_total:nr_throttled
  • container_cpu_cfs_throttled_seconds_total:throttled_time (v1) / throttled_usec (v2)

つまり、これらのメトリクスの意味を把握するには、cgroupsのperiodやthrottleについて理解すれば良いということになります。

cgroupsのperiodとthrottle

cgroupsでは、時間をperiodという短い区間単位に分割し、その単位内で制限を適用しています。 つまり、periodの中でプロセスが使うことのできる時間はどのくらいかというクオータ(quota)を指定し、クオータを使い切ってなお使おうとしている部分はスロットル(throttle)として扱われるということです。 なお、このクオータはperiodが変わると復活します。

例えば、Periodが100ms・Quotaが60msの場合のcgroupsによるプロセスの制限を図示すると下のようになります。 cgroupsのperiodとthrottleの例

PeriodとQuotaの値はcgroup毎に変えることができ、

というパラメータ(cgroupファイル)で設定できます。 v1・v2のいずれにしてもデフォルトではperiodは100msで、quotaは設定されていません。

なお、クオータはマルチコア環境であってもグローバルなプールとなっているため、quotaがperiodと一致しているからといってCPUを全て利用できるわけではありません。 quotaとperiodが一致していてもスロットルは発生する

また、上の説明では実際に使用した分を積算してクオータを超えていないか判断数という仕組みに見えまるが、実際にそれぞれのプロセスに対して使用量を厳密にトラッキングするのはオーバーヘッドが大きいので、periodをさらに細かく分けたsliceという単位を配分しその使用量で管理されます。

まとめ

以上の説明からに、スロットル関連のメトリクスの取得元・意味は以下のようになります。

  • container_cpu_cfs_periods_total:コンテナが実行可能だったperiodの個数(nr_periods)
  • container_cpu_cfs_throttled_periods_total:コンテナがスロットルされたperiodの個数(nr_throttled)
  • container_cpu_cfs_throttled_seconds_total:コンテナがスロットルされた時間(秒)(throttled_time (v1)・throttled_usec (v2))

また、これらを図示すると以下のようになります。 各メトリクスの図解

参考

Footnotes

  1. cAdvisorによるメトリクス定義部分のコード

  2. cAdvisorメトリクス値のセット部分のコード

  3. cgroup v1 v2でのセット部分のコード

Ads