DUICUO

KubernetesコンテナのCPU使用率を正しく計算する方法

パラメータの説明

Prometheusを使用してKubernetes環境でコンテナのCPU使用率を設定すると、CPU使用率が100%を超える状況に遭遇することがよくあります。その理由は次のとおりです。

1. コンテナスペックCPU期間
コンテナに CPU 制限が課せられると、コンテナ CPU クロック サイクルとも呼ばれる CFS スケジューリング時間ウィンドウは通常 100,000 マイクロ秒になります。

2. コンテナスペックCPUクォータ
これは、コンテナが使用するCPU時間の合計サイクル数を指します。クォータが700,000に設定されている場合、コンテナは7 * 100,000マイクロ秒のCPU時間しか使用できないことを意味します。これは通常、Kubernetesのresource.cpu.limitsの値に相当します。

3. コンテナスペックCPUシェア
これは、コンテナに割り当てられたホストCPUの相対値を指します。例えば、「share」が500mに設定されている場合、ウィンドウの開始時にホストノードに0.5CPU(50,000マイクロ秒)を要求することを意味します。これは通常、Kubernetesの「resource.cpu.requests」の値に相当します。

4.コンテナのCPU使用時間(秒)合計
コンテナのCPU使用率を1秒あたり統計的に分析します。コンテナのすべてのコアが対象となります。

5.コンテナのCPUシステム合計秒数
コンテナカーネルモードでの1秒以内のCPU消費量の統計分析

6.コンテナ_CPU_ユーザー_秒数_合計
コンテナユーザー空間における1秒以内のCPU消費量の統計分析

公式ドキュメントを参照してください: https://docs.signalfx.com/en/latest/integrations/agent/monitors/cadvisor.html および https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md

特定の式

1. デフォルトでは、container_cpu_usage_seconds_total を直接使用すると、次のようになります。

 sum(irate(container_cpu_usage_seconds_total{container="$Container",instance="$Node",pod="$Pod"}[5m])*100)by(pod)

デフォルトの統計データは、このコンテナ内のすべてのコアの平均使用率です。


2. 各コンテナの CPU 使用率を正確に計算するには、次のように % 形式を使用します。

 sum(irate(container_cpu_usage_seconds_total{container="$Container",instance="$Node",pod="$Pod"}[5m])*100)by(pod)/sum(container_spec_cpu_quo ta{container="$Container",instance="$Node",pod="$Pod"}/container_spec_cpu_period{container="$Container",instance="$Node",pod="$Pod"})b​​y(pod)

container_spec_cpu_quota と container_spec_cpu_period の比率は、コンテナ内のコアの数を表します。


2. 公式の git の問題を参照してください。
https://github.com/google/cadvisor/issues/2026#issuecomment-415819667

docker 統計

docker stats によって出力されるメトリック列の計算方法は次のとおりです。

まず、docker stats は Docker API /containers/(id)/stats インターフェースを通じてライブ データ ストリームを取得し、それを docker stats を通じて統合します。

Linux の docker stats によって出力されるメモリ使用量 (MEM USAGE) 列には、実際にはキャッシュされたメモリは含まれません。

Docker バージョン 19.03 および 19.03 では、API インターフェース出力のキャッシュ使用量に対応するフィールドは memory_stats.total_inactive_file ですが、Docker 19.03 以降のバージョンでは、対応するフィールドは memory_stats.cache です。

docker stats の出力における PIDS 列は、コンテナによって作成されたプロセスまたはスレッドの数を表します。スレッドは Linux カーネルの用語で、軽量プロセスやカーネルタスクとも呼ばれます。

