本文の内容は、2022年10月5日にJavier Martínezが投稿したブログ(https://sysdig.com/blog/kubernetes-errimagepull-imagepullbackoff/)を元に日本語に翻訳・再構成した内容となっております。
コンテナを使用している時、ImagePullBackOffやErrImagePullなどのPodステータスが一般的に発生します。
ErrImagePullは、コンテナに指定されたイメージを取得またはプルできないときに発生するエラーです。
ImagePullBackOffは、イメージのプルが修正されるまでの待機猶予期間です。
今回は、その様子をご紹介します。
- コンテナイメージ
- イメージのプル
- イメージのプルポリシー
- ErrImagePull
- ErrImagePullのデバッグ
- イメージプルエラーの監視
- その他のイメージエラー
コンテナイメージ
コンテナ化の最大の強みは、特定のイメージを数秒で実行できることです。コンテナとは、基本システムから分離して実行されるプロセスのグループです。コンテナイメージには、これらのプロセスを実行するために必要なすべてのリソース(バイナリ、ライブラリ、および必要な設定)が含まれています。コンテナレジストリは、コンテナイメージのリポジトリであり、次の2つの基本的なアクションがあります。
- Push: イメージをアップロードし、リポジトリで利用できるようにする
- Pull:コンテナで使用するためにイメージをダウンロードする
この記事の例では docker CLI を使用しますが、Open Container Initiative Distribution の仕様を実装したツールであれば、コンテナレジストリのすべてのインタラクションに使用することができます。
イメージのプル
イメージは名前によって定義することができます。さらに、あるイメージの特定のバージョンに特定の名前かタグをつけることもできます。また、コンテンツのハッシュであるダイジェストで識別することもできます。latest
というタグは、あるイメージの最新版を意味します。名前を指定してイメージを取得する
イメージの名前だけを指定すると、latest
タグのついたイメージがプルされます。docker pull nginx
kubectl run mypod nginx
名前+タグでイメージをプル
latest
のイメージをプルしたくない場合は、特定のリリースタグを指定することができます。docker pull nginx:1.23.1-alpine
kubectl run mypod nginx:1.23.1-alpine
詳しくは、タグの変更可能性についての記事を参照してください。
ダイジェストでイメージを取得する
ダイジェストとは、実際のイメージのsha256ハッシュのことです。このダイジェストを使ってイメージをプルし、ダウンロードしたファイルでその真偽や統合性を検証することができます。docker pull sha256:d164f755e525e8baee113987bdc70298da4c6f48fdc0bbd395817edf17cf7c2b
kubectl run mypod --image=nginx:sha25645b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5
イメージプルポリシー
Kubernetesの特徴として、コンテナごとにImage Pull Policy(imagePullPolicyフィールド)を設定することができます。これに基づいて、kubeletがコンテナイメージを取得する方法が異なります。imagePullPolicyの値は3種類あります:
- Always
- IfNotPresent
- Never
Always
imagePullPolicyをAlwaysに設定すると、kubeletはこのコンテナのイメージをプルする際に毎回リポジトリをチェックします。IfNotPresent
imagePullPolicyをIfNotPresentに設定すると、kubeletはローカルにノードが存在しない場合のみ、リポジトリからイメージを取り出します。Never
imagePullPolicyをNeverに設定すると、kubeletはイメージレジストリからイメージをプルすることを試みなくなります。ローカルにキャッシュされた(事前にプルされた)イメージがある場合、そのイメージを使用してコンテナが起動されます。ローカルにイメージが存在しない場合、Podの作成は
ErrImageNeverPull
エラーで失敗します。AlwaysPullImagesアドミッションコントローラーを使用することで、クラスターのイメージプルポリシー全体を変更できることに注意してください。
デフォルトのイメージプルポリシー
- imagePullPolicyを省略し、タグがlatestの場合、imagePullPolicyはAlwaysに設定されます。
- imagePullPolicy を省略し、イメージのタグを指定すると、imagePullPolicy は Always に設定されます。
- imagePullPolicy を省略し、タグを latest 以外の値に設定した場合、imagePullPolicy は IfNotPresent に設定されます。
ErrImagePull
KubernetesがPod内のコンテナ用のイメージをプルしようとすると、うまくいかないことがあります。ErrImagePull ステータスは、kubelet
が Pod 内のコンテナを起動しようとしたが、Pod、デプロイ、または ReplicaSet マニフェストに指定されたイメージに何か問題があった場合に表示されます。kubectlを使用してクラスター内のPodに関する情報を取得する場合を想像してください:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
goodpod 1/1 Running 0 21h
mypod 0/1 ErrImagePull 0 4s
ということは:
- Podは
READY
ステータスではない - ステータスは
ErrImagePull
さらに、Pod内のコンテナのログを確認することができます:
$ kubectl logs mypod --all-containers
Error from server (BadRequest): container "mycontainer" in pod "mypod" is waiting to start: trying and failing to pull image
この場合、おそらく指定されたイメージは利用できないか、存在しないため、これは400エラー(BadRequest)を指しています。
ImagePullBackOff
ImagePullBackOffはKubernetesの待機ステータスで、リトライ間のバックオフが増加した猶予期間です。バックオフ期間が過ぎると、kubeletは再びイメージのプルを試みます。これはCrashLoopBackOffステータスに似ており、同じくコンテナでエラーが発生した後にリトライする間の猶予期間です。バックオフ時間は再試行のたびに増加し、最大で5分までとなります。
ImagePullBackOffはエラーではないことに注意してください。前述の通り、イメージのプル時に問題が発生したことによるステータス理由に過ぎません。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
goodpod 1/1 Running 0 21h
mypod 0/1 ImagePullBackOff 0 84s
ということは:
- Podは
READY
ステータスでない - ステータスはImagePullBackOff
- CrashLoopBackOffとは異なり、再起動はない(厳密にはPodは起動すらしていない)
$ kubectl describe pod mypod
State: Waiting
Reason: ImagePullBackOff
...
Warning Failed 3m57s (x4 over 5m28s) kubelet Error: ErrImagePull
Warning Failed 3m42s (x6 over 5m28s) kubelet Error: ImagePullBackOff
Normal BackOff 18s (x20 over 5m28s) kubelet Back-off pulling image "failed-image"
ErrImagePullとImagePullBackOffのタイムライン
ErrImagePullとImagePullBackOffのデバッグ
Image Pull Errorが発生する原因にはいくつか考えられます。以下はその例です。- イメージが間違っている
- イメージタグが正しくない
- イメージのダイジェストが間違っている
- ネットワークの問題、またはイメージリポジトリが利用できない
- プライベートレジストリからのプルであるが、imagePullSecret が提供されていない
これは考えられる原因のリストですが、あなたのソリューションに基づくと、他にも多くの原因があるかもしれないことに注意してください。一番の対策は、確認することでしょう:
$ kubectl describe pod podname
$ kubect logs podname –all-containers
$ kubectl get events --field-selector involvedObject.name=podname
次の例では、イメージエラーが見つかったログを掘り下げる方法を見ることができます。ErrImagePullとImagePullBackOffのデバッグオプションがある3つの端末です。
その他のイメージエラー
ErrImageNeverPull
このエラーは、kubeletがノード内のイメージのプルに失敗し、imagePullPolicyがNeverに設定されている場合に表示されます。このエラーを修正するには、Pull Policyを変更してイメージを外部からプルできるようにするか、正しいイメージをローカルに追加してください。Pending
ErrImagePullと関連するImagePullBackOffは、Pod上のPendingステータスと異なる場合があることに留意してください。Pendingステータスは、ほとんどの場合、kube-schedulerがあなたのPodを作業中または適格なNodeに割り当てることができない結果です。
Prometheusでイメージプルエラーを監視する
PrometheusとKube State Metrics(KSM)を使えば、ImagePullBackOffやErrImagePullステータスのコンテナを持つPodを簡単に追跡することができます。kube_pod_container_status_waiting_reason{reason="ErrImagePull"}
kube_pod_container_status_waiting_reason{reason="ImagePullBackOff"}
実はこの2つのメトリクスは、以下のPrometheusのクエリーを見ればわかるように、補完関係にあります。
PrometheusでErrImagePullとImagePullBackOffを監視する
ImagePullBackOffの待機期間と、ErrImagePullを返すイメージプル再試行の間でPodが移動しているのです。
また、ImagePullPolicyをNeverに設定したコンテナを使用している場合は、ErrImageNeverPullとしてエラーを追跡する必要があることを忘れないでください。
kube_pod_container_status_waiting_reason{reason="ErrImageNeverPull"}
まとめ
コンテナイメージは、クラウドアプリケーションのニーズをキックスタートするための素晴らしい方法です。そのおかげで、すぐに起動してスケーリングできる何千ものアプリケーションにアクセスすることができます。しかし、設定ミスや不整合、リポジトリの問題などが原因で、イメージのエラーが出始めるかもしれません。イメージの定義が不正であったり、セットアップにエラーがあったりすると、コンテナは正常に起動できなくなります。
Kubernetesはイメージプルエラーが発生した場合、猶予期間を設けています。このImage Pull Backoffは、イメージ定義の問題を修正する時間を与えてくれるため、かなり便利です。しかし、あなたのクラスターでこれがいつ起こるのか、そしてその都度何を意味するのかを認識する必要があります。
Sysdig MonitorでImage Pullエラーのトラブルシューティングを行う
Sysdig MonitorのAdvisorに仕組みを使えば、Kubernetesクラスターで発生しているImage Pull Errorsを簡単に確認することができます。Sysdig Advisorは、ライブログ、パフォーマンスデータ、推奨される修正ステップにより、平均解決時間(MTTR)を短縮します。Kubernetesのトラブルシューティングのための簡単なボタンです。
Sysdig MonitorのErrImagePullとImagePullBackOffのトラブルシューティング
30日間無料でお試しください!