一般的な Kubernetes 終了コードの解釈

一般的な Kubernetes 終了コードの解釈
この記事はWeChatの公開アカウント「DCOS」から転載したもので、著者はzouyeeです。この記事の転載についてはDCOS公式アカウントまでご連絡ください。

1. 終了コード履歴

終了コードの歴史は、Unix オペレーティング システムの初期の頃にまで遡ります。 Unix システムでは、プロセス終了コードは、プロセスが終了したときに親プロセスに渡される整数値であり、プロセスの終了ステータスを示すために使用されます。この整数値は通常 0 から 255 までで、0 はプロセスが正常に終了したことを示し、他の値は通常、さまざまなエラーや異常な状態を示すために使用されます。

プロセス終了コードは、もともと親プロセスが子プロセスの実行結果を理解するための簡単なメカニズムを提供するために設計されました。これにより、親プロセスは、エラー状態の処理や他の操作の続行など、子プロセスの終了コードに基づいて適切なアクションを実行できるようになります。

Unix システムでは、特定の終了コード値には通常、次のような特定の意味があります。

  • 0: エラーなしで正常に実行されたことを示します。
  • 1: 通常は一般的なエラーを示します。
  • 2: コマンドの構文エラーを示します。
  • 127: コマンドが見つからなかったことを示します。

Unix オペレーティング システムが進化し、さまざまな実装が時間の経過とともに進化するにつれて、プロセス終了コードの意味は変化する可能性がありますが、基本的な概念は同じままです。

Linux システムでは、プロセス終了コードの使用方法は Unix システムの場合と同様です。 Linux は Unix のプロセス管理メカニズムを継承し、これを基に拡張および改善しています。したがって、Linux のプロセス終了コードは、プロセスの実行ステータスを理解して診断するのに役立つ重要な概念です。

プロセス終了コードの歴史は、初期の Unix システムにまで遡ります。これは Unix および Linux オペレーティング システムにおける重要な概念であり、プロセス間通信のためのシンプルで効果的なメカニズムを提供します。アプリケーションまたはコマンドが致命的なエラーにより終了または失敗すると、128 シリーズの終了コード (128+n) が生成されます。ここで、n はシグナル番号です。 n SIGTERM、SIGKILL など、すべてのタイプの終了コードが含まれます。

2. 終了コード 127

終了コード 127 は Kubernetes 固有のエラー コードではなく、Linux や Unix 系オペレーティング システムで使用される標準の終了コードです。もちろん、Kubernetes ではこれがよく見られますが、これは通常、コンテナ内で実行されているコマンドまたはバイナリが見つからなかったことを意味します。

標準的な終了コードには次のようなものがあります。

写真

一般的な原因

