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…紛らわしい…)
わざとなのかそうでないのかわかりませんが、値の設定にはその辺りも頭に入れておく必要があります。