機雷がなんだ! 全速前進!

SEというかプログラマというか、日々のエンジニア生活の中で体験したことなどを中心に書きためていくことにする。

コンテナイメージの違いによる pod のふるまい

f:id:orinbou:20200506225742p:plain

コンテナイメージの違いによる pod のふるまいに関するちょっとしたメモです。

TL;DR

下記の流れでコンテナイメージの違いによる pod のふるまいの違いを確認しました。

  • サンプルpodを作成&起動確認(メインプロセスなし <= コンテナイメージ:busybox)
  • サンプルpodを作成&起動確認(メインプロセスあり <= コンテナイメージ:nginx)
  • サンプルpodを作成&起動確認(メインプロセスあり <= コンテナイメージ:busybox + command)
  • まとめ

やったこと

まずk8sクラスタ上にテキトーなpodを配置したかったのでマニフェスト

■ busybox.yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: busybox
    image: busybox

を書いてサンプルのpodをデプロイ

$ kubectl apply -f busybox.yaml
pod/busybox created

してみたら、あれ?podが起動(Running)にならない、、、

$ kubectl get pods -w
NAME   READY   STATUS              RESTARTS   AGE
busybox 0/1     ContainerCreating   0          3s
busybox 0/1     Completed           0          6s
busybox 0/1     Completed           1          9s
busybox 0/1     CrashLoopBackOff    1          10s
busybox 0/1     Completed           2          24s
busybox 0/1     CrashLoopBackOff    2          38s
busybox 0/1     Completed           3          54s
busybox 0/1     CrashLoopBackOff    3          55s
:

しかも再起動を繰り返してる、、なんでだろう?

試しに nginx のマニフェスト

■ nginx.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx

を書いてサンプルのpodをデプロイ

$ kubectl apply -f nginx.yaml
pod/nginx created

してみたところ問題なくpodが起動(Running)した。なんでだろう?

$ kubectl get pods -w
NAME   READY   STATUS              RESTARTS   AGE
busybox 0/1     CrashLoopBackOff    5          3m46s
nginx      0/1     ContainerCreating   0          4s
nginx      1/1     Running             0          7s

次に、先ほどのマニフェストにコマンド実行を追記して

■ busybox.yaml(※command 追記)

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']

既存のpod(busybox)を削除して

$ kubectl delete pod busybox
pod "busybox" deleted

問題のpodを再作成してみる。

$ kubectl apply -f busybox.yaml
pod/busybox created

ちゃんと起動しました。

$ kubectl get pods -wNAME    READY   STATUS    RESTARTS   AGE
busybox 1/1     Running   0          56s
nginx      1/1     Running   0          13m

この理由ですが、k8sコンテナは、実行中のメインプロセスが終了するとコンテナも終了しようとするためです。 つまり、nginxイメージを使用するpodは、メインプロセスであるnginxが動作し続けているため、 podは起動状態(Running)になり、その状態を維持し続けますが、busyboxイメージを使用するpodは、 実行コマンドが指定されていない場合、メインプロセスがすぐに終了してしまうため、podは、 ほんの一瞬だけ起動状態(Running)になりますが、すぐに完了(Completed)してしまいます。

今回マニフェストに追記したコマンド(sleep)により3600秒間(1時間)はメインプロセスが終了しないため、 busyboxイメージを使用するpodも起動状態(Running)となりました。 が、その時間が経過すると、先ほどと同様に再起動を繰り返すようになります。

ちなみに、busyboxイメージを使用する kubernetes の資料やマニフェストのサンプルの多くはコマンドを指定して使用されています。

知っていればそれまでなのですが、テキトーにサンプルをつくると、想定外の事象に苦しむことになりがちなので、 ご注意ください。

参考URL

この記事を書くにあたり下記の情報を参考にさせていただきました。