終了コード 127 の一般的な原因をいくつか見てみましょう。

  1. コマンドまたはバイナリがインストールされていません。Kubernetes コンテナのコマンド フィールドに指定された実行可能ファイルが、コンテナのファイル システムにインストールされていません。必要なバイナリまたはコマンドが利用可能であることを確認する必要があります。
  2. パスまたはコマンドが正しくありません。Pod 定義で指定されたコマンドが正しくないか、指定されたパスに存在しません。これはエラーの最も一般的な原因の 1 つであり、通常は Dockerfile またはポッド仕様のエントリポイントまたはコマンド入力が正しくないことが原因で発生します。
  3. 依存関係が不足しています。コンテナー内で実行されているアプリケーションまたはスクリプトには、関連する依存関係がインストールされていません。必要な依存関係がすべてコンテナ イメージに含まれていることを確認する必要があります。
  4. スクリプトがシェル インタープリター コマンドとして指定されている場合は、スクリプトが有効 (たとえば、#!/bin/bash) であり、コンテナー内で使用可能であることを確認する必要があります。
  5. シェル スクリプトの構文エラー シェル スクリプトがコード 127 で終了する場合は、スクリプトに構文エラーや実行を妨げる可能性のあるその他の問題がないか確認してください。
  6. 権限が不十分です。コンテナ内でコマンドを実行しているユーザーには、指定されたコマンドを実行するために必要な権限がない可能性があります。コンテナが適切な権限で実行されていることを確認してください。
  7. イメージの互換性の問題 使用するコンテナ イメージがホスト アーキテクチャおよびオペレーティング システムと互換性があることを確認します。イメージが一致しないと、arm マシンで x86 イメージを実行するなど、コマンドが見つからない場合があります。
  8. ボリューム マウント コマンドがボリュームにマウントされたファイルである場合は、ボリューム マウントが正しく構成され、必要なファイルにアクセスできることを確認します。
  9. 環境変数 一部のコマンドは特定の環境変数に依存する場合があります。必要な環境変数が正しく設定されていることを確認してください。
  10. Kubernetes RBAC ポリシー RBAC が有効になっている場合は、指定されたコマンドを実行するために必要な権限があることを確認する必要があります。

トラブルシューティング方法

問題をトラブルシューティングするには、次のコマンドを使用して Pod のログを確認します。

 kubectl logs -f <pod-name>

また、Pod のステータスを確認することもできます。これにより、Pod の現在の状態、最近のイベント、エラー メッセージなど、Pod に関する詳細情報が提供されます。

 kubectl describe pod <pod-name>

シェル (BusyBox など) を含むデバッグ コンテナを Pod に接続することもできます。これにより、コンテナに入り、環境、パス、コマンドの可用性を手動で検査できます。

BusyBox を使用したデバッグの例:

 containers: - name: my-container image: my-image:latest command: ["/bin/sleep", "infinity"] - name: debug-container image: busybox:latest command: ["/bin/sh"] tty: true stdin: true

K8s の上位バージョンであれば、一時的なコンテナである Ephemeral Containers も使用できます。これは、Kubernetes v1.16 でアルファとして導入された新しい機能です。一時コンテナの機能を有効にすることも非常に簡単です。 kubernetes v1.16 以降のバージョンでは、kube-api および kubelet サービスに起動パラメータ --feature-gates=EphemeralCnotallow=true を設定し、再起動します。

ログを注意深く確認し、上記の指示に従ってトラブルシューティングを行うことで、終了コード 127 の問題の原因を特定できるはずです。

修正方法

終了コード 127 の一般的な原因とそのトラブルシューティング方法がわかったので、次にその修正方法を見てみましょう。

  1. コマンドまたはバイナリがインストールされていません

必要なコマンドまたはバイナリが不足している場合は、コンテナ イメージにインストールする必要がある場合があります。必要なソフトウェアをインストールするには、Dockerfile またはビルド プロセスを変更します。

例:

 FROM alpine:latest RUN apk --no-cache add <package-name>
  1. パスまたはコマンドが正しくありません

Pod 定義でコマンドを指定する場合は、バイナリへの絶対パスを使用することを検討してください。これにより、現在の作業ディレクトリに関係なく、ランタイムがバイナリを見つけることができるようになります。

例:

 containers: - name: my-container image: my-image:latest command: ["/usr/local/bin/my-command"]
  1. 依存関係が欠落している

コマンドを実行できない理由は、コンテナ イメージに追加のソフトウェアをインストールする必要があることが原因である可能性があります。コマンドに追加のセットアップまたはインストール手順が必要な場合は、メイン コンテナが起動する前に init コンテナを使用してそれらのタスクを実行できます。

例 (init コンテナを使用してパッケージをインストールする):

 initContainers: - name: install-package image: alpine:latest command: ["apk", "--no-cache", "add", "<package-name>"] volumeMounts: - name: shared-data mountPath: /data
  1. シェルインタープリタ

スクリプトをコマンドとして指定する場合は、スクリプトが有効であり (たとえば、#!/bin/bash)、コンテナー内で使用可能であることを確認してください。

例:

 #!/bin/bash
  1. ボリュームマウント

Pod の構成をチェックして、ボリュームが正しくマウントされていることを確認します。ボリューム名、マウント パス、サブパスが正しいことを確認します。

例:

 volumes: - name: my-volume emptyDir: {} containers: - name: my-container image: my-image:latest volumeMounts: - name: my-volume mountPath: /path/in/container

同時に、Pod 定義で指定されたボリュームが存在し、使用可能であることを確認する必要があります。永続ボリューム (PV) の場合は、そのステータスを確認する必要があります。 emptyDir またはその他のタイプのボリュームの場合は、正しく作成およびマウントされているかどうかを確認する必要があります。ボリュームマウントでサブパスが使用される場合は、指定されたサブパスがソースディレクトリまたはファイルに存在することを確認する必要があります。

例:

 volumeMounts: - name: my-volume mountPath: /path/in/container subPath: my-file.txt

3. 終了コード 137

Kubernetes では、終了コード 137 はプロセスが強制的に終了されたことを示します。 Unix および Linux システムでは、プロセスがシグナルによって終了すると、終了コードはシグナル番号に 128 を加えた値で決定されます。シグナル番号は 9 で、これは「SIGKILL」を意味するため、128 に 9 を加えると終了コードは 137 になります。

Kubernetes クラスター内のコンテナがメモリ制限を超えると、Kubernetes システムによって「OOMKilled」エラーで強制終了されることがあります。これは、メモリ不足のためにプロセスが強制終了されたことを示します。このエラーの終了コードは 137OOM で、「メモリ不足」を意味します。

Pod のステータスが「OOMKilled」と表示される場合は、次のコマンドで確認できます。

 kubectl describe pod <podname>

OOMキラー

OOMKiller は、メモリを大量に消費するプロセスを強制終了することで、システムのメモリ不足を防ぐ Linux カーネルのメカニズムです。システムのメモリが不足すると、カーネルは OOMKiller を呼び出して、メモリを解放し、システムの実行を継続するために強制終了するプロセスを選択します。

カーネルには 2 つの異なる OOM Killer があります。 1 つはグローバル OOM Killer であり、もう 1 つは cgroup メモリ コントローラ ベースの OOM Killer (cgroup v1 または cgroup v2) です。

簡単に言えば、カーネルが物理メモリ ページの割り当てで問題に遭遇すると、グローバル OOM Killer がトリガーされます。カーネルがメモリ ページを割り当てようとして (カーネル用か、ページを必要とするプロセス用かのいずれか)、最初は失敗すると、カーネルはさまざまな方法でメモリを再利用して整理しようとします。この試行が成功するか、少なくとも何らかの進捗があった場合、カーネルは割り当ての再試行を継続します。ページを解放できなかったり、処理が進まなかったりすると、多くの場合、OOM Killer がトリガーされます。

OOMKiller は終了するプロセスを選択すると、そのプロセスに正常に終了するように要求する信号を送信します。プロセスがシグナルに応答しない場合、カーネルはプロセスを強制的に終了し、そのメモリを解放します。

注: メモリの問題により終了したポッドは、必ずしもノードから削除されるわけではありません。再起動ポリシーが「常に」に設定されている場合、ポッドの再起動が試行されます。

システム レベルでは、Linux カーネルはホスト上で実行されている各プロセスの oom_score を維持します。プロセスが強制終了される可能性は、スコアの高さによって異なります。

oom_score_adj 値を使用すると、ユーザーは OOM プロセスをカスタマイズし、プロセスを強制終了するタイミングを定義できます。 Kubernetes は、Pod のサービス品質 (QoS) を定義するときに oom_score_adj 値を使用します。

K8s は、Pod に対して 3 種類の QoS を定義しており、それぞれに対応する oom_score_adj 値があります。

  • 保証: -997
  • ベストエフォート: 1000
  • バースト可能: min(max(2, 1000 — (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)

Pod が QoS 保証型の場合、その oom_score_adj 値は -997 なので、ノードのメモリが不足すると最後に終了される Pod になります。 BestEffort Pod は値 1000 に設定されているため、最初に終了します。

Pod の QoS を表示するには、次のコマンドを使用します。

 kubectl get pod -o jsnotallow='{.status.qosClass}'

以下は、PodGuaranteed QoS タイプを定義するコンピューティング ポリシーです。

  • Pod 内の各コンテナには、メモリ制限とメモリ要求が必要です。
  • Pod 内の各コンテナのメモリ制限は、メモリ要求と同じである必要があります。
  • Pod 内の各コンテナには、CPU 制限と CPU 要求が必要です。
  • ポッド内の各コンテナの CPU 制限は、CPU 要求と同じである必要があります。

終了コード 137 には、次の 2 つの一般的な状況があります。

1. 最も一般的な理由は、リソースの制限に関連しています。多くの場合、Kubernetes はコンテナに割り当てられたメモリ制限を超えます。

2. 別のケースは手動介入です。ユーザーまたはスクリプトがコンテナ プロセスに「SIGKILL」シグナルを送信し、この終了コードが生成されます。

トラブルシューティング方法

  1. ポッドログを確認する

OOMKilled エラーを診断する最初のステップは、Pod ログをチェックして、メモリ関連のエラー メッセージがあるかどうかを確認することです。

 kubectl describe pod <podname> State: Running Started: Fri, 12 May 2023 11:14:13 +0200 Last State: Terminated Reason: OOMKilled Exit Code: 137 ...

Pod ログをクエリすることもできます。

 cat /var/log/pods/<podname>

もちろん、(標準出力)を使用することもできます。

 kubectl logs -f <podname>
  1. メモリ使用量の監視

Prometheus や Grafana などの監視システムを使用して、Pod とコンテナのメモリ使用量を監視します。これにより、どのコンテナがメモリを過剰に消費し、OOMKilled エラーをトリガーしているかを特定できます。コンテナ ホスト上で dmesg を使用して、その時点の oomkiller シーンを表示することもできます。

  1. メモリアナライザの使用

pprof などのメモリ プロファイラーを使用して、過剰なメモリ使用の原因となっている可能性のあるメモリ リークや非効率的なコードを特定します。

修正方法

OOMKilled Kubernetes エラーの一般的な原因とその修正方法を以下に示します。

  1. コンテナのメモリ制限に達しました

これは、コンテナーで指定されたメモリ制限設定が正しくないことが原因である可能性があります。解決策としては、メモリ制限の値を増やすか、負荷増加の根本原因を調査して修正することです。一般的な原因としては、特に Pod 内で複数のコンテナが実行されている場合に大量のメモリ リソースを消費する可能性がある大きなファイルのアップロードや、トラフィック量の急増などが挙げられます。

  1. アプリケーションのメモリリークによりコンテナのメモリ使用量が上限に達しました

メモリ リークの原因を突き止めるには、アプリケーションをデバッグする必要があります。

  1. すべてのポッドで使用されるメモリの合計がノード上の使用可能なメモリを超えています

ノード上の使用可能なメモリを増やすことでノード メモリを増やすか、より多くのメモリを持つノードに Pod を移行します。ノード上で実行されているポッドのメモリ制限を調整して、メモリ制限内に収まるようにすることもできます。 Pod が使用するメモリの最小量を指定するメモリ要求設定にも注意する必要があることに注意してください。設定値が高すぎると、使用可能なメモリが効率的に使用されない可能性があります。リソース割り当てに関する提案については、「VPA コンポーネント」を参照してください。

メモリ要求と制限を調整する際、ノードが過負荷になると、Kubernetes は次の優先順位で Pod を終了します。

  • リクエストや制限のないポッド。
  • リクエストはあるが制限はないポッド。
  • メモリ要求値 (指定された最小メモリ値) よりも多くのメモリを使用するが、メモリ制限よりも少ないメモリを使用するポッド。
  • メモリ制限を超えて使用する Pod。

予防方法

OOMKilled の発生を防ぐ方法はいくつかあります。

  1. 適切なメモリ制限を設定する

ストレス テストと監視を通じてアプリケーションのメモリ使用量を決定し、上記の方法でコンテナーに許可されるメモリの最大量を設定します。過度に保守的になると、リソースの非効率的な利用により資金が無駄になる可能性があります。一方、過小評価すると、OOMKilled 現象が頻繁に発生する可能性があります。

  1. HPA

ベストプラクティスは、K8s が提供する HPA メカニズムを使用して、アプリケーションのメモリ使用量が増加したときに Pod レプリカの数を自動的に増やすことです。

  1. ノードリソースの割り当て

ノードにトラフィックを処理するのに十分なリソースがあることを確認します。

  1. アプリケーションのメモリ使用量を最適化する

アプリケーションを監視し、適切に最適化してメモリ消費を削減します。

  1. アプリケーションでのメモリリークを回避する

アプリケーションの観点から見ると、メモリ リークは長期間にわたってチェックおよび修正する必要があります。

著者の時間、視野、知識が限られているため、この記事には誤りや欠落が含まれる可能性があります。読者や業界の専門家が訂正したり意見を交換したりしてくれることを期待しています。

参考文献

1. https://spacelift.io/blog/oomkilled-exit-code-137

2. https://spacelift.io/blog/exit-code-127

3. https://cloud.tencent.com/developer/news/1152344

4. https://utcc.utoronto.ca/~cks/space/blog/linux/OOMKillerWhen

この記事はWeChatの公開アカウント「DCOS」から転載したもので、著者は「DCOS」で、以下のQRコードを通じてフォローできます。

この記事を転載する場合は、「DCOS」公開アカウントまでご連絡ください。

<<:  CKA 認定の合格率を向上: Kubernetes Ingress 7 層プロキシの完全ガイド!

>>:  K8s とは何ですか? また、そのアーキテクチャは何ですか?

推薦する

予測メンテナンスは、エッジコンピューティングIoTから始まるサービス指向の変革を可能にします

今は変革の時代です。デジタル化により製造業は急速に前進し、産業サービスやビジネスモデルの革新が加速し...

WeChat操作を通じてフォロワーを増やし、宣伝する方法、いくつかの非常に実用的なヒントとコツを共有します。

1. WeChat運用の基本的な考え方1. WeChatプラットフォームに精通し、柔軟に活用する私た...

コンテナ化への道: ビルド時間を盗んだのは誰ですか?

完全クラウド時代の到来により、多くの企業がコンテナ化の道を歩み始めており、Lao Liu 氏の会社も...

新しいサイトが含まれない要因と解決策

多くのウェブマスターは、この厄介な問題に遭遇します。なぜ私の新しいサイトはいつも含まれないのでしょう...

layerhost: 月額 4.99 ドル、ロサンゼルス VPS、PCCW、1G メモリ/1 コア/70g SSD/2T トラフィック

レイヤーホストのVPSは、当初の月額20ドルから現在の人気価格まで、新たな変革を迎えました。依然とし...

2021 年に注目すべき 8 つのエッジ コンピューティング トレンド

[[373788]]コンピューティングの今後とそれが組織の戦略にどのような影響を与えるでしょうか?専...

ケース分析: ウェブサイトのインデックスボリュームが減少した場合はどうすればよいでしょうか?

今日の話題に入る前に、今日お話しする内容をよりよく説明できるように、写真をお見せしましょう。上の写真...

profitserver: スペインのデータセンターの VPS の簡単なレビュー

Profitserver は常に無制限トラフィックの VPS サービスに重点を置いてきました。コア ...

Huawei Cloud Stack 8.1がリリースされ、政府と企業向けのインテリジェントアップグレードのベンチマークを設定

Huawei Connect 2021が9月23日に開幕しました。Huaweiは、ユーザーがデジタル...

エッジコンピューティングが商用 IoT ソリューションの構築にもたらす意味

ガートナーによると、2023年末までに、大企業の50%以上がIoT向けにインストールされた少なくとも...

ハイブリッド クラウドは本当に私たちに適しているのでしょうか?企業はハイブリッドクラウドをどのように活用する予定ですか?

1. ハイブリッド クラウドは当社のビジネスに適していますか?近年、クラウド技術の活発な発展に伴い、...

Azure PaaS サービスに安全に接続する方法

[[423609]] [51CTO.com クイック翻訳]ご存知のとおり、PaaS ベースのサービス...

Googleのランキングは単純なウェブページの最適化ではない

GOOGLE ランキングについて話すとき、多くの友人はそれが単一の Web ページ タグの最適化プロ...

WeChat Momentsネイティブプロモーションページ広告がオンラインになりました!オリンピックマーケティングの革新的な方法!

リオオリンピックの開幕とともに、Momentsのネイティブプロモーションページ広告が開始され、NIK...

WeChat公開会議で明らかにされた殺意、最も価値のある情報はここにある

Titanium Media Note: 昨日のWeChatパブリックコミュニケーションカンファレン...