本物の故障を作って読む
このラボは本物の障害が起きるクラスター上で動きます
VMの中に本物のk3sが起動しています。kubeletとcontainerdが実際に動いているので、イメージを取得できなければImagePullBackOffと表示され、プロセスが死ねばCrashLoopBackOffになり、メモリを超えれば本当にOOMKilledになります。
CKAコースのほかのラボが動く偽のクラスターでは、これらの症状を作ることすらできません。そのため、これまでは文章だけで学んできました。
最初の起動に2分ほどかかります。
目標
6つの障害をわざと作り、それぞれをどこでどのように読み取るかを、手で覚えます。最後に、1つの分類表にまとめます。
なぜ重要なのか
問題解決は、知識ではなく反射神経です。kubectl get podに表示された文字を見て、3秒以内に「次に見る場所」が思い浮かぶ必要があります。
そして、似ているように見える症状は、原因がまったく違います。
PendingとContainerCreatingは、どちらも「まだ起動していない」ですが、前者はスケジューラーの問題で、後者はkubeletの問題です。livenessの失敗とreadinessの失敗は、どちらも「プローブが失敗した」ですが、前者は再起動を招き、後者はトラフィックからだけ外します。- 存在しないConfigMapを
envで参照するとCreateContainerConfigErrorで、同じものをボリュームとして参照するとPendingです。
これらの区別は、暗記できません。自分で作ってみてはじめて、体に残ります。
ステップ
すべてのPodは、brokenネームスペースに作成します。名前は決まっています。
ts-image: 存在しないイメージでImagePullBackOffを作成し、イベントから実際の理由を読み取って記録してください(保存先:/root/cka/imagepull.txt)。そのあと、修正版を起動してください(名前:ts-image-fixed)。ts-crash: すぐに死ぬコマンドでCrashLoopBackOffを作成し、すでに死んだコンテナのログを読み取って記録してください(保存先:/root/cka/crashloop.txt)。再起動回数も一緒に書きます。ts-oom: メモリのlimitsを超えて使うコンテナでOOMKilledを作成し、終了コードと一緒に記録してください(保存先:/root/cka/oom.txt)。ts-liveness・ts-readiness: それぞれ、失敗するプローブを1つだけ設定し、結果がどう違うかを記録してください(保存先:/root/cka/probe.txt)。ts-pending: スケジュールされえないPodを作成し、スケジューラーが残した理由を記録してください(保存先:/root/cka/pending.txt)。PendingとContainerCreatingの違いも書きます。ts-config(env参照)・ts-volume(ボリューム参照): どちらも存在しないConfigMapを指すようにし、状態がなぜ違うのかを記録してください(保存先:/root/cka/configref.txt)。- 症状5つの分類表を作成してください(保存先:
/root/cka/triage.md)。各行は증상 · 어디를 볼까 · 흔한 원인の形式です(韓国語の3つの見出しは、順に「症状」「どこを見るか」「よくある原因」という意味です)。 - 次の4行と、何を先に見るかを書いてください(保存先:
/root/cka/report.md)。oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods=の4行です。
参考
- イベントは、
kubectl -n broken describe pod <이름>の下部のEvents:にあります(プレースホルダーはPod名です)。kubectl get events --sort-by=.lastTimestampで、全体を時系列に見ることもできます。 - すでに死んだコンテナのログは、
kubectl logs <파드> --previousです(プレースホルダーはPod名です)。これを知らないと、CrashLoopBackOffを永遠に診断できません。現在のコンテナは、まだログを残す前だからです。 - 終了の理由とコードは、
kubectl get pod <이름> -o jsonpath='{.status.containerStatuses[0].lastState.terminated}'にあります(プレースホルダーはPod名です)。 - メモリをわざと使うには、
dd if=/dev/zero of=/dev/shm/x bs=1M count=<큰 수>が簡単です(プレースホルダーは大きな数です)。 - よくあるミス1: 3で、
requestsだけを与えて、limitsを与えないことです。OOMは、limitsを超えたときに起こります。 - よくあるミス2: 4で、2つのプローブを1つのPodに一緒に設定することです。そうすると、どちらのプローブで再起動したのか区別できません。
イメージを取得できないとき
ts-image: 存在しないイメージでImagePullBackOffを作成し、イベントから実際の理由を読み取って記録してください(保存先: /root/cka/imagepull.txt)。そのあと、修正版を起動してください(名前: ts-image-fixed)。
存在しないタグを指定すればよいです。状態だけを見ず、describeのEventsで実際の理由を読んでください。
すでに死んだコンテナのログを読む
ts-crash: すぐに死ぬコマンドでCrashLoopBackOffを作成し、すでに死んだコンテナのログを読み取って記録してください(保存先: /root/cka/crashloop.txt)。再起動回数も一緒に書きます。
kubectl logs <파드>は現在のコンテナを見ます(プレースホルダーはPod名です)。さっき死んだものを見るには、--previousが必要です。
メモリを超えると137で死ぬ
ts-oom: メモリのlimitsを超えて使うコンテナでOOMKilledを作成し、終了コードと一緒に記録してください(保存先: /root/cka/oom.txt)。
limits.memoryを小さく指定し、それより多く使わせてください。終了コードが何を意味するかも、一緒に書きます。
2つのプローブは結果が違う
ts-liveness・ts-readiness: それぞれ、失敗するプローブを1つだけ設定し、結果がどう違うかを記録してください(保存先: /root/cka/probe.txt)。
1つのPodには、プローブを1つだけ設定してください。両方を一緒に設定すると、どちらのために再起動したのか区別できません。
Pendingはスケジューラーの問題
ts-pending: スケジュールされえないPodを作成し、スケジューラーが残した理由を記録してください(保存先: /root/cka/pending.txt)。PendingとContainerCreatingの違いも書きます。
ノードが提供できないリソースを要求すればよいです。スケジューラーは、なぜ配置できなかったのかをイベントに残します。
同じ原因、違う症状
ts-config(env参照)・ts-volume(ボリューム参照): どちらも存在しないConfigMapを指すようにし、状態がなぜ違うのかを記録してください(保存先: /root/cka/configref.txt)。
存在しないConfigMapをenvFromで参照したPodと、ボリュームとして参照したPodを、それぞれ作成して、状態を比較してください。
1つの表にまとめる
症状5つの分類表を作成してください(保存先: /root/cka/triage.md)。各行は증상 · 어디를 볼까 · 흔한 원인の形式です(韓国語の3つの見出しは、順に「症状」「どこを見るか」「よくある原因」という意味です)。
各行は증상 · 어디를 볼까 · 흔한 원인の形式です(韓国語の3つの見出しは、順に「症状」「どこを見るか」「よくある原因」という意味です)。試験会場で、3秒以内に次の行動が思い浮かぶようにすることが目的です。
何を学んだか
次の4行と、何を先に見るかを書いてください(保存先: /root/cka/report.md)。oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods=の4行です。
oom_exit_code=、liveness_restarts=、readiness_restarts=、broken_pods=の4行と一緒に、調査の順序を書いてください。