Pod QoSクラスとは
Resource LimitはNodeのCapacityを超えて指定することができる。
もし、pod AがNodeのメモリ90%を使用していて、pod Bがメモリ50%を使用しようとした場合、どっちのコンテナをkillすべきだろうか? メモリを確保できないからpod Bをkillすべきか?それともpod Aをkillしてpod Bを動かせるようにすべきか?
それは言うまでもなく状況による。
Kubernetesにはどのpodをkillするかを判断するために、Podに優先度をつける仕組みがあり、Quality of Service(QoS)
クラスと呼ばれる。
優先度が低いQoSクラスをもったpodからkillされる。
Kubernetesは3つのQoSクラスを提供する。QoSはpodに対して自動的に付与される(人が手動で指定するものではない)。
- BestEffort (優先度が一番低い)
- Burstable
- Guaranteed (優先度が一番高い)
どのQoSクラスがpodに付与されるかはResource Requests
とResource Limits
の2つから決定される。
どういった条件でQoSクラスが決まるか
BestEffortが設定される条件
- pod内のどのコンテナにもCPU Resource RequestsとCPU Resource Limitsが設定されていなく、かつMemory Resource RequestsとMemory Resource Limitsが設定されていない。
Guaranteed (the highest)が設定される条件
- pod内のどのコンテナにもCPU Resource RequestsとCPU Resource Limitsが設定されていて、かつMemory Resource RequestsとMemory Resource Limitsが設定されている。
- そして Resource RequestsとResource Limitsの値がそれぞれ同じであること。(CPU,Memory両方)
Burstableが設定される条件
- BestEffortもGuaranteedも設定されていない場合。
- つまり例えばResource Requestsしか設定されていない場合や、Resource RequestsとResource Limitsの両方が指定されているがそれぞれの値が異なっている場合にはBurstableが設定される。
- またたとえCPU Resource RequestsとCPU Resource Limitsが設定されていて値が同じであってもMemory Resource RequestsとMemory Resource Limitsの値が同じでなければBurstableが設定される。
pod内に複数のコンテナが存在する場合、どうやってpodのQoSが決まるか
まず各コンテナに上記のルールに従ってQoSを割り当てる。
全てのコンテナがBestEffortならpodのQoSはBestEffortになる。
全てのコンテナがGuaranteedならpodのQoSはGuaranteedになる。
それ以外の場合はpodのQoSはBurstableになる。
ちなみにpodのQoSはkubectl describe pod -o yaml|json
したときに、status.qosClass
fieldに表示される。
nodeのメモリ上限に達した場合、どういった判断でプロセスがkillされるか
QoSクラスに従ってどのコンテナがkillされるか決まる。
最初にkillされるのはBestEffort。次にBurstable。最後にGuaranteed(ただしsystem processがメモリを必要とした場合のみkillされる)。
同じQoSクラスだった場合、どうやってどのコンテナがkillされるかを決めているか
どの実行中プロセスもOutOfMemory (OOM) scoreを持っている。参考:Linux のオーバーコミットについて調べてみた
システムはOutOfMemory (OOM) scoreをもとにどのプロセスをkillするかを決めている。
参考
- Kubernetes in Action (最高に分かりやすく書かれているのでぜひ買いましょう)
- Configure Quality of Service for Pods
- Resource Quality of Service in Kubernetes