LoginSignup
68
41

More than 5 years have passed since last update.

Kubernetes: kubectl 上の Pod のステータス表記について

Last updated at Posted at 2018-12-03

kubectl で Pod を表示した場合、RunningTerminating などのステータスが表示されます。しかし、このステータスは Pod オブジェクトの単一フィールドを表示しているわけではなく、いくつかのフィールドと条件によって表示が分けられています。

この記事ではよく見る Pod のステータス表記について整理してみます。

kubectl のステータスの出し分け

ご存じの通りkubectl で Pod を表示したとき、下記のように STATUS カラムで Pod のステータスを見ることができます。

$ kubectl get pods -w
NAME      READY     STATUS    RESTARTS   AGE
myapp     0/1       Pending   0          0s
myapp     0/1       ContainerCreating   0         0s
myapp     1/1       Running   0         1s
myapp     1/1       Terminating   0         8s

Pod の状態は主に pod.status フィールドにて PodStatus というオブジェクトで管理されています。PodStatus には Phase というフィールドがありますが、kubectl は単純にこれを表示しているわけではありません。

kubectl の Pod のステータス表示のロジックは主に printers.go の printPod() という関数になります。

この関数では下記の Pod のフィールドを参照して Pod のステータスを出しています。より詳細な情報があればそれを優先して表示されるようになっています。例えば、pod.status.phasependingcontainerStatuses.state.waiting.reasonContainerCreating の場合は、ContainerCreating が表示されます。

  • pod.status PodStatus オブジェクト
    • phase Pod のフェーズ。Pending, Running, Succeede, Failed, Unknown の値が入る
    • reason Pod の今の状態に至った理由
  • pod.status.initContainerStatuses initContainer 用の ContainerStatus の配列
    • restartCount 再起動した階数
    • state.waiting.reason 処理を待っている理由 (CrashLoopBackoff など)
    • state.terminated.exitCode 終了した場合の終了コード
    • state.terminated.reason 終了した場合の理由
    • state.terminated.signal 終了した場合のシグナル
  • pod.status.containerStatuses 通常のコンテナ用の ContainerStatus の配列
    • restartCount 再起動した階数
    • state.waiting.reason 処理を待っている理由 (CrashLoopBackoff など)
    • state.terminated.exitCode 終了した場合の終了コード
    • state.terminated.reason 終了した場合の理由
    • state.terminated.signal 終了した場合のシグナル
    • state.running 動作中かどうか
    • ready ready 状態かどうか
  • pod.metadata ObjectMeta オブジェクト
    • deletionTimestamp 削除が始まったときに入る時間

また Pod は複数のコンテナ(通常のコンテナ + initContainers) から構成されるので、エラーがあるコンテナの情報が優先的に表示されたりといった工夫をしているため注意が必要です。コンテナすべての情報を見たい場合は、kubectl describekubectl get pod -o yaml でオブジェクト全体を見たほうが良いでしょう。

代表的な Pod のステータス表記

ステータス表示のもととなるフィールドで分類して、代表的な kubectl の Pod のステータス表記を以下にまとめました。

pod.status.phase

  • Pending Pod オブジェクトが作成され、まだ全てのコンテナが起動していない状態。フィールドの値としてはコンテナの起動中なども含むが、ContainerCreating などの表記が優先されて表示されるため、kubectl ではコンテナ起動を行う前までがこの表記となる。
  • Running すべてのコンテナが起動している状態

pod.status.reason

  • Unknown Pod の削除前 (deletionTimestamp が入る前)にノードが未応答 (NodeLost)になったもの
  • NodeLost Pod の削除中 (deletionTimestamp が入っている)にノード未応答になったもの
  • Evicted Pod が退避 (Evict)対象となった。Evict はノードのリソースが足りなくなった場合に行われる。

metadata.deletionTimestamp

  • Terminating Pod の削除時間 (deletionTimestamp) が入っていて、reasonNodeLost ではないもの。終了処理 (preStop やシグナルハンドリング)中の Pod。終了処理が終わると Pod オブジェクト自体が削除される

initContainerStatuses.state.terminated.exitCode

  • Init:0/3 initContainers のうち処理が終わった(終了コードが0)コンテナ数
  • Init:Error initContainers のコンテナのいずれかエラーが発生した

