KubernetesのEvicted Podsを理解する

By 清水 孝郎 - SEPTEMBER 21, 2022

SHARE:

本文の内容は、2022年9月20日にJavier Martínezが投稿したブログ(https://sysdig.com/blog/kubernetes-pod-evicted/)を元に日本語に翻訳・再構成した内容となっております。

KubernetesのPodがevictedされるとはどういうことでしょうか?通常は十分なリソースがないために終了させられます。しかし、なぜこのようなことが起こるのでしょうか?

Evictionとは、あるNodeに割り当てられたPodに終了を要求するプロセスです。Kubernetesで最も一般的なケースはPreemptionで、リソースが限られているNodeに新しいPodをスケジュールするために、他のPodを終了させて最初のPodにリソースを残す必要があるのです。

また、Kubernetesは常にリソースをチェックし、必要に応じてPodを退去させますが、これはNode-pressure evictionと呼ばれる処理です。

Understanding Kubernetes Evicted Pods main image
毎日、何千ものPodが家から追い出されています。立ち往生し、混乱した彼らは、それまでのライフスタイルを捨てなければならないでしょう。なかには、うなだれる人さえいます。CPUやメモリに高い要求を突きつける現在の社会が、この問題の一端を担っているのです。

この記事の中で、あなたはきっと気づくはずです:

  • Podがevictedされる理由: PreemptionとNode-pressure
  • Preemption eviction
  • Pod Priority Classes
  • Node-pressure eviction
  • Quality of Service Classes
  • その他のevictionタイプ
  • PrometheusでKubernetesのPod evictionを監視する

Podがevictedされる理由: PreemptionとNode-pressure

KubernetesでPodのevictionが発生する理由はいくつかあります。最も重要なものは

  • Preemption
  • Node-pressure eviction

Preemption eviction

Preemptionとは、新しいPodをスケジュールする必要があるが、十分なリソースを持つ適切なNodeがない場合、kube-schedulerは優先度の低いPodをいくつかevicting(終了)させることによって、新しいPodがそのNodeに属することができるかどうかをチェックすることです。

まずはKubernetesのスケジューリングがどのように機能するかを理解しましょう。

Podのスケジューリング

Kubernetesのスケジューリングは、Podをノードに割り当てるプロセスです。

デフォルトでは、スケジューリングを担当するKubernetesのエンティティである kube-scheduler がコントロールプレーンで実行されています。Podはマッチするノードが見つかるまでは Pending state でスタートします。

PodをNodeに割り当てるプロセスは、次のような流れで行われます。

  • Filtering
  • Scoring

Filtering

フィルタリングのステップでは、 kube-scheduler が現在のPodが配置される可能性のあるすべてのノードを選択します。ここではTaintsTolerationsのような機能が考慮されます。終了すると、そのPodに適したNodeのリストが作成されます。

Scoring

スコアリングのステップでは、 kube-scheduler は前のステップで得られたリストを取得し、各ノードにスコアを割り当てます。このようにして、候補ノードは最も適切なものから最も適切でないものへと並べられます。2つのノードが同じスコアを持っている場合、kube-schedulerはそれらをランダムに並べます。

Filtering and Scoring processフィルタリングとスコアリングの処理

しかし、Podを実行するのに適したNodeがない場合はどうなるでしょうか?その場合、Kubernetesはpreemptionを開始し、新しいPodを割り当てるために優先度の低いPodをevictさせようとします。

Pod Priority Classes

preemption処理の際に、特定のPodがevictedされないようにするにはどうしたらいいのでしょうか?おそらく、特定のPodはあなたにとって重要であり、決して終了させるべきではないでしょう。

そのため、KubernetesはPriority Classを備えています。

Priority ClassはKubernetesのオブジェクトで、特定のPodに優先度の数値を対応させることができます。値が大きいものほど重要度が高く、evictedされる可能性が低いと分類されます。

現在のPriority Classは、以下のようにしてクエリーすることができます:

kubectl get priorityclasses
kubectl get pc

NAME                      VALUE        GLOBAL-DEFAULT   AGE
system-cluster-critical   2000000000   false            2d
system-node-critical      2000001000   false            2d

Priority Classの例

Lovenstein氏の漫画Berry Club comic を使って実例をやってみましょう。

Image

ブルーベリー、ラズベリー、ストロベリーを表す3つのPodがあります:

NAME         READY   STATUS             RESTARTS   AGE
blueberry    1/1     Running            0          4h41m
raspberry    1/1     Running            0          58m
strawberry   1/1     Running            0          5h22m

そして、Priority Classはtrueberryとfalseberryの2つがあります。前者は値が高いほど優先度が高いことを示します。

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: trueberry
value: 1000000
globalDefault: false
description: "This fruit is a true berry"

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: falseberry
value: 5000
globalDefault: false
description: "This fruit is a false berry"

  • ブルーベリーは、trueberry priority class (value = 1000000) を持つようになります。
  • ラズベリーとストロベリーは両方とも falseberry priority class (value = 5000) を持ちます。

これは、preemption が発生した場合、ラズベリーとストロベリーはより高い優先順位のPodのためにevictedさせられる可能性が高いということを意味します。

次に、Podの定義に次のように追加して、PodにPriority Classesを割り当てます。

priorityClassName: trueberry

では、さらに3つのフルーツを追加してみましょう。新しいフルーツはすべて、trueberryという高いPriority Classを含んでいます。

新しい3つのフルーツは、ノードが満たせないメモリやCPUを必要とするため、kubeletは新しいフルーツよりも低い優先順位のPodをすべてevictsさせます。ブルーベリーは優先順位が高いため、そのまま実行されます。

NAME         READY   STATUS             RESTARTS   AGE
banana       0/1     ContainerCreating  0          2s
blueberry    1/1     Running            0          4h42m
raspberry    0/1     Terminating        0          59m
strawberry   0/1     Terminating        0          5h23m
tomato       0/1     ContainerCreating  0          2s
watermelon   0/1     ContainerCreating  0          2s

Kubernetes Priority Classes - Live exampleKubernetesのプライオリティクラス – 実例

これが最終的な結果です:

NAME         READY   STATUS             RESTARTS   AGE
banana       1/1     Running            0          3s
blueberry    1/1     Running            0          4h43m
tomato       1/1     Running            0          3s
watermelon   1/1     Running            0          3s

ベリークラブにとっては不思議な時代です…。

Node-pressure eviction

preemptionとは別に、Kubernetesはディスクプレッシャー、CPU、OOM(Out of Memory)などのノードリソースを常にチェックしています。

ノード内のリソース(CPUやメモリなど)の消費量がある閾値に達した場合、kubelet はリソースを解放するためにPodのevictingを開始します。退去順序の決定には、QoS(Quality of Service)が考慮されます。

Quality of Service Classes

Kubernetesでは、Podには3つのQoSクラスが設定されており、リソースが不足した場合にどの程度evictedさせるか、可能性が低いものから高いものまで定義されています。
  • Guaranteed
  • Burstable
  • BestEffort

QoSクラスはどのようにPodに割り当てられるのでしょうか?これは、CPUとメモリのリミットとリクエストに基づいています。備忘録として。

  • Limits:コンテナが使用できるリソースの最大量。
  • Requests:コンテナが実行するために必要な最小限のリソース量。
リミットとリクエストの詳細については、例を交えてKubernetesのリミットとリクエストを理解するをご確認ください。

QoS Classes in KubernetesKubernetesのQoSクラス


Guaranteed

以下のような、PodにはGuaranteedというQoSクラスが割り当てられます。

  • Pod内のすべてのコンテナには、CPUとメモリに対してLimitsとRequestsの両方が設定されています。
  • Pod内のすべてのコンテナで、CPU LimitとCPU Requestが同じ値になっています。
  • Pod内のすべてのコンテナで、メモリLimitとメモリRequestが同じ値になっている。

Guaranteed Podは、通常、ノード内の別のPodを割り当てるためにevictedされることはありません。


Burstable

以下のような、PodにはBurstableというQoSクラスが割り当てられます:

  • QoS ClassがGuaranteedでない場合。
  • Pod内のコンテナに対してLimitsまたはRequestが設定されている。

Burstable Podはevictedさせられる可能性がありますが、次のカテゴリに比べるとその可能性は低くなります。

BestEffort

以下のような、PodにはBestEffortというQoSクラスが割り当てられます。

  • Pod内のどのコンテナにもLimitsとRequestsが設定されていない場合。

BestEffort Podは、ノードでノードプレッシャープロセスが発生した場合に、最も高い確率でevictionさせられます。

重要:LimitsとRequestsには、ephemeral-storageのような他の利用可能なリソースがあるかもしれませんが、それらはQoS Classの計算には使用されません。

Quality of Service cheatsheetQoSチートシート

前述のように、QoS Classはノードプレッシャーによるevictionのために考慮されます。以下は、内部で行われる処理です。

kubeletはevictedさせるPodを以下の順番でランク付けしています:

  • 使用量がリクエストを上回っているBestEffort または Burstable 
  • 使用量がリクエストを下回っているBurstable Pods、または Guaranteed  Pods
Kubernetesは、グループ1からのPodをグループ2よりも先にevictさせようとします。

上記から得られるいくつかのポイント:

  • コンテナ内に非常に低いリクエストを追加した場合、そのPodはグループ1が割り当てられる可能性が高く、つまりevictedされる可能性が高くなります。
  • どのPodがevictedされるかはわかりませんが、Kubernetesはグループ2の前にグループ1のPodをevictedさせようとします。
  • Guaranteed Podは通常、evictedから安全です。 kubelet は他のPodをスケジュールするためにそれらをevictedさせることはありません。しかし、一部のシステムサービスがより多くのリソースを必要とする場合、kubeletは必要に応じてGuaranteed  Podsを終了させます(常に最も低い優先度で)。

その他のevictionの種類

この記事では、preemptionnode-pressure evictionに焦点を当てましたが、Podは他の方法でもevictedさせることができます。例えば以下のようなものがあります。

API-initiated eviction

Kubernetes Eviction APIを使用して、いずれかのノードにあるPodのon-demand evictionをリクエストすることができます。

Taint-based eviction

KubernetesのTaintとTolerationsを使用すると、PodをNodeにどのように割り当てるべきかをガイドすることができます。しかし、既存のNodeに NoExecute taint を適用すると、それを許容しないすべてのPodが即座にevictedさせられてしまいます。

Node drain

Nodeが使えなくなったり、もう作業したくなくなったりすることがあります。kubectl cordon コマンドはその上で新しいPodがスケジュールされるのを防ぎますが、現在のPodを一度に全て完全に空にすることも可能です。 kubectl drain nodenameを実行すると、そのノードのgraceful termination periodを尊重して、そのノード内のすべてのPodがevictionされます。

PrometheusでKubernetesのPod evictionを監視する

クラウドソリューションでは、Prometheusを使用して、Podのevictionsを簡単に監視することができます:

kube_pod_status_reason{reason="Evicted"} > 0

Monitor Evicted Pods with PrometheusPrometheusでEvicted Podsを監視する

これは、クラスター内のすべてのEvicted Podを表示します。また、kube_pod_status_phase{phase="Failed"} と組み合わせることで、Podに障害が発生した後にevictedされたものに対してアラートを出すことも可能です。

さらに深く掘り下げたい方は、Prometheusでリソースを監視するための以下の記事もご確認ください。


まとめ

ご覧の通り、evictionは、限られたリソース(この場合はPodが使用するノード)を制御できるKubernetesの機能のひとつです。

preemptionの間、Kubernetesは新しいものをスケジュールするために優先度の低いPodをevictingさせることによって、リソースを解放しようとします。Priority Classesを使えば、どのPodがpreemption後も実行され続ける可能性が高いかを制御することができます。

実行中、Kubernetesは、Node-pressureをチェックし、必要であればPodをevictedさせます。QoSクラスを使用すると、Node-pressureが発生した場合にどのPodがevictedされやすいかを制御できます。

メモリとCPUはノードの重要なリソースであり、Pod、コンテナ、ノードが適切な量を使用するように設定する必要があります。これらのリソースを適切に管理すれば、コスト面でのメリットだけでなく、重要なプロセスをどのような状況でも稼働させ続けることができる可能性があります。


Sysdig MonitorでPod evictionに先手を打つ

Sysdig Advisorを利用することで、クラスターリソースの可用性を確認し、Podのevictionを防止することができます。特徴としては、:

  • クラスターキャパシティ管理
  • 潜在的なキャパシティの問題を優先的に表示
  • ワークロードの適切なサイジングのガイド
Screenshot of Sysdig Monitor, with the CPU overcommit resource
Sysdig Advisorは、ライブログ、パフォーマンスデータ、推奨される改善策によって、平均解決時間(MTTR)を短縮します。Kubernetesのトラブルシューティングのための簡単にする仕組みです!

30日間無料でお試しください!


AWS MarketplaceでSysdig Secure DevOps Platformをご購入ください!

Sysdigは、AWS Marketplaceで簡単にご購入いただくことができます。

AWS MarketplaceのSysdig Secure DevOps Platformをご参照ください。