はじめに
認定アプリケーション開発者試験(CKAD)の勉強をするにあたって検索するとよく出てくる以下のサイトなどの演習問題をやっていると、Podを作るときに--restart=Never
というオプションが結構出てきます。そこでこのオプションを付ける必要はあるのか、またどういうときに付けたほうがいいのかについて調べてみました。
- https://github.com/dgkanatsios/CKAD-exercises
- https://medium.com/bb-tutorials-and-thoughts/practice-enough-with-these-questions-for-the-ckad-exam-2f42d1228552
--restart=~
オプションの挙動
まず公式ドキュメントのkubectl run
の部分を確認すると以下のように書いてありました。
これから、restartが取れる値はAlways,OnFailure,Never
の3つであることとデフォルト値がAlways
であることが分かります。
公式ドキュメントにはこれ以上の記載はなかったため調べてみると、restartポリシーの値によって作られるものの種類が変わるという記事が出てくるが、これはkubectlのバージョン1.18までの挙動であり1.19以降では何に設定してもPodが作成されます。(kubernetesのrestartPolicyを理解するの記事に以前どう記載されていたかも載っていました)
$ kubectl run nginx-always --image=nginx --restart=Always
$ kubectl run nginx-onfailure --image=nginx --restart=OnFailure
$ kubectl run nginx-never --image=nginx --restart=Never
# 全てPodで作成される
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-always 1/1 Running 0 2m50s
nginx-never 1/1 Running 0 2m16s
nginx-onfailure 1/1 Running 0 2m29s
以上から現在のrestart
の値の意味がよく分からなかったですが、もう少しだけ調べてみました。
ls
で存在するディレクトリと存在しないディレクトリを指定してみます。
# コマンドが成功
$ kubectl run busybox-always-ok --image=busybox --restart=Always -- ls /etc
$ kubectl run busybox-onfailure-ok --image=busybox --restart=OnFailure -- ls /etc
$ kubectl run busybox-never-ok --image=busybox --restart=Never -- ls /etc
# コマンドが失敗
$ kubectl run busybox-always-ng --image=busybox --restart=Always -- ls /notexist;
$ kubectl run busybox-onfailure-ng --image=busybox --restart=OnFailure -- ls /notexist;
$ kubectl run busybox-never-ng --image=busybox --restart=Never -- ls /notexist
作られたPodを確認してみます。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
busybox-always-ok 0/1 CrashLoopBackOff 2 51s
busybox-always-ng 0/1 CrashLoopBackOff 1 29s
busybox-never-ok 0/1 Completed 0 46s
busybox-never-ng 0/1 Error 0 12s
busybox-onfailure-ok 0/1 Completed 0 51s
busybox-onfailure-ng 0/1 CrashLoopBackOff 1 19s
Alwaysはコマンドの成功失敗にかかわらずPodが再起動しています。それに対しOnFailureはコマンドが成功した場合は完了し、失敗した場合は再起動を行っています。Neverはコマンドが成功した場合は完了、失敗した場合もエラーのまま再起動を行わないことが分かります。
実行コマンド\--restart
|
Always | OnFailure | Never |
---|---|---|---|
成功 | 再起動 | 完了 | 完了 |
失敗 | 再起動 | 再起動 | 完了(エラー) |
デフォルトの--restart=Always
のままにしておくと、正常に実行されていてもCrashLoopBackOff
と表示されてしまうため、多少時間がかかっても--restart=Never
を付けたほうがyamlファイルの間違いなどにも気づきやすいかもしれないと思いました。
--restart=Never
を付けないといけない場合
--restart=Never
を付けないといけない場合として、作ったnginxPodに別のPodからアクセスできるかを試したい場合などは付ける必要がありました。
$ kubectl run nginx --image=nginx --port=80
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 77s 10.1.3.88 docker-desktop <none> <none>
# --restart=Neverを付ける必要がある
$ kubectl run busybox --image=busybox --restart=Never --rm -it -- sh -c "wget -O- 10.1.3.88"
Connecting to 10.1.3.88 (10.1.3.88:80)
writing to stdout
・
・
・
これに--restart=Never(OnFailure)
を付けなかった場合、いくら待っても結果が返ってこなかったです。
おそらくコマンドを実行した後Podの再起動が始まってしまうため、いつまでもPodが完了せず結果が返ってこないのだと思います。
結論
restart
オプションはつけなくていい場合も結構多いのですがCrashLoopBackOff
の文字は試験中だと結構焦ってしまうため、CKADの試験に当たっては不安なら--restart=Never
を付けたほうが無難かもしれないと思いました。