1. Docker API を使用してコンテナ リソースの使用率を表示する方法は、次のとおりです。

 $ curl -s --unix -socket /var/run/docker.sock "http://localhost/v1.40/containers/10f2db238edc/stats" | jq -r
{
「読み取り」 : 「2022-01-05T06:14:47.705943252Z」
"先読み" : "0001-01-01T00:00:00Z" ,
「pids_stats」 : {
「現在」 : 240
},
「blkio_stats」 : {
「io_service_bytes_recursive」 : [
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「読む」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「書き込み」
「値」 : 917504
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」「同期」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「非同期」
「値」 : 917504
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」「破棄」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
"op" : "合計" ,
「値」 : 917504
}
],
「io_serviced_recursive」 : [
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「読む」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「書き込み」
「値」 : 32
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「同期」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」 : 「非同期」
「値」 : 32
},
{
「メジャー」 : 253
「マイナー」 : 0
「op」「破棄」
「値」 : 0
},
{
「メジャー」 : 253
「マイナー」 : 0
"op" : "合計" ,
「値」 : 32
}
],
"io_queue_recursive" : [],
"io_service_time_recursive" : [],
"io_wait_time_recursive" : [],
"io_merged_recursive" : [],
"io_time_recursive" : [],
「セクター再帰」 : []
},
"num_procs" : 0 ,
「ストレージ統計」 : {},
「CPU統計」 : {
「CPU使用量」 : {
「合計使用量」 : 251563853433744
「CPU使用率」 : [
22988555937059
6049382848016
22411490707722
5362525449957
25004835766513
6165050456944
27740046633494
6245013152748
29404953317631
5960151933082
29169053441816
5894880727311
25772990860310
5398581194412
22856145246881
5140195759848
],
"カーネルモードでの使用法" : 30692640000000 ,
「ユーザーモードでの使用状況」 : 213996900000000
},
"システムCPU使用量" : 22058735930000000 ,
"オンラインCPU" : 16
「throttling_data」 : {
「ピリオド」 : 10673334
「スロットル期間」 : 1437
「スロットル時間」 : 109134709435
}
},
"precpu_stats" : {
「CPU使用量」 : {
"total_usage" : 0 ,
"カーネルモードでの使用法" : 0 ,
「ユーザーモードでの使用法」 : 0
},
「throttling_data」 : {
「期間」 : 0
"throttled_periods" : 0 ,
"スロットル時間" : 0
}
},
「メモリ統計」 : {
「使用法」 : 8589447168
「最大使用量」 : 8589926400
「統計」 : {
"active_anon" : 0
"アクティブファイル" : 260198400
「キャッシュ」 : 1561460736
「汚い」 : 3514368
「階層メモリ制限」 : 8589934592
"階層メモリ制限" : 8589934592 ,
"inactive_anon" : 6947250176 ,
"非アクティブファイル" : 1300377600 ,
"マップされたファイル" : 0 ,
「pgfault」 : 3519153
"pgmajfault" : 0 ,
「pgpgin」 : 184508478
「pgpgout」 : 184052901
「RSS」 : 6947373056
"rss_huge" : 6090129408
"total_active_anon" : 0 ,
"total_active_file" : 260198400 ,
"total_cache" : 1561460736
「合計ダーティ」 : 3514368
"total_inactive_anon" : 6947250176 ,
"total_inactive_files" : 1300377600 ,
"total_mapped_file" : 0 ,
"total_pgfault" : 3519153
"total_pgmajfault" : 0 ,
"total_pgpgin" : 184508478
"total_pgpgout" : 184052901
"total_rss" : 6947373056
"total_rss_huge" : 6090129408 ,
"total_unevictable" : 0 ,
"total_writeback" : 0 ,
「追放不能」 : 0 ,
「書き戻し」 : 0
},
「制限」 : 8589934592
},
「名前」 : 「/k8s_prod-xc-fund_prod-xc-fund-646dfc657b-g4px4_prod_523dcf9d-6137-4abf-b4ad-bd3999abcf25_0」
「id」 : 「10f2db238edc13f538716952764d6c9751e5519224bcce83b72ea7c876cc0475」

2. 正式な住所の計算方法
https://docs.docker.com/engine/api/v1.40/#operation/コンテナ統計

​precpu_stats​前回の読み取りにおけるCPU統計情報であり、CPU使用率の計算に使用されます。これは​cpu_stats​フィールドの正確なコピーではありません。
​precpu_stats.online_cpus​​​​​ または​cpu_stats.online_cpus​いずれかが nil の場合、古いデーモンとの互換性のため、対応する​cpu_usage.percpu_usage​​​​​ 配列の長さを使用する必要があります。
docker cli ツールの​stats​コマンドによって表示される値を計算するには、次の式を使用できます。

  • used_memory = ​memory_stats.usage - memory_stats.stats.cache​
  • 利用可能なメモリ = ​memory_stats.limit​
  • メモリ使用量 % = ​(used_memory / available_memory) * 100.0​
  • cpu_delta = ​cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage​
  • system_cpu_delta = ​cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage​
  • number_cpus = ​lenght(cpu_stats.cpu_usage.percpu_usage)​​​ または​cpu_stats.online_cpus​
  • CPU使用率 % = ​(cpu_delta / system_cpu_delta) * number_cpus * 100.0​