Kubernetesの世界を航海する皆さん、こんにちは!👋 クラスターを運用していると、「このPodだけは絶対に死なせてはならない!」とか、「スペースがなければ他のPodを追い出してでも実行されなければならない!」と考える重要なワークロードがありますよね。例えば、モニタリングシステム、ロギングエージェント、またはコアAPIサーバーのようなPodたちです。
今日は、まさにこのような重要なPodを守る方法、KubernetesのPriorityClassについて詳しく見ていきましょう。大切なPodの優先順位をどのように設定し、他のPodよりも常に先に場所を確保できるようにするか、一緒に見ていきませんか?🧐

🤔 PriorityClassはなぜ必要ですか?
Kubernetesスケジューラーは、デフォルトですべてのPodを平等に扱います。しかし、クラスターのリソース(CPU、メモリ)が不足するとどうなるでしょうか?新しく作成されたPodは、スペースが空くまでPending状態で無限に待機することになります。もしこのPodが非常に重要な役割を果たすPodであれば、サービス全体に障害が発生する可能性もあります。😱
また、クラスターにスペースが不足している場合、どのPodを最初に削除(Evict)するかを決定する必要がある状況も発生するかもしれません。この時、重要度の低いPodから削除し、重要なPodは最大限保護する必要があります。
PriorityClassは、まさにこのような状況のために存在します。Podに extit{‘優先順位’} extit{}というランクを付けて、スケジューラーとノード(kubelet)がどのPodをより重要に扱うべきかを伝える役割を果たします。
- スケジューリング優先権 (Scheduling Priority): リソースが不足している場合、優先順位の高いPodは、優先順位の低いPodよりも先にスケジューリングキューの前面に配置されます。
- プリエンプション (Preemption): より重要なPodがスケジューリングされるスペースがない場合、すでに実行中の重要度の低いPodをノードから追い出し(Evict)、その場所を占有することができます。
⚙️ PriorityClassの使い方:3ステップで完了!
最も高い優先順位を持つPodを作成するプロセスは非常に簡単です。たった3つのステップを覚えてください!
ステップ1:PriorityClassオブジェクトを作成する
まず、どのような優先順位のランクを作成するかを定義する必要があります。valueフィールドに高い数字を入れるほど優先順位が高くなります。システムで使用される最も高い優先順位は通常10億(1,000,000,000)なので、私たちが作成する優先順位はこれより高く設定してはいけません。ここでは100万点を与えて、非常に高いランクを作成してみましょう。
preemptionPolicyはPreemptLowerPriorityに設定し、この優先順位を持つPodがスペースがないときに、自分より低い優先順位のPodを追い出すことを許可します。
high-priority.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for critical pods only."
preemptionPolicy: PreemptLowerPriority
- value: 優先順位スコアです。数字が大きいほど優先順位が高くなります。(最大1,000,000,000)
- globalDefault: trueに設定すると、priorityClassNameを指定していないすべてのPodがこの優先順位を持つようになります。通常はfalseにして明示的に指定する方が安全です。
- preemptionPolicy:
- PreemptLowerPriority (デフォルト): 自分より低い優先順位のPodをプリエンプトできます。
- Never: 他のPodを絶対にプリエンプトしません。
次に、このYAMLファイルをクラスターに適用します。
$ kubectl apply -f high-priority.yaml
priorityclass.scheduling.k8s.io/high-priority created
####
ステップ2:PodにPriorityClassを指定する
次に、作成したhigh-priorityランクを実際のPodに適用してみましょう。Podのスペック(spec)にpriorityClassNameフィールドを追加し、先ほど作成したPriorityClassの名前を記述するだけです。
high-priority-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-critical-app
spec:
containers:
- name: my-app-container
image: nginx
priorityClassName: high-priority
ステップ3:Podの作成と確認
それでは、このPodを作成してみましょう。
$ kubectl apply -f high-priority-pod.yaml
pod/my-critical-app created
このPodにはhigh-priorityランクが割り当てられました。もしクラスターにリソースが不足し、このPodがPending状態になった場合、Kubernetesスケジューラーはhigh-priorityよりも優先順位の低い他のPodをノードから削除してスペースを確保し、my-critical-app Podを実行しようと試みるでしょう。
⚠️ 注意事項とヒント
- プリエンプションは無料ではない!: プリエンプション機能は非常に強力ですが、実行中のPodを終了させるコストが発生します。終了するPodは正常な終了手順(termination grace period)を経ますが、これによりサービスに一時的な中断が発生する可能性があります。したがって、本当に必要なコアPodにのみ高い優先順位を付与する必要があります。
- PodDisruptionBudget (PDB)との関係: プリエンプションの過程でKubernetesはPDBを尊重します。つまり、あるPodを追い出そうとしたときに、そのPodが属するグループのPDBポリシーに違反する場合、プリエンプションは失敗する可能性があります。重要なPodグループにはPDBを設定して、最小限の可用性を保証することをお勧めします。
- 無分別な使用は禁物: すべてのPodに高い優先順位を付与することは意味がありません。優先順位は相対的な概念だからです。本当に重要なワークロードを特定し、階層的に優先順位を設計することが重要です。
✨ 結論
PriorityClassは、複雑で多忙なKubernetesクラスターで秩序を維持し、重要なアプリケーションの安定性を保証する核となる機能です。スケジューリング優先権とプリエンプション(Preemption)メカニズムを通じて、リソースが不足する極限状況でもコアサービスが中断なく実行されることを保証します。
さあ、皆さんもクラスターの重要なPodを特定し、PriorityClassを使って強固な保護膜を張ってあげましょう!🛡️
コメントを残す