Pod Quality of Serviceクラス
このページでは、Kubernetesにおける Quality of Service(QoS)クラス を紹介し、 Pod内のコンテナに指定したリソース制約に応じて、KubernetesがどのようにPodにQoSクラスを割り当てるのかについて説明します。 Kubernetesは、ノード上で利用可能なリソースが不足した際に、どのPodを退避させるかを決定するために、このクラスを利用します。
Quality of Serviceクラス
Kubernetesは、実行中のPodを分類し、各Podを特定の Quality of Service(QoS)クラス に割り当てます。
Kubernetesは、このクラスを用いてそれぞれのPodの扱い方を決定します。
分類は、Pod内のコンテナのリソース要求と、それらの要求とリソース制限との関連性に基づいて行われます。
これはQuality of Service(QoS)クラスと呼ばれます。
Kubernetesは、Podのコンポーネントであるコンテナのリソース要求と制限に基づいて、すべてのPodにQoSクラスを割り当てます。
QoSクラスは、ノードの圧迫が発生しているノードからどのPodを退避させるかを決定する際に使用されます。
QoSクラスにはGuaranteed、Burstable、BestEffortがあります。
ノードのリソースが不足すると、KubernetesはまずBestEffort Podを退避し、次にBurstable、最後にGuaranteed Podを退避させます。
リソースの圧迫による退避の場合、リソース要求を超過しているPodのみが退避の候補となります。
Guaranteed
GuaranteedのPodは最も厳しいリソース制限を持ち、退避される可能性が最も低いです。
制限を超過するか、ノードからプリエンプト可能なより低い優先度のPodが存在しない限り、強制終了されることはありません。
ただし、指定された制限を超えてリソースを取得することはできません。
これらのPodは、static CPU管理ポリシーを使って、排他的にCPUを利用することもできます。
条件
PodがGuaranteed QoSクラスとして分類されるための条件は以下の通りです:
- Pod内のすべてのコンテナが、メモリ制限とメモリ要求を持っていること。
- Pod内のすべてのコンテナで、メモリ制限がメモリ要求と等しいこと。
- Pod内のすべてのコンテナが、CPU制限とCPU要求を持っていること。
- Pod内のすべてのコンテナで、CPU制限がCPU要求と等しいこと。
もしくは、PodがPodレベルのリソースを使用する場合は以下の通りです:
Kubernetes v1.34 [beta](enabled by default)- PodがPodレベルのメモリ制限とメモリ要求を持ち、それらの値が等しいこと。
- PodがPodレベルのCPU制限とCPU要求を持ち、それらの値が等しいこと。
Burstable
BurstableのPodは、要求に基づく下限のリソース保証を持ちますが、特定の制限は必要としません。
制限が指定されていない場合、デフォルトでノードの容量と同等の制限となり、リソースが利用可能であればPodは柔軟にリソースを増やすことができます。
ノードのリソース圧迫によるPod退避の際、これらのPodは、すべてのBestEffort Podが退避されてから退避されます。
Burstable Podには、リソース制限や要求を持たないコンテナを含めることができるため、BurstableなPodは任意の量のノードリソースを使おうとする可能性があります。
条件
以下の場合、PodはBurstable QoSクラスとして分類されます:
- Podが
GuaranteedQoSクラスの条件を満たさないこと。 - Pod内の少なくとも1つのコンテナがメモリまたはCPUの要求または制限を持つか、 PodがPodレベルのメモリまたはCPUの要求または制限を持つこと。
BestEffort
BestEffort QoSクラスのPodは、他のQoSクラスのPodに明示的に割り当てられていないノードリソースを使用できます。
たとえば、kubeletで利用可能な16個のCPUコアを持つノードがあり、Guaranteed Podに4個のCPUコアを割り当てた場合、
BestEffort QoSクラスのPodは、残りの12個のCPUコアのうち任意の量を使うことができます。
kubeletは、ノードがリソース圧迫を受けた場合、BestEffort Podを優先的に退避させます。
条件
Podは、GuaranteedまたはBurstableのいずれの条件も満たさない場合、BestEffort QoSクラスになります。
つまり、Pod内のどのコンテナもメモリ制限またはメモリ要求を持たず、Pod内のどのコンテナもCPU制限またはCPU要求を持たず、PodがPodレベルのメモリまたはCPUの制限または要求を持たない場合にのみ、PodはBestEffortとなります。
Pod内のコンテナは、(CPUまたはメモリ以外の)他のリソースを要求していても、BestEffortとして分類されます。
cgroup v2を使用したメモリQoS
Kubernetes v1.22 [alpha](disabled by default)メモリQoSは、cgroup v2のメモリコントローラーを使用して、Kubernetesでメモリリソースを保証します。
Pod内のコンテナのメモリ要求と制限は、メモリコントローラーが提供するmemory.minとmemory.highインターフェースの設定に使用されます。
memory.minがメモリ要求に設定されると、メモリリソースは予約され、カーネルによって回収されることはありません。
これが、メモリQoSがKubernetes Podのメモリ可用性を保証する仕組みです。
また、コンテナでメモリ制限が設定されている場合、システムはコンテナのメモリ使用量を制限する必要があります。
メモリQoSは、memory.highを使用してメモリ制限に近づいているワークロードの動作を抑制し、瞬間的なメモリ割り当てによってシステムが圧迫されないようにします。
メモリQoSは、QoSクラスに基づいてどの設定を適用するか決定しますが、 これらは異なるメカニズムであり、どちらもQuality of Serviceに対する制御を提供します。
QoSクラスに依存しない動作
Kubernetesによって割り当てられたQoSクラスとは無関係な動作もあります。 例えば、以下が該当します:
-
リソース制限を超過したコンテナは、そのPod内の他のコンテナに影響を与えることなく、kubeletによって強制終了され、再起動されます。
-
コンテナがリソース要求を超過し、実行しているノードがリソース圧迫に直面している場合、 そのコンテナが含まれるPodは退避の候補となります。 このような場合、Pod内のすべてのコンテナが終了されます。 Kubernetesは、通常は別のノード上に、置き換えとなるPodを作成する可能性があります。
-
Podのリソース要求は、コンポーネントであるコンテナのリソース要求の合計に等しく、 Podのリソース制限は、コンポーネントであるコンテナのリソース制限の合計に等しくなります。
-
kube-schedulerは、どのPodをプリエンプトするかを選択する際に、QoSクラスを考慮しません。 プリエンプションは、クラスター内に、定義したすべてのPodを実行するのに十分なリソースがない場合に発生する可能性があります。
次の項目
- Podとコンテナのリソース管理について学ぶ。
- ノードの圧迫による退避について学ぶ。
- Podの優先度とプリエンプションについて学ぶ。
- Pod Disruptionについて学ぶ。
- コンテナおよびPodにメモリリソースを割り当てる方法を学ぶ。
- コンテナおよびPodにCPUリソースを割り当てる方法を学ぶ。
- PodにQuality of Serviceを設定する方法を学ぶ。