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はどちらをkillすべきか適切な判断を下すことができない。
そのためpodに優先度をつける必要がある。
そのための仕組みがQuality of Service(QoS)クラスと呼ばれるもの。
優先度が低いQoSクラスをもったpodからkillされる。

Kubernetesは3つのQuality of Service(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するかを決めている。

参考

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.