LoginSignup
7
1

More than 3 years have passed since last update.

Kubernetes Resource Limits の挙動確認

Last updated at Posted at 2020-07-05

はじめに

Kubernetesでは、Podに割り当てるリソースの制限が出来ます。主に2種類の指定方法があります。自分たちのワークロードに応じて、適切なものを選択すると良いでしょう。

Resource Requests
Podを作成する時に必要なリソースをリクエストする指定。実際にPodが使用するリソースは制限しない。Requestsで指定したリソースを超えて無制限にリソースを利用可能

Resource Limits
Podが実際に資料するリソースを制限する仕組み。CPUを指定すると、指定した数以上は使用されない。メモリを指定すると、指定した数を超えた場合は、OOM Killer でPodを強制終了する(OOM Killer)

今回の記事では、Resource Limit の挙動確認します。Kubernetes は、Oracle Cloud の Kubernetesサービス(OKE)を使っていますが、一般的な環境と変わらないはずです。

Resource Limits

Resource Limits 有りの Pod を作成します。マニフェストファイル内に、cpu: "1"memory: "200Mi" を指定します。余談ですがコンテナイメージのsugimount/toolbox は、便利なツール群を導入済みの Ubuntu 18.04 の Image です。自作のものです。Dockerfile は Docker Hub 経由でたどれるので興味があればどうぞ。

  • cpu: "1" : 1秒間に、1個の vCPU を1000ミリ秒使用可能な制限
  • memory: "200Mi" : Memory を 200MiB の制限
cat <<'EOF' > /home/testuser01/manifests/resourcelimit.yaml
apiVersion: v1
kind: Pod
metadata:
  name: limited-pod
spec:
  containers:
  - image: sugimount/toolbox:release-0.0.3
    name: limited-pod
    command: ["sleep", "1800m"]
    resources:
      limits:
        cpu: "1"
        memory: "200Mi"
EOF

Apply して作成します。

kubectl apply -f /home/testuser01/manifests/resourcelimit.yaml

Resource Limits 無し。

cat <<'EOF' > /home/testuser01/manifests/no_resourcelimit.yaml
apiVersion: v1
kind: Pod
metadata:
  name: no-limited-pod
spec:
  containers:
  - image: sugimount/toolbox:release-0.0.3
    name: no-limited-pod
    command: ["sleep", "1800m"]
EOF

Apply

kubectl apply -f /home/testuser01/manifests/no_resourcelimit.yaml

2個の Pod が稼働しています

$ kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
limited-pod      1/1     Running   0          38m   10.244.3.18   10.0.10.6   <none>           <none>
no-limited-pod   1/1     Running   0          33s   10.244.3.19   10.0.10.6   <none>           <none>

動作確認 Resource Limits あり

Resource Limits が指定されているPod 内で負荷を掛けるために、bash を起動します。

kubectl exec -it limited-pod bash

なお、Pod 内からCPUの詳細情報を確認すると、Hostで見えているCPUがすべての数見えています。特に Resource Limits の指定は関係ないようです。(下の例だと2vCPU分)

root@limited-pod:/# cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8167M CPU @ 2.00GHz
stepping        : 4
microcode       : 0x1
cpu MHz         : 1995.308
cache size      : 16384 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit
bogomips        : 3990.61
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8167M CPU @ 2.00GHz
stepping        : 4
microcode       : 0x1
cpu MHz         : 1995.308
cache size      : 16384 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 1
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit
bogomips        : 3990.61
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

root@limited-pod:/# 

メモリについても同様で、Host側に搭載されているメモリが全て見えています。こちらも、特に Resource Limits の指定は関係なく、すべてが見えています。

# free -m
              total        used        free      shared  buff/cache   available
Mem:          14761         607       12669          25        1485       13848
Swap:             0           0           0

stress コマンドで CPU に負荷を掛けます

stress -c 2

Host側で dstat コマンドを実行し、消費したリソースを確認します。左列の usr の部分が、50% 前後になっています。Resource Limits で cpu: "1" 指定しているため、2個中の1個が使用されたと考えると、数値は一致しています。正常に制限されていますね。(なお、Resource Limits の指定が無い場合は、100% になります。後で説明します)

