Kotaro7750's Gehirn
Home About
  • Home
  • Category
  • About

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(cf. CFS Bandwidth Control — The Linux Kernel documentation)
    • period:cpu.cfs_period_usでマイクロ秒単位で指定。デフォルトは100ms
    • quota:cpu.cfs_quota_usでマイクロ病で指定。デフォルトで-1(制限なし)
  • cgroup v2(cf. Control Group v2 — The Linux Kernel documentation)
    • period:cpu.maxの2番目の値でマイクロ秒単位で指定。デフォルトは100ms
    • quota:cpu.maxの1番目の値でマイクロ秒単位で指定。デフォルトはmax(制限なし)

というパラメータ(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))

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

参考

  • 第53回 Linuxカーネルのコンテナ機能 - cgroup v2から使うCPUの帯域幅制限(1) | gihyo.jp
  • 第54回 Linuxカーネルのコンテナ機能 ―cgroup v2から使うCPUの帯域幅制限(2) | gihyo.jp
  • KubernetesのResource Requests & Resource Limitsの内部処理をソースコードレベルで読み解く - inductor’s blog
  • Site Unreachable
  • CPU Throttling - Unthrottled: How a Valid Fix Becomes a Regression
  • CPU Throttling - Unthrottled: Fixing CPU Limits in the Cloud
  • KubernetesのOOMとCPUスロットリング – Sysdig
  • Using Prometheus to Avoid Disasters with Kubernetes CPU Limits | Containers
  • CFS Bandwidth Control — The Linux Kernel documentation
  • Understanding CPU throttling in Kubernetes to improve application performance #k8sjp - Speaker Deck

Footnotes

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

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

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

Related Posts

スケーラブルなOpenTelemetry CollectorパイプラインをKubernetes上に構築する

スケーラブルなOpenTelemetry CollectorパイプラインをKubernetes上に構築する

2025-04-14

OpenTelemetry Certified Associate ( OTCA ) を取得した

OpenTelemetry Certified Associate ( OTCA ) を取得した

2025-04-13

KorbでKubernetesの既存PVのStorage Classを変更する

KorbでKubernetesの既存PVのStorage Classを変更する

2024-12-15

New Posts

スケーラブルなOpenTelemetry CollectorパイプラインをKubernetes上に構築する

スケーラブルなOpenTelemetry CollectorパイプラインをKubernetes上に構築する

2025-04-14

OpenTelemetry Certified Associate ( OTCA ) を取得した

OpenTelemetry Certified Associate ( OTCA ) を取得した

2025-04-13

Golangのnet/httpの実装からHTTP1.1クライアントでのTCPコネクションの挙動を確かめる

Golangのnet/httpの実装からHTTP1.1クライアントでのTCPコネクションの挙動を確かめる

2025-03-21

ToC

  • TL; DR;
  • 背景
  • メトリクスの取得元
  • cgroupsのperiodとthrottle
  • まとめ
  • 参考
  • Footnotes

Ads

Ads

Privacy Policy