今k8sとTiltを使っているのですが、結構な頻度で、再起動時にトラブルが起きます。あるPODがうまく起動しないのです。 イメージはありますが、ErrImgaePullになるのです。
ここからは実験をしていきます。
まず問題のPODのイメージを削除します。このイメージは、TiltのダミーのDeploymentの起動時にビルドされます。 なので、tiltを再起動しないで、起動しようとすると、pull errorみたいなやつになります。やってみましょう。
ErrImagePullでした。あれ、いつもとエラーが違う。いつもはImagePullBackoffみたいなやつだったような。。
ここで、ErrImagePullの意味を調べましょう。
これは勉強になります。ありがとうございます。
KubernetesがPod内のコンテナ用のイメージをプルしようとすると、うまくいかないことがあります。ErrImagePull ステータスは、 kubelet が Pod 内のコンテナを起動しようとしたが、Pod、デプロイ、または ReplicaSet マニフェストに指定されたイメージに何か問題があった場合に表示されます。
ではログを見てみます。
> kubectl logs hoge-pod Error from server (BadRequest): container "hoge" in pod "hoge-podl" is waiting to start: trying and failing to pull image
これはPod の起動時にイメージの pull (取得) に失敗していることを示しているそうです。まあ、イメージないですからね。
ImagePullBackOff は Kubernetes における Pod のステータスの一つで、コンテナイメージの pull (取得) に失敗し、再試行している状態 を示します
なるほど。これはGeminiさんの発言ですが、要するに再試行中の状態ってことですね。どっちにしてもイメージのpullに失敗したことが分かるわけですね。 さて、では、イメージをビルドしましょう。
私はTiltを使っており、tilt upで自動的にビルドするようになっています。やってみます。
> minikube image ls imageないです > tilt up > minikube lmage ls imageありました
さあこれでpull自体はできるはずですね。もう一度POD起動してみましょう。
結果は、ErrImagePullでした。これはつまりイメージが壊れている、エラーが出ているってことですかね。 ログを見てみましょう。
あれ、同じログですね。。。おわた。。 つまり、minikube image lsで存在が確認できているのに、イメージのpullに失敗するケースがあるってことでしょうか?
describeというのをやってみます。
> kubectl describe po hoge-pod .... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 10m default-scheduler Successfully assigned default/hoge-pod to minikube Normal Pulling 8m56s (x4 over 10m) kubelet Pulling image "hoge/hoge-image:latest" Warning Failed 8m53s (x4 over 10m) kubelet Failed to pull image "hoge/hoge-image:latest": Error response from daemon: pull access denied for hoge/hoge-image, repository does not exist or may require 'docker login': denied: requested access to the resource is denied Warning Failed 8m53s (x4 over 10m) kubelet Error: ErrImagePull Warning Failed 8m39s (x6 over 10m) kubelet Error: ImagePullBackOff Normal BackOff 22s (x41 over 10m) kubelet Back-off pulling image "hoge/hoge-image"
上記について、Claude3.7様によりますと
ここで重要なポイントは: "repository does not exist or may require 'docker login'" - これは Docker Hub などの外部レジストリを探しに行っている証拠です "pull access denied" - 外部レジストリへのアクセス権がないか、そもそもそのリポジトリが存在しないことを示しています "requested access to the resource is denied" - 外部リソースへのアクセスが拒否されています つまり、Kubernetes は minikube のローカルイメージを見に行くのではなく、Docker Hub などの外部レジストリから hoge/hoge-image を pull しようとして失敗しているんです 🔍
だそうです。なるほど。。。 ここで既に3回目位なことに気づきました。
self.k8s.create_deployment( name=deployment_name, namespace="default", labels=labels, container_image=container_image, container_name=container_name, container_port=container_port, env_vars=env_vars, image_pull_policy=image_pull_policy, )
上記のimage_pull_policyを設定しておりませんでした。その結果デフォルトのAlwaysになっていて、これは毎回外部をチェックする的な意味のようです。 そこでimage_pull_policyを追加して、値は「Never」にしました。これはローカルイメージしか見ないそうです。
はて、これで再度試したら、正常起動(Running)しました。
一応、image_pull_policyを「IfNotPresent」にして、試してみます。 これでもいけました。これなら本番感動時もよさげなので、こっちにしておきます。
まとめ
多分結構な頻度でエラーになっているのは、tiltの再起動をせずにpod起動をしようとして純粋にイメージがない場合と、上記のようにコードを修正した結果imagePullPolicyが消えて外部を見に行っているのと、イメージにエラーがあって起動できないのと、があるのかなあと思った。全てにおいて kubectl get po
からの kubectl logs {pod name}
と kubectl describe po {pod name}
によって、明確になるはずなので、これをps1ファイルにしておこうと思いました。