containerStatuses.state.waiting.reason

  • ContainerCreating すべてのコンテナが起動するのを待っている状態。コンテナイメージの pull もここに含まれる。(initContainer がない場合)
  • PodInitializing すべてのコンテナが起動するのを待っている状態。コンテナイメージの pull もここに含まれる。 (initContainer がある場合)
  • CreateContainerError いずれかのコンテナの作成時にコンテナランタイム側で処理に失敗した。kubectl describe で詳細を確認する必要がある。
  • PostStartHookError いずれかのコンテナの postStart フックが異常終了した
  • CrashLoopBackOff コンテナのいずれかが再起動を待っている状態 (後述)
  • ErrImagePull コンテナのいずれかが pull に失敗した
  • ImagePullBackOff コンテナのいずれかが再 pull を待っている状態 (後述)

containerStatuses.state.terminated.reason

  • Completed restartPolicynever (コンテナを再起動しない設定)ですべてのコンテナが正常終了した
  • Error コンテナのいずれかが異常終了 (終了ステータスが 0 以外)した
  • OOMKilled メモリが足りず OOM (Out of Memory) Killer によって kill された。resources の limit のメモリが足りているか要確認

BackOff について

CrashLoopBackoffImagePullBackOffBackOff はリトライの間隔を Exponential Backoff というアルゴリズムで、間隔を指数関数的に増やしていくことを意味しています。

Kubernetes 1.12.3 の実装では CrashLoopBackoffImagePullBackOff のリトライ間隔(backoff)は以下のようになっています。

例えばコンテナが起動時に異常終了した(終了コードが 0 以外) 場合は、下記のように ErrorCrashLoopBackoff のステータスが交互に現れることになります。

$ kubectl get pods -w
myapp   1/2   Error   0     7s
myapp   1/2   Error   1     11s
myapp   1/2   CrashLoopBackOff   1     12s
myapp   1/2   Error   2     27s
myapp   1/2   CrashLoopBackOff   2     38s
myapp   1/2   Error   3     52s
myapp   1/2   CrashLoopBackOff   3     63s
myapp   1/2   Error   4     100s

まずコンテナが異常終了したため、終了理由 containerStatuses.state.terminated.reasonError が入り、次に BackOff の時間を待っている間、待ち理由 containerStatuses.state.waiting.reasonCrashLoopBackoff が入ります。再度コンテナが起動して異常終了し、これを繰り返すためこのような表示になります。

Pod のステータスの例

initContainer を持たない場合

initContainer を持たない Pod の場合、下記のようにステータスが変化していきます。

$ kubectl get pods -w

NAME    READY   STATUS    RESTARTS   AGE
# Pod オブジェクトが作成された時点で Pending になる
myapp   0/1   Pending   0     0s
# Pod がスケジュールされ kubelet でこの状態になる
myapp   0/1   ContainerCreating   0     0s
# すべてのコンテナが立ち上がると Running になる
myapp   1/1   Running   0     6s
# 終了処理中は Terminating となる
myapp   1/1   Terminating   0     10s
myapp   0/1   Terminating   0     10s

initContainer を持つ場合

initContainer を持つ Pod の場合、少しステータスの変化が異なります。以下の例では initContainer 3 つ、コンテナ 3つの Pod の起動例です。

$ kubectl get pods -w

NAME    READY   STATUS    RESTARTS   AGE
# Pod オブジェクトが作成された時点で Pending になる
myapp   0/3   Pending   0     0s
# initContainers の初期化が始まる (3つ分)
myapp   0/3   Init:0/3   0     0s
myapp   0/3   Init:1/3   0     4s
myapp   0/3   Init:2/3   0     8s
# initContainers の初期化が終わると、PodInitializing の表記になる。
myapp   0/3   PodInitializing   0     12s
# コンテナが起動していく (3つ分)
myapp   0/3   Running   0     23s
myapp   1/3   Running   0     34s
myapp   2/3   Running   0     49s
myapp   3/3   Running   0     55s
# 終了中は Terminating の表記となる
myapp   3/3   Terminating   0     69s
myapp   0/3   Terminating   0     99s

まとめ

kubectl のステータスは様々なフィールドを参照して表示しています。kubectl get pods -w で遷移をウォッチしてみるとステータスの遷移がわかりデバッグ時にも役立ちます。


このエントリは、弊社 Z Lab のメンバーによる Z Lab Advent Calendar 2018 の3日目として業務時間中に書きました。4日目は @watawuwu の担当です。

68
41
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
41