はじめに
Kubernetesでは以下のようにlimitsというフィールドがあり
$ kubectl explain pod.spec.containers.resources.limits KIND: Pod VERSION: v1 FIELD: limits <map[string]string>
メモリやCPUリソースに制限を与えることができます。
今回はその中でもCPUに焦点を当て、Podの使用するCPUを抑制する「CPU throttling」の動きを発生させてみました。
コンテナへのリミット
例えばPodのYAMLに以下のように書かれていると
spec: containers: ... resources: limits: cpu: 300m request: cpu: 100m
リクエストとしてNodeに空きが100mないとPodはスケジュールされません。そしてリミットとしては300mが記載されているので、それを越えようとするとスロットリングと呼ばれるリソースの抑制にコンテナ基盤が動きます。
ちなみに、この抑制はNode全体としては余裕があった場合でも発動する点は注意が必要です。
CPUスロットリングの発生時の挙動
実際に特定のPodに対して負荷掛けを行いました。Podの負荷は以下コマンドにて
$ kubectl top pod xx -n xx
CPUとメモリの値が取得できるので
xx 63m 123Mi
負荷をかけ続けると以下のようにLimitである300mで値が高止まりしています。
14:05:07 xx 63m 123Mi 14:05:19 xx 63m 123Mi 14:05:33 xx 296m 123Mi 14:05:46 xx 296m 123Mi 14:05:59 xx 296m 123Mi ...
同値はNodeのリソースを見ても(kubectl top node
)それが反映されていて
14:05:08 xx 703m 34% 4285Mi 64% 14:05:21 xx 703m 34% 4285Mi 64% 14:05:34 xx 1118m 56% 4288Mi 64% 14:05:48 xx 1118m 56% 4288Mi 64% 14:06:01 xx 1118m 56% 4288Mi 64% ...
Node自体には空きがあってもリソースが絞られていることが分かります。
ちなみにコンテナの中には/sys/fs/cgroup/cpu/cpu.statというファイルがあり、ここにはthrottleがかかると値が増える項目があります。特にnr_throttledはcgroup内のタスクがスロットリングされた回数を示しているので、ここをウォッチすればPodのスロットリングの傾向をつかめます。
nr_periods 12090682 nr_throttled 4630438 throttled_time 45265054505800
終わりに
メモリ不足の場合は即座にコンテナを落としますが、CPUの場合は制限がかかるのみなので気づきにくい部分もあります。しかし、指定されているLimitを上限とした使用率を見ておくことで制限がかかっている状態なのか否かは掴めるので定期的にモニタリングをすることをおすすめします。
以上です。