kubernetesクラスタを運用する時、nodeにシステムのリソースを確保していますか?
私は全く気にしていませんでした、そしてちょっとした問題になりました。
そこでこのためのオプションkube-reservedとsystem-reservedをサクッと設定して平和に…
でも余分に割り振ったらリソースもったいないし、少なすぎたらやる意味ないし、適切な値を…
なんて考えてたら完全理解に時間がかかったのでざくざくまとめておきます。
参考ドキュメント
https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/node-allocatable.md
理解したこと
-
kube-reservedとsystem-reservedの2種類がある -
kube-reservedはdockerやkubeletなどのkubernetesを動作させるのに必要なservice、system-reservedはsshdやudevなどのOS系のserviceのリソースをそれぞれ確保するのに使う- といってもそれらのserviceを勝手に見分けてくれるスゴい奴などではなく、cgroupで指定するのでそれらのcgroupを把握するなり変更するなりその辺の事前準備は必要
- 後述する「ゆるい制限」なら特に必要ない
- podで動作しているものは
kube-reserved扱いっぽいやつでも入らない(cgroupを他のpodと別にできないので無理)- kube-apiserverとかをpodで動かしてる場合など
- といってもそれらのserviceを勝手に見分けてくれるスゴい奴などではなく、cgroupで指定するのでそれらのcgroupを把握するなり変更するなりその辺の事前準備は必要
-
--kube-reservedで確保するリソースの量を指定して、--kube-reserved-cgroupでそれを適用するcgroupのグループを指定する-
system-reservedも同じ - cgroupをマニュアルで指定するなら両者に本質的な違いはない?
-
- node全体のリソースから
kube-reservedとsystem-reservedのぶんを引いたものがpodで使えるリソースになる -
enforce-node-allocatableでkube-reservedとsystem-reservedを指定することにより、指定したリソースの量をlimitにすることができる- これを付けない場合は
--kube-reservedや--system-reservedで指定した値をpodが使えるリソース量から引くだけの比較的ゆるい制限になる- ので、両方指定する意味はなくなって、足した数値を片方に集めるのと同じことになる
- 個人的にはここまでやらなくていいかなという感想
- これを付けない場合は
-
eviction-hardはnode全体のリソースにかかる - ユーザーログインに使うリソースをsystem-reservedに含めるのをめっちゃ勧めてるけどこれを/user.sliceから動かす方法がわからない
- cgroup-driverはよくわからなかった
- 使用するリソース量は環境に依るのでどのくらいの値が適切かは各々が調べる必要がある
数値を決める
多すぎ => もったいない
少なすぎ => 意味ない
です
キャパシティに関してはこの記事
https://kubernetes.io/blog/2016/11/visualize-kubelet-performance-with-node-dashboard/
を参考にするといいらしいのですが、benchmarkのページも含め何が何やらさっぱりでした。
なのでこれは置いといて、別のやり方で決めます。
systemd-cgtopコマンドを使えばcgroupごとのリソース消費を見ることができます。
が、ずっと眺めてるわけにもいかないのでメトリクスを取得するのがよいでしょう。
cadvisorのメトリクスcontainer_memory_usage_bytesとcontainer_cpu_usage_seconds_totalが、idというlabelでcgroupごとのメトリクスを取得しているようなのでこれを参考にします。
これらのメトリクスをいい感じにまとめると…

なんとなく見えてきました。
cpuは素直にこのままでいいと思いますが、メモリは必要に応じて開放できる余地がありそうなのでその辺りを考慮する必要がありそうです。
備考
メモリの制限は直感的に数字通り動くのでわかりやすかったですが、cpuの制限が少しわかりにくかったです。
それぞれ設定された値をもとに各cgroupのcpu.sharesは設定されており、cpu.cfs_quota_usは設定されておらず、つまり相対的な制限となっています。
コア1つに対して100mを設定したら絶対に10%が上限になるわけではなくて、他でcpuを使っていなければもっとたくさん使うということです。
manifestでlimitsでなくrequestsを設定するイメージと考えるとわかりやすいかと思います。(このイメージだとメモリはlimits…紛らわしい…)
わざとなのかそうでないのかわかりませんが、値の設定にはその辺りも頭に入れておく必要があります。