ログで原因を絞る
このラボは本物のVM上で動きます
この環境はPodではなく、KubeVirtが起動した仮想マシンです。Linuxカーネルが別に動き、systemdが実際にサービスを管理し、dockerは模倣ではなく本物のDockerエンジンです。docker runで起動したコンテナは実際にプロセスになり、docker execもdocker logsもそのまま動作します。
以前はこのラボがPodの中で動いており、カーネル権限をすべて落とした環境だったため、コンテナを起動するステップがすべて塞がれていました。今は塞がれたステップはありません。
知っておくべきことが2つあります。
- 最初の起動に1分ほどかかります。VMが起動してDockerをインストールするためです。Podのラボ(通常40秒)より遅くなります。
- ブラウザープレビューはありません。VMへの接続は、採点用のポート1つしか開いていません。Webサーバーを起動した場合は、VMの中で
curlを使って確認してください。
目標
生きているコンテナと死んだコンテナをそれぞれ診断し、ログ・終了コード・状態フィールドの3つで原因を絞り込む順序を身につけます。
なぜ重要なのか
コンテナの診断が難しいのは、情報がないからではなく、どこを見るかの順序がないからです。順序があれば、たいていは3分以内に終わります。ログを最初に見るのは、アプリ自身が残した最後の言葉だからです。その次に終了コードを見るのは、ログが空のとき(つまりシグナルで即死したとき)、それが唯一の手がかりだからです。この順序は、あとでKubernetesでもそのまま使います。道具の名前が変わるだけです。
ステップ
/root/dk3を作成し、dk-noisyコンテナがline-1からline-50までを出力し、最後にdone-50を出力して終了するようにします。dk-noisyのログの最後の5行だけを/root/dk3/tail5.txtとして保存します。dk-errコンテナを作成し、標準出力にto-stdout、標準エラー出力にto-stderrを出力させたうえで、標準出力だけを/root/dk3/out.txtに、標準エラー出力だけを/root/dk3/err.txtに、分離して保存します。dk-noisyのログにタイムスタンプを付け、最初の1行だけを/root/dk3/ts.txtとして保存します。nginx:1.27-alpineでdk-web2を起動し、その中でnginxのバージョンを確認して/root/dk3/nginx-version.txtとして保存します。dk-crashコンテナを作成し、startingを出力したあと、存在しないパスを読んで失敗させます。そして/root/dk3/crash.txtに、exit=<실제 종료코드>を1行で書きます(プレースホルダーは実際の終了コードです)。dk-noisyのログにline-が何回出てくるかを数え、/root/dk3/count.txtに数字だけを書きます。/root/dk3/triage.mdに、dk-noisy、dk-crash、dk-web2の3つのコンテナを1行ずつ書きます。各行にコンテナ名と現在の状態を一緒に入れ、dk-crashの行には終了コードも入れます。
参考
docker logs --tail N、docker logs -tを使います。- nginxのバージョンは標準エラー出力に出ます。
2>&1で受け取らないと、ファイルに入りません。 - よくある間違い1: ステップ1で
--rmを付けると、ログを見るためのコンテナが残りません。 - よくある間違い2: ステップ7で、
done-50もline-を含むかどうかを確認してください。採点では、実際のログを数え直して照合します。
ログを大量に出すコンテナを作る
/root/dk3を作成し、dk-noisyコンテナがline-1からline-50までを出力し、最後にdone-50を出力して終了するようにします。
ループで複数行を出力させ、最後に完了の印を残してください。コンテナが最後まで実行されてはじめて、最後の行が出ます。
最後の数行だけを見る
dk-noisyのログの最後の5行だけを/root/dk3/tail5.txtとして保存します。
ログが長いときは、先頭ではなく末尾を見る必要があります。出力する行数を制限するオプションがあります。
標準出力と標準エラー出力を分離する
dk-errコンテナを作成し、標準出力にto-stdout、標準エラー出力にto-stderrを出力させたうえで、標準出力だけを/root/dk3/out.txtに、標準エラー出力だけを/root/dk3/err.txtに、分離して保存します。
docker logsは、2つのストリームをそれぞれそのまま流します。シェルのリダイレクトで、片方ずつ絞り込めます。
いつ出力されたログかを調べる
dk-noisyのログにタイムスタンプを付け、最初の1行だけを/root/dk3/ts.txtとして保存します。
タイムスタンプを付けるオプションがあります。先頭にRFC3339形式の時刻が付いた最初の1行だけを保存してください。
動いているコンテナの中を確認する
nginx:1.27-alpineでdk-web2を起動し、その中でnginxのバージョンを確認して/root/dk3/nginx-version.txtとして保存します。
nginxは、バージョンを標準エラー出力に出力します。リダイレクトを忘れると、ファイルが空に見えることがあります。
失敗したコンテナを診断する
dk-crashコンテナを作成し、startingを出力したあと、存在しないパスを読んで失敗させます。そして/root/dk3/crash.txtに、exit=<실제 종료코드>を1行で書きます(プレースホルダーは実際の終了コードです)。
ログの最後の行と終了コードを一緒に見ると、原因が特定できます。終了コードはinspectで確認してください。
ログからパターンを数える
dk-noisyのログにline-が何回出てくるかを数え、/root/dk3/count.txtに数字だけを書きます。
ログをファイルに移さず、パイプでそのまま数えても構いません。正確な個数を数え、ファイルには数字だけを残してください。
3つのコンテナの状態をまとめる
/root/dk3/triage.mdに、dk-noisy、dk-crash、dk-web2の3つのコンテナを1行ずつ書きます。各行にコンテナ名と現在の状態を一緒に入れ、dk-crashの行には終了コードも入れます。
各コンテナの実際の状態と終了コードをinspectで確認し、1行ずつ書いてください。死んでいるものには、終了コードも一緒に必要です。