OOM キルについて
Azure Kubernetes Service (AKS) でワークロードを実行すると、システムまたはアプリケーション ポッドで再起動を引き起こすメモリ不足エラーが発生する可能性があります。 このガイドは、AKS クラスター ノードのメモリ不足 (OOMKilled) の問題を特定して解決するのに役立ちます。
Important
クラスター内のメモリの問題に対処するには、Azure portal の AKS の [問題の診断と解決 ] セクションを使用します。
OOMKilled と Evictions の説明
AKS などの Kubernetes 環境では、メモリ関連の問題により 、OOMKilled と Evictions という 2 種類のイベントが発生する可能性があります。 どちらもリソースの負荷によってトリガーされますが、原因、スコープ、動作が異なります。
OOMKilled は、カーネル OOM キラーによって終了されたコンテナーに対してのみ報告されます。 ポッド全体ではなく、終了し、既定で再起動されるメモリ制限を超えるコンテナーであることに注意してください。 一方、削除はポッド レベルで発生し、Kubernetes によってトリガーされます。具体的には、ノードがメモリ不足のときに、すべてのノードで実行されている Kubelet によってトリガーされます。 削除されたポッドは、状態が [失敗] と " 削除済み" の理由を報告します。
OOMKilled: Container-Level 終了
OOMKilled は、 コンテナー がメモリ制限を超え、 Linux カーネルの Out-Of-Memory (OOM) キラーによって終了されたときに発生します。
これはコンテナー固有のイベントです。 影響を受けるのは、メモリ制限に違反したコンテナーだけです。 ポッドに他の正常なコンテナーが含まれている場合、ポッドの実行が続行される可能性があります。 通常、終了したコンテナーは自動的に再起動されます。
一般的なインジケーターには、終了コード 137 と、kubectl describe podでの OOMKilled の理由が含まれます。
削除: Kubelet による Pod-Level の削除
このガイドでは OOMKilled に焦点を当てていますが、 削除 は Kubernetes の別のメカニズムであることを理解すると便利です。 ノードがメモリ不足の場合など、ポッド レベルで発生します。
注
このガイドでは、ポッドの削除の可能性のあるすべての原因については説明しません。これは、そのスコープがメモリ関連の OOMKilled イベントに限定されているためです。
Kubelet は、メモリを解放し、ノードの安定性を維持するためにポッドを削除する可能性があります。
削除されたポッドには、失敗の状態と削除 された 理由が表示 されます。
個々のコンテナーを対象とする OOMKilled とは異なり、削除はポッド全体に影響します。
OOM キルの考えられる原因
OOMKilled イベントは、いくつかの理由で発生する可能性があります。 最も一般的な原因は次のとおりです。
リソースのオーバーコミット: ポッド リソースの要求と制限が適切に設定されていないため、過剰なメモリ使用量が発生します。
メモリ リーク: アプリケーションでメモリ リークが発生し、時間の経過と同時に消費されるメモリが増える可能性があります。
高いワークロード: アプリケーションの負荷が急激に急増すると、割り当てられた制限を超えてメモリ使用量が増加する可能性があります。
不十分なノード リソース: ノードに実行中のポッドをサポートするための十分なメモリがない可能性があり、OOM の強制終了が発生する可能性があります。
非効率的なリソース管理: リソースのクォータと制限が不足すると、リソースの消費が制御されない可能性があります。
OOM によって強制終了されたポッドの識別
これらのさまざまな方法のいずれかを使用して、メモリ不足のために強制終了される POD を識別できます。
注
OOMKilled は、 システム ポッド (AKS によって作成された kube-system 名前空間内のもの) と ユーザー ポッド (他の名前空間のポッド) の両方で発生する可能性があります。 さらにアクションを実行する前に、まず影響を受けるポッドを特定することが不可欠です。
Important
クラスター内のメモリの問題に対処するには、Azure portal の AKS の [問題の診断と解決 ] セクションを使用します。
ポッドの状態を確認する
名前空間内のすべてのポッドの状態を確認するには、次のコマンドを使用します。
kubectl get pods -n <namespace>
状態が OOMKilled のポッドを探します。
ポッドについて説明する
kubectl describe pod <pod-name>を使用して、ポッドに関する詳細情報を取得します。
kubectl describe pod <pod-name> -n <namespace>
出力で、[コンテナーの状態] セクションで OOM 強制終了の兆候を確認します。
ポッド ログ
kubectl logs <pod-name>を使用してポッド ログを確認し、メモリ関連の問題を特定します。
ポッドのログを表示するには、次を使用します。
kubectl logs <pod-name> -n <namespace>
ポッドが再起動した場合は、前のログを確認します。
kubectl logs <pod-name> -n <namespace> --previous
ノード ログ
ノード の kubelet ログを確認 して、問題の時点で OOM キラーがトリガーされ、ポッドのメモリ使用量がその制限に達したことを示すメッセージがあるかどうかを確認できます。
または、ポッドが実行されていた ノードに SSH 接続 し、カーネル ログで OOM メッセージを確認することもできます。 このコマンドは、終了した OOM キラーを処理するコマンドを表示します。
chroot /host # access the node session
grep -i "Memory cgroup out of memory" /var/log/syslog
イベント
kubectl get events --sort-by=.lastTimestamp -n <namespace>を使用して OOMKilled ポッドを検索します。ポッドの説明の events セクションを使用して、OOM 関連のメッセージを検索します。
kubectl describe pod <pod-name> -n <namespace>
システム ポッドの OOMKilled の処理
注
システム ポッドは、kube-system 名前空間にあり、AKS によって作成されたものを参照します。
metrics-server
発行:
- リソースが不足しているため、OOMKilled。
Solution:
- メトリックス サーバーの構成 VPA を使用して、メトリック ス サーバーに追加のリソースを割り当てることができます。
CoreDNS
発行:
- トラフィックの急増による OOMKilled。
Solution:
- CoreDNS スケーリングをカスタマイズ して、ワークロードの要件に基づいて自動スケーリングを適切に構成します。
kube-system 名前空間内の他のポッド
クラスターに システム ノード プールとユーザー ノード プール が含まれていることを確認して、メモリ負荷の高いユーザー ワークロードをシステム ポッドから分離します。 また、システム ノード プールに少なくとも 3 つのノードがあることを確認する必要があります。
ユーザー ポッドの OOMKilled の処理
メモリ制限が不十分であるか、過剰なメモリ消費が原因で、ユーザー ポッドが OOMKilled になる可能性があります。 ソリューションには、適切なリソース要求と制限の設定、およびメモリ使用量の調査にアプリケーション ベンダーを関与させる機能が含まれます。
原因 1: ユーザー ワークロードがシステム ノード プールで実行されている可能性がある
ユーザー ワークロード用のユーザー ノード プールを作成することをお勧めします。 詳細については、「 Azure Kubernetes Service (AKS) でのシステム ノード プールの管理」を参照してください。
原因 2: OOMkilled が原因でアプリケーション ポッドが再起動し続ける
この動作は、ポッドに十分なメモリが割り当てされておらず、さらに多くのメモリが必要であるため、ポッドが常に再起動する原因である可能性があります。
解決するには、要求と制限に関するドキュメントを確認し、それに応じてデプロイを変更する方法を理解します。 詳細については、「 ポッドとコンテナーのリソース管理」を参照してください。
kubectl set resources deployment <deployment-name> --limits=memory=<LIMITS>Mi ---requests=memory=<MEMORY>Mi
アプリケーション ポッドの推奨量にリソース要求と制限を設定する。
診断については、 Azure Kubernetes Service (AKS) の問題の診断と解決の概要に関するページを参照してください。
原因 3: ポッドで実行されているアプリケーションが過剰なメモリを消費している
ポッド レベルでメモリ不足を確認します。
kubectl top を使用してメモリ使用量を確認します。
kubectl top pod <pod-name> -n <namespace>
メトリックが使用できない場合は、cgroup の統計を直接調べることができます。
kubectl exec -it <pod-name> -n <namespace> -- cat /sys/fs/cgroup/memory.current
または、これを使用して MB 単位の値を確認できます。
kubectl exec -it <pod-name> -n <namespace> -- cat /sys/fs/cgroup/memory.current | awk '{print $1/1024/1024 " MB"}'
これは、ポッドがメモリ制限に近づいているか、メモリ制限を超えているかを確認するのに役立ちます。
- OOMKilled イベントを確認する
kubectl get events --sort-by='.lastTimestamp' -n <namespace>
解決するには、アプリケーション ベンダーと連携します。 アプリがサード パーティ製の場合は、既知の問題またはメモリ チューニング ガイドがあるかどうかを確認します。 また、アプリケーション フレームワークに応じて、 クラスターを Kubernetes 1.25 にアップグレードした後にポッドでメモリの飽和状態が発生したときに推奨されるように、最新バージョンの Java または .Net を使用しているかどうかをベンダーに確認するよう依頼します。
アプリケーション ベンダーまたはチームは、アプリケーションを調査して、メモリ リークのチェックや、アプリでポッド構成でメモリ リソースの上限が高い必要があるかどうかを評価するなど、大量のメモリを使用している理由を判断できます。 それまでの間、問題を一時的に軽減するために、OOMKill イベントが発生しているコンテナーのメモリ制限を増やします。
今後の OOMKill の回避
リソース制限の検証と設定
すべてのアプリケーション ポッドの適切な リソース要求と制限を確認して 設定します。 メモリ使用量を検証するには、 kubectl top と cgroup 統計を使用します。
システム・ノード・プールおよびユーザー・ノード・プールのセットアップ
クラスターに システム ノード プールとユーザー ノード プール が含まれていることを確認して、メモリ負荷の高いユーザー ワークロードをシステム ポッドから分離します。 また、システム ノード プールに少なくとも 3 つのノードがあることを確認する必要があります。
アプリケーションの評価
最適なパフォーマンスを確保し、AKS クラスター内のメモリ不足を回避するには、アプリケーションのリソース使用パターンを確認することをお勧めします。 具体的には、アプリケーションが適切なメモリ制限を要求しているかどうか、および負荷の下での動作が割り当てられたリソースと一致しているかどうかを評価します。 この評価は、ポッドの削除または OOMKilled イベントを防ぐために調整が必要かどうかを識別するのに役立ちます。