[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  6   2  92   0   0   0| 151k  230k|   0     0 |   0     0 |1005  2150
  2   1  98   0   0   0|   0    20k|4276B 5411B|   0     0 | 782  1516
  2   1  98   0   0   0|   0     0 |3139B 3357B|   0     0 | 684  1451
  3   1  96   0   0   0|   0  8192B|8588B   13k|   0     0 | 737  1605
 37   0  63   0   0   0|   0     0 |2939B 3176B|   0     0 |1255  1298
 52   1  47   0   0   0|   0     0 |2566B 2886B|   0     0 |1655  1584
 52   1  48   0   0   0|   0  4096B|2658B 2978B|   0     0 |1592  1379
 53   1  45   0   0   0|   0     0 |2966B 3352B|   0     0 |1892  2590
 52   0  48   0   0   0|   0     0 |4321B 5125B|   0     0 |1394   986

同様にメモリにも負荷を掛けましょう。Resource Limits の範囲に収まる指定です。

stress --vm 1 --vm-bytes 190M --vm-hang 1

Host側のメモリ消費量を見ると、used の部分が 190M 程増えています。

[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]# dstat -tpcdrmngy
Terminal width too small, trimming output.
----system---- ---procs--- ----total-cpu-usage---- -dsk/total- --io/total- ------memory-usage----- -net/total- ---paging-->
     time     |run blk new|usr sys idl wai hiq siq| read  writ| read  writ| used  buff  cach  free| recv  send|  in   out >
05-07 07:42:24|  0   0 9.5|  5   2  93   0   0   0| 107k  178k|1.96  6.81 | 717M 3108k 1382M 12.4G|   0     0 |   0     0 >
05-07 07:42:25|  0   0   0|  1   1  98   0   0   0|   0     0 |   0     0 | 717M 3108k 1382M 12.4G|5354B 4794B|   0     0 >
05-07 07:42:26|  0   0  12|  3   2  96   0   0   0|   0     0 |   0     0 | 717M 3108k 1382M 12.4G|6188B 6736B|   0     0 >
05-07 07:42:27|  0   0 4.0|  3   1  96   0   0   0|   0    16k|   0  4.00 | 717M 3108k 1382M 12.4G|4541B  973B|   0     0 >
05-07 07:42:28|  0   0   0|  4   1  96   0   0   0|   0     0 |   0     0 | 717M 3108k 1382M 12.4G|5445B 6106B|   0     0 >
05-07 07:42:29|  0   0 3.0|  2   3  95   0   0   0|   0     0 |   0     0 | 907M 3108k 1382M 12.2G|6244B   11k|   0     0 >
05-07 07:42:30|  0   0   0|  2   3  95   0   0   0|   0     0 |   0     0 | 907M 3108k 1382M 12.2G|5655B 5914B|   0     0 >
05-07 07:42:31|  0   0  23|  5   4  92   0   0   0|   0     0 |   0     0 | 908M 3108k 1382M 12.2G| 287B  875B|   0     0 >
05-07 07:42:32|  0   0 6.0|  3   3  94   0   0   0|   0  8192B|   0  1.00 | 908M 3108k 1382M 12.2G|3982B 4502B|   0     0 >
05-07 07:42:33|  0   0   0|  2   3  96   0   0   0|   0     0 |   0     0 | 908M 3108k 1382M 12.2G|2254B 2806B|   0     0 >^C

では今度は、Resource Limits を超える負荷を掛けてみます。すると、bash が強制終了して、Pod から排出されました。

root@limited-pod:/# stress --vm 1 --vm-bytes 250M --vm-hang 1
stress: info: [22] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
command terminated with exit code 137
testuser01@cloudshell:manifests (ap-tokyo-1)$ 

Pod が強制終了して、Restartしている様子が見えます。

$ kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
limited-pod      1/1     Running   4          50m   10.244.3.29   10.0.10.6   <none>           <none>
no-limited-pod   1/1     Running   0          48m   10.244.3.25   10.0.10.6   <none>           <none>

output=yaml を指定して、詳細な情報を確認しましょう。

kubectl get pod limited-pod --output=yaml

lastState の欄に、reason: OOMKilled が見えます。Resource Limits の指定を超えて利用したため、コンテナプロセスが強制終了されましたね。

省略
    lastState:
      terminated:
        containerID: docker://263b2ef2a1ee4cfdd86e37fb88ddecdcc2db92c05794c5b096a6b2cf756e3a83
        exitCode: 137
        finishedAt: "2020-07-05T07:43:13Z"
        reason: OOMKilled
        startedAt: "2020-07-05T07:38:59Z"
省略

Host側メモリを見ると、特段変化はありません。すぐにメモリが Limits を超えたことを検知して、OOM Killed されました。

[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]# dstat -tpcdrmngy
Terminal width too small, trimming output.
----system---- ---procs--- ----total-cpu-usage---- -dsk/total- --io/total- ------memory-usage----- -net/total- ---paging-->
     time     |run blk new|usr sys idl wai hiq siq| read  writ| read  writ| used  buff  cach  free| recv  send|  in   out >
05-07 07:43:10|  0   0 9.5|  5   2  93   0   0   0| 106k  177k|1.95  6.77 | 717M 3108k 1383M 12.4G|   0     0 |   0     0 >
05-07 07:43:11|  0   0  10|  2   1  98   0   0   0|   0     0 |   0     0 | 717M 3108k 1383M 12.4G|2668B 4084B|   0     0 >
05-07 07:43:12|  0   0   0|  2   1  98   0   0   0|   0     0 |   0     0 | 717M 3108k 1383M 12.4G|3470B 3724B|   0     0 >
05-07 07:43:13|  0   0 6.0|  1   1  98   0   0   0|   0    16k|   0  3.00 | 718M 3108k 1383M 12.4G|3548B 4195B|   0     0 >
05-07 07:43:14|1.0   0  81| 21  21  51   6   0   1|   0  1860k|   0  85.0 | 716M 3108k 1383M 12.4G|  16k   18k|   0     0 >
05-07 07:43:15|2.0   0  81| 12  10  78   0   0   0|   0   436k|   0  80.0 | 724M 3108k 1390M 12.3G|  14k 9245B|   0     0 >
05-07 07:43:16|1.0   0  86| 14   8  77   0   0   0|   0    48k|   0  11.0 | 721M 3108k 1383M 12.4G|  11k 6252B|   0     0 >
05-07 07:43:17|  0   0  21|  7   3  90   0   0   0|   0     0 |   0     0 | 715M 3108k 1383M 12.4G|8982B 5462B|   0     0 >
05-07 07:43:18|1.0   0  25|  3   2  95   0   0   0|   0     0 |   0     0 | 715M 3108k 1383M 12.4G|2688B 3152B|   0     0 >^C
[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]#

動作確認 Resource Limits なし

Resource Limits が無いPod 内で負荷を掛けるために、bash を起動します。

kubectl exec -it no-limited-pod bash

Pod 内から見える CPU の情報は、Resource Limits の有無では何もかわりません

root@no-limited-pod:/# cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8167M CPU @ 2.00GHz
stepping        : 4
microcode       : 0x1
cpu MHz         : 1995.308
cache size      : 16384 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit
bogomips        : 3990.61
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 85
model name      : Intel(R) Xeon(R) Platinum 8167M CPU @ 2.00GHz
stepping        : 4
microcode       : 0x1
cpu MHz         : 1995.308
cache size      : 16384 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 1
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat umip pku ospke md_clear
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit
bogomips        : 3990.61
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

root@no-limited-pod:/# 

Memory も同様に何もかわりません

root@no-limited-pod:/# free -m
              total        used        free      shared  buff/cache   available
Mem:          14761         606       12666          25        1489       13851
Swap:             0           0           0
root@no-limited-pod:/# 

stress コマンドで CPU に負荷を掛けます

stress -c 2

Host側で dstat コマンドを実行し、消費したリソースを確認します。usr の部分が、99% 前後になっています。Resource Limits が有りでは、50% 前後になっていたところですが、何も制限されていないことが分かります。

[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]# dstat -tpcdrmngy
Terminal width too small, trimming output.
----system---- ---procs--- ----total-cpu-usage---- -dsk/total- --io/total- ------memory-usage----- -net/total- ---paging-->
     time     |run blk new|usr sys idl wai hiq siq| read  writ| read  writ| used  buff  cach  free| recv  send|  in   out >
05-07 08:46:03|  0   0 8.3|  4   2  94   0   0   0|  69k  129k|1.26  4.83 | 721M 3108k 1385M 12.4G|   0     0 |   0     0 >
05-07 08:46:04|  0   0 4.0|  4   2  95   0   0   0|   0     0 |   0     0 | 721M 3108k 1385M 12.4G|  16k   19k|   0     0 >
05-07 08:46:05|  0   0 2.0|  1   0  99   0   0   0|   0    16k|   0  4.00 | 721M 3108k 1385M 12.4G|6948B 5678B|   0     0 >
05-07 08:46:06|1.0   0  10|  2   1  97   0   0   0|   0   212k|   0  28.0 | 722M 3108k 1385M 12.4G|2658B 3138B|   0     0 >
05-07 08:46:07|2.0   0 3.0| 75   0  25   0   0   0|   0     0 |   0     0 | 722M 3108k 1385M 12.4G|4912B 5792B|   0     0 >
05-07 08:46:08|3.0   0 2.0| 99   1   0   0   0   0|   0     0 |   0     0 | 722M 3108k 1385M 12.4G|3815B 4355B|   0     0 >
05-07 08:46:09|2.0   0 4.0| 99   1   1   0   0   0|   0     0 |   0     0 | 722M 3108k 1385M 12.4G|2566B 3072B|   0     0 >
05-07 08:46:10|2.0   0 6.0| 99   1   0   0   0   1|   0    12k|   0  3.00 | 722M 3108k 1385M 12.4G|7160B 3705B|   0     0 >
05-07 08:46:11|2.0   0 1.0| 99   1   1   0   0   0|   0     0 |   0     0 | 722M 3108k 1385M 12.4G|8320B   13k|   0     0 >^C
[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]#

では今度は、メモリに負荷を掛けます。

root@limited-pod:/# stress --vm 1 --vm-bytes 250M --vm-hang 1
stress: info: [22] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
command terminated with exit code 137
testuser01@cloudshell:manifests (ap-tokyo-1)$ 

Host側メモリを見ると、250MB 程のメモリが使用されています。Resource Limits 有りでは OOM Killed されましたが、Resource Limits 無しでは正常に稼働しています。

[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]# dstat -tpcdrmngy
Terminal width too small, trimming output.
----system---- ---procs--- ----total-cpu-usage---- -dsk/total- --io/total- ------memory-usage----- -net/total- ---paging-->
     time     |run blk new|usr sys idl wai hiq siq| read  writ| read  writ| used  buff  cach  free| recv  send|  in   out >
05-07 08:47:30|  0   0 8.3|  4   2  94   0   0   0|  69k  128k|1.25  4.80 | 721M 3108k 1385M 12.4G|   0     0 |   0     0 >
05-07 08:47:31|  0   0  12|  1   1  98   0   0   0|   0     0 |   0     0 | 721M 3108k 1385M 12.4G| 132B  150B|   0     0 >
05-07 08:47:32|  0   0 1.0|  3   1  96   0   0   0|   0     0 |   0     0 | 721M 3108k 1385M 12.4G|  11k   17k|   0     0 >
05-07 08:47:33|  0   0  13|  4   2  94   0   0   0|   0     0 |   0     0 | 721M 3108k 1385M 12.4G| 946B 1022B|   0     0 >
05-07 08:47:34|  0   0 2.0|  3   5  92   0   0   0|   0    28k|   0  5.00 | 972M 3108k 1385M 12.1G|  23k   24k|   0     0 >
05-07 08:47:35|  0   0 4.0|  3   4  94   0   0   0|   0     0 |   0     0 | 972M 3108k 1385M 12.1G|  66B   66B|   0     0 >
05-07 08:47:36|  0   0  12|  2   4  94   0   0   1|   0   136k|   0  20.0 | 972M 3108k 1385M 12.1G|6038B 7014B|   0     0 >
05-07 08:47:37|  0   0   0|  1   4  95   0   0   0|   0     0 |   0     0 | 972M 3108k 1385M 12.1G|1184B 1772B|   0     0 >
05-07 08:47:38|  0   0   0|  2   4  94   0   0   0|   0     0 |   0     0 | 972M 3108k 1385M 12.1G|6213B 6756B|   0     0 >^C
[root@oke-crdazdbgvsw-n3geolfmm3d-s6bnuvahoda-2 ~]#

まとめ

この結果をみると、CPU については Limits を指定すれば、指定した数を超えずに稼働してくれて良いです。

メモリについては、指定した数を超えると OOM Killed されて強制再起動されます。そのため、該当の Worker Node の全体でメモリをうまく管理していく必要があります。

参考URL

CPU
https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-cpu-resource/

Memory
https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-memory-resource/

Metric Server
https://github.com/kubernetes-sigs/metrics-server

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1