KubernetesのQuality of Service(QoS)クラスについて


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 RequestsResource 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するかを決めている。


参考