Podからセルフヒーリングまで
目標
Pod1つを手で起動するところから始めて、Deployment・Job・CronJob・DaemonSetをそれぞれ作り、所有関係(ownerReferences)をたどったあと、Podをわざと削除してセルフヒーリングが実際に動くことを、削除前後の一覧で証明します。
なぜ重要なのか
現場でPodを直接作ることはほとんどありません。それでもPodを理解しなければならない理由は、すべてのワークロードコントローラーが、結局のところPodテンプレートを抱えた外側の殻だからです。Deploymentの問題は、ほとんどがPodテンプレートの問題です。
コントローラーを選ぶ基準は1つに要約できます。このプロセスは自分で終わるのか。終わらないサービスにJobを使うと永遠に完了せず、終わるバッチにDeploymentを使うと終了のたびに再起動されて、CrashLoopBackOffのように見えます。新人が最もよく起こす事故です。
最後のステップがこのラボの核心です。「Podを削除すると再び作られる」という話は誰でも知っていますが、戻ってきたPodが同じPodではないことを目で見た人は少数です。名前が変わるという事実1つが、「Podの名前に依存するな」「状態をPodの中に置くな」といった原則すべての根拠です。
ステップ
- ネームスペース
kcna-workを作成し、その中にイメージがnginx:1.27-alpineのPodhelloを作成して、Runningになるまで進めてください。 - 同じネームスペースにDeployment
webを作成してください。イメージはnginx:1.27-alpine、replicasは3、Podテンプレートのラベルはapp=webです。 webのreplicasを5に増やし、5個すべてがReadyになるまで待ってください。webが作ったReplicaSetの名前を/root/kcna-work/rs-name.txtに1行で保存し、webのPodを1つ選んで、そのPodのmetadata.ownerReferences[0].kindの値を/root/kcna-work/owner.txtに1行で保存してください。- 同じネームスペースにJob
reportを作成してください。イメージはbusybox:1.36、completionsは3です。そしてCronJobnightlyを作成してください。scheduleは毎日03:00(0 3 * * *)です。 - 同じネームスペースにDaemonSet
node-agentを作成してください。イメージはbusybox:1.36で、コンテナがすぐに終了しないよう、長時間動き続けるコマンドを指定してください。 - セルフヒーリングを証明してください。(a)
webのPod名5個を/root/kcna-work/before.txtに保存し、(b)そのうち1つを削除したあと、削除した名前を/root/kcna-work/deleted.txtに1行で保存し、(c)新しいPodがReadyになってから、Pod名5個を/root/kcna-work/after.txtに保存してください。
参考
- Podの名前だけを取り出すときは、
kubectl get pods -n kcna-work -l app=web -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'が便利です。 kubectl get rs -n kcna-workでReplicaSetの名前を確認し、kubectl get rs <이름> -n kcna-work -o yamlでownerReferencesを見られます(プレースホルダーはReplicaSet名です)。- DaemonSetには
kubectl createのサブコマンドがないため、YAMLを自分で書いてapplyする必要があります。spec.selector.matchLabelsとspec.template.metadata.labelsは同じでなければなりません。 - よくあるミス1: ステップ5のJobの
restartPolicyを空のままにしてしまうことです。デフォルト値のAlwaysはJobでは拒否されます。 - よくあるミス2: ステップ7でPodを削除した直後に、すぐ
after.txtを取得してしまうことです。新しいPodがまだ一覧になく、5行になりません。
最初のPodを起動する
ネームスペースkcna-workを作成し、その中にイメージがnginx:1.27-alpineのPodhelloを作成して、Runningになるまで進めてください。
先にネームスペースを作成し、その中にPodを作成します。kubectl runで素早く作るか、YAMLを書いてもかまいません。PodがRunningになるまで数秒かかることがあるので、状態を確認してから採点してください。
DeploymentにPodの管理を任せる
同じネームスペースにDeploymentwebを作成してください。イメージはnginx:1.27-alpine、replicasは3、Podテンプレートのラベルはapp=webです。
kubectl create deploymentは、Podテンプレートのラベルを自動で付けてくれます。どのラベルが付いたか、-o yamlで一度確認してみてください。準備ができたレプリカ数は、status側で見られます。
レプリカ数を変更する
webのreplicasを5に増やし、5個すべてがReadyになるまで待ってください。
kubectl scaleで1行で済ませることも、マニフェストを修正して再度applyすることもできます。どちらが記録に残る方式なのか考えてみてください。採点はspecとstatusの両方を見ます。
所有関係をたどる
webが作ったReplicaSetの名前を/root/kcna-work/rs-name.txtに1行で保存し、webのPodを1つ選んで、そのPodのmetadata.ownerReferences[0].kindの値を/root/kcna-work/owner.txtに1行で保存してください。
ネームスペースのReplicaSet一覧を見ると、名前の後ろにハッシュが付いています。そのオブジェクトのmetadata.ownerReferencesを-o jsonpathや-o yamlで開くと、誰が作ったのかがわかります。Pod側も同じフィールドを持っています。
終わる仕事: JobとCronJob
同じネームスペースにJobreportを作成してください。イメージはbusybox:1.36、completionsは3です。そしてCronJobnightlyを作成してください。scheduleは毎日03:00(0 3 * * *)です。
JobのPodテンプレートは、restartPolicyにAlwaysを使えません。なぜなのか考えてみれば、値が決まります。CronJobのscheduleは、標準的なcron表記の5桁です。
ノードごとに1つ: DaemonSet
同じネームスペースにDaemonSetnode-agentを作成してください。イメージはbusybox:1.36で、コンテナがすぐに終了しないよう、長時間動き続けるコマンドを指定してください。
DaemonSetのマニフェストには、replicasフィールドがありません。個数を決める主体が人ではないからです。kubectl createでは作れないので、YAMLを自分で書く必要があり、selectorとtemplate.metadata.labelsが一致している必要があります。
Podを削除してセルフヒーリングを証明する
セルフヒーリングを証明してください。(a)webのPod名5個を/root/kcna-work/before.txtに保存し、(b)そのうち1つを削除したあと、削除した名前を/root/kcna-work/deleted.txtに1行で保存し、(c)新しいPodがReadyになってから、Pod名5個を/root/kcna-work/after.txtに保存してください。
削除前の一覧、削除した名前、削除後の一覧を、それぞれファイルに残してはじめて採点が成立します。削除後の一覧は、コントローラーが新しいPodを作ったあとに取得してはじめて5行になります。戻ってきたPodの名前が、削除したものと同じか違うか、自分で確認してみてください。