TT Lab
はじめる
学ぶ 学習パス コース

CKA — Kubernetes管理者

症状を読むのは反射神経だ

TT Labで続きを見る

一言でいうと

問題解決は、文章では身につきません。kubectl get podに表示された文字を見て、3秒以内に次に見る場所が思い浮かぶ必要がありますが、それは自分で障害を作ってみてはじめて、体に残ります。

なぜ本物の障害でなければならないのか

CKAは、問題解決が配点の大きな部分を占めます。ところが、前のモジュールが動いている偽のクラスターには、kubeletもコンテナランタイムもないので、障害そのものを作れませんでした。

症状 偽のクラスターでは
ImagePullBackOff イメージを取得しないので発生しません
CrashLoopBackOff プロセスがないので、死ぬこともありません
OOMKilled メモリを使わないので、超過することがありません
プローブ失敗による再起動 プローブを実行しません
PVCBound プロビジョナーがないので、永遠にPendingです

そのため、「この症状は何を意味するのか」を、文章だけで学ぶしかありませんでした。問題解決は、そのようには身につきません。kubectl get podに表示された文字を見て、3秒以内に次に見る場所が思い浮かぶ必要がありますが、それは自分で作ってみてはじめて、体に残ります。

似ているのに原因が違うもの

3つだけ覚えておけばよい

  1. describeのEventsを先に見ます。状態名は、どこで詰まったかだけを教えてくれます。何がないのかは、常にイベントにあります。
  2. logsが空なら--previousです。CrashLoopBackOffのPodの現在のコンテナは、まだ何も出力していません。
  3. NODE列を見ます。空ならスケジューラー、埋まっていればkubeletです。この1行で、調査の範囲が半分になります。

症状ごとに次に見る場所

状態名を原因に直接結び付けず、次にどこを見るかに結び付けると、調査がはるかに速くなります。以下は、その対応表です。

状態 次に見る場所 よくある原因
Pending、NODEが空 describe podのEvents requestsがノードの余裕より大きい、テイント、ノードセレクターがどのノードとも合わない
Pending、ボリューム関連 PVCの状態とStorageClass プロビジョナーがない、またはアクセスモードが合わない
ContainerCreatingが長い そのノードのkubelet イメージが大きい、ボリュームのマウントが終わらない、Secretがない
ImagePullBackOff Eventsのpull失敗の行 タグのタイプミス、プライベートレジストリの資格情報がない、ネットワークの遮断
CrashLoopBackOff logs --previous 設定がなくてすぐに終了する、依存サービスに届かない
OOMKilled describeのLast State limitsが実際の使用量より小さい
CreateContainerConfigError 参照したConfigMap・Secret 名前のタイプミス、またはまだ作成されていない
Runningなのにトラフィックがない エンドポイントとreadiness セレクターがラベルと合わない、またはreadinessが失敗し続けている

最後の行は、特によく人を引っかけます。PodはRunningでログも正常なのに、リクエストが1つも入ってこない状況です。このとき見るべきなのは、Podではなくサービスのエンドポイントです。空なら、2つのうちどちらかです。サービスのセレクターがPodのラベルと合わないか、readinessプローブが失敗して、Podが一覧から外れているかです。2つの場合を分ける方法は簡単です。PodにReady 0/1と表示されていればプローブの問題で、Ready 1/1なのにエンドポイントが空なら、セレクターの問題です。

ノード自体が問題のときも、Podの症状として最初に現れます。ノードがNotReadyになると、その上のPodはしばらくRunningのまま残り、一定時間が過ぎてはじめて片付けられます。そのため、「PodはRunningなのに応答がない」という状況では、Podだけを見ずに、kubectl get nodesを一度実行する習慣が必要です。この1行が、数十分を節約してくれます。

実務で本当に大切なこと

状態名ではなく、Eventsを先に読みます。状態は、どこで詰まったかだけを教えてくれて、何がないのかは、常にイベントにあります。試験でも実務でも、この順序を入れ替えると、時間を2倍使います。

NODE列1つで、調査の範囲が半分になります。空ならスケジューラー、埋まっていればkubeletです。kubectl get pod -o wideを習慣にすれば、この分岐が無料でついてきます。

CrashLoopBackOffでは、--previousなしにログを見ません。現在のコンテナは、作り直されたばかりで、まだ何も出力していません。空のログを見て「ログがない」と判断するのが、最もよくある無駄足です。

次の2つのラボで、これらを自分で作ってみます。