Kubernetes ErrImagePullとImagePullBackOffの詳細

本文の内容は、2022年10月5日にJavier Martínezが投稿したブログ(https://sysdig.com/blog/kubernetes-errimagepull-imagepullbackoff/)を元に日本語に翻訳・再構成した内容となっております。<br /><br />コンテナを使用している時、ImagePullBackOffやErrImagePullなどのPodステータスが一般的に発生します。<br /><br /><strong>ErrImagePull</strong>は、コンテナに指定されたイメージを取得またはプルできないときに発生するエラーです。<br /><br /><strong>ImagePullBackOff</strong>は、イメージのプルが修正されるまでの待機猶予期間です。<br /><br /><img src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-00.png" alt="ErrImagePull and ImagePullBackOff cover" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-00.png" data-ll-status="loaded" /><br />今回は、その様子をご紹介します。<br /><br /><ul><li>コンテナイメージ</li><li>イメージのプル</li><li>イメージのプルポリシー</li><li>ErrImagePull</li><li>ErrImagePullのデバッグ</li><li>イメージプルエラーの監視</li><li>その他のイメージエラー</li></ul><br /><h2>コンテナイメージ</h2>コンテナ化の最大の強みは、特定のイメージを数秒で実行できることです。<strong>コンテナ</strong>とは、基本システムから分離して実行されるプロセスのグループです。<strong>コンテナイメージ</strong>には、これらのプロセスを実行するために必要なすべてのリソース（バイナリ、ライブラリ、および必要な設定）が含まれています。<br /><br /><strong>コンテナレジストリ</strong>は、コンテナイメージのリポジトリであり、次の2つの基本的なアクションがあります。<br /><br /><ul><li><strong>Push</strong>: イメージをアップロードし、リポジトリで利用できるようにする</li><li><strong>Pull</strong>：コンテナで使用するためにイメージをダウンロードする</li></ul><br />
<p><span style="text-size: smaller; font-style: italic; border: 1px solid #FF9E1B; display: block; border-radius: 25px; padding: 25px; max-width: 96%; margin: 2em auto;"><em>この記事の例では docker CLI を使用しますが、Open Container Initiative Distribution の仕様を実装したツールであれば、コンテナレジストリのすべてのインタラクションに使用することができます。<br />
</em></span></p>




<br /><h2>イメージのプル</h2>イメージは名前によって定義することができます。さらに、あるイメージの特定のバージョンに特定の名前かタグをつけることもできます。また、コンテンツのハッシュであるダイジェストで識別することもできます。<br /><br /><span> </span><code>latest</code><span> </span>というタグは、あるイメージの最新版を意味します。<br /><br /><h3>名前を指定してイメージを取得する</h3>イメージの名前だけを指定すると、<span> </span><code>latest</code><span> </span>タグのついたイメージがプルされます。<br /><br /><pre class="prettyprint">docker pull nginx
kubectl run mypod nginx</pre><br /><h3>名前＋タグでイメージをプル</h3><code>latest</code><span> </span>のイメージをプルしたくない場合は、特定のリリースタグを指定することができます。<br /><br /><pre class="prettyprint">docker pull nginx:1.23.1-alpine
kubectl run mypod nginx:1.23.1-alpine</pre><br />詳しくは、<a href="https://www.linkedin.com/pulse/%25E3%2583%259F%25E3%2583%25A5%25E3%2583%25BC%25E3%2582%25BF%25E3%2583%25B3%25E3%2583%2588%25E3%2582%25BF%25E3%2582%25B0%25E3%2581%25AE%25E6%2594%25BB%25E6%2592%2583-%25E3%2581%25BE%25E3%2581%259F%25E3%2581%25AF%25E3%2582%25BF%25E3%2582%25B0%25E3%2581%25AE%25E5%258F%25AF%25E5%25A4%2589%25E6%2580%25A7%25E3%2581%258C%25E7%259C%259F%25E3%2581%25AE%25E3%2582%25BB%25E3%2582%25AD%25E3%2583%25A5%25E3%2583%25AA%25E3%2583%2586%25E3%2582%25A3%25E8%2584%2585%25E5%25A8%2581%25E3%2581%25A7%25E3%2581%2582%25E3%2582%258B%25E7%2590%2586%25E7%2594%25B1-takao-shimizu/?trackingId=QPk5agrNR3a9lOrZ4R8EbQ%3D%3D">タグの変更可能性についての記事</a>を参照してください。<br /><br /><h3>ダイジェストでイメージを取得する</h3>ダイジェストとは、実際のイメージのsha256ハッシュのことです。このダイジェストを使ってイメージをプルし、ダウンロードしたファイルでその真偽や統合性を検証することができます。<br /><br /><pre class="prettyprint">docker pull sha256:d164f755e525e8baee113987bdc70298da4c6f48fdc0bbd395817edf17cf7c2b
kubectl run mypod --image=nginx:sha25645b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5</pre><br /><h3>イメージプルポリシー</h3>Kubernetesの特徴として、コンテナごとにImage Pull Policy（imagePullPolicyフィールド）を設定することができます。これに基づいて、kubeletがコンテナイメージを取得する方法が異なります。<br /><br />imagePullPolicyの値は3種類あります：<br /><br /><ul><li>Always</li><li>IfNotPresent</li><li>Never</li></ul><br /><h4>Always</h4>imagePullPolicyを<strong>Always</strong>に設定すると、kubeletはこのコンテナのイメージをプルする際に毎回リポジトリをチェックします。<br /><br /><h4>IfNotPresent</h4>imagePullPolicyを<strong>IfNotPresent</strong>に設定すると、kubeletはローカルにノードが存在しない場合のみ、リポジトリからイメージを取り出します。<br /><br /><h4>Never</h4>imagePullPolicyを<strong>Never</strong>に設定すると、kubeletはイメージレジストリからイメージをプルすることを試みなくなります。ローカルにキャッシュされた（事前にプルされた）イメージがある場合、そのイメージを使用してコンテナが起動されます。<br /><br />ローカルにイメージが存在しない場合、Podの作成は<span> </span><code>ErrImageNeverPull</code><span> </span>エラーで失敗します。<br /><br /><img alt="ImagePullPolicy description: always, never and ifnotpresent" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-01.png" src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-01.png" data-ll-status="loaded" /><br />AlwaysPullImages<a href="https://sysdig.jp/blog/kubernetes-admission-controllers/">アドミッションコントローラー</a>を使用することで、クラスターのイメージプルポリシー全体を変更できることに注意してください。<br /><br /><h4>デフォルトのイメージプルポリシー</h4><ul><li>imagePullPolicyを省略し、タグがlatestの場合、imagePullPolicyはAlwaysに設定されます。</li><li>imagePullPolicy を省略し、イメージのタグを指定すると、imagePullPolicy は Always に設定されます。</li><li>imagePullPolicy を省略し、タグを latest 以外の値に設定した場合、imagePullPolicy は IfNotPresent に設定されます。</li></ul><br /><h3>ErrImagePull</h3>KubernetesがPod内のコンテナ用のイメージをプルしようとすると、うまくいかないことがあります。ErrImagePull ステータスは、<span> </span><code>kubelet</code><span> </span>が Pod 内のコンテナを起動しようとしたが、Pod、デプロイ、または ReplicaSet マニフェストに指定されたイメージに何か問題があった場合に表示されます。<br /><br />kubectlを使用してクラスター内のPodに関する情報を取得する場合を想像してください：<br /><br /><pre class="prettyprint">$ kubectl get pods
NAME    READY   STATUS             RESTARTS   AGE
goodpod 1/1     Running            0          21h
mypod   0/1     ErrImagePull       0          4s</pre><br />ということは：<br /><br /><ul><li>Podは<span> </span><code>READY</code><span> </span>ステータスではない</li><li>ステータスは<span> </span><code>ErrImagePull</code></li></ul><br />さらに、Pod内のコンテナのログを確認することができます：<br /><br /><pre class="prettyprint">$ kubectl logs mypod --all-containers
Error from server (BadRequest): container "mycontainer" in pod "mypod" is waiting to start: trying and failing to pull image</pre><br />この場合、おそらく指定されたイメージは利用できないか、存在しないため、これは400エラー（BadRequest）を指しています。<br /><br /><h3>ImagePullBackOff</h3>ImagePullBackOffはKubernetesの待機ステータスで、リトライ間のバックオフが増加した猶予期間です。バックオフ期間が過ぎると、kubeletは再びイメージのプルを試みます。<br /><br />これは<a href="https://sysdig.jp/blog/debug-kubernetes-crashloopbackoff/">CrashLoopBackOffステータス</a>に似ており、同じくコンテナでエラーが発生した後にリトライする間の猶予期間です。バックオフ時間は再試行のたびに増加し、最大で5分までとなります。<br /><br />ImagePullBackOffはエラーではないことに注意してください。前述の通り、イメージのプル時に問題が発生したことによるステータス理由に過ぎません。<br /><br /><pre class="prettyprint">$ kubectl get pods
NAME    READY   STATUS             RESTARTS   AGE
goodpod 1/1     Running            0          21h
mypod   0/1     ImagePullBackOff   0          84s</pre><br />ということは：<br /><br /><ul><li>Podは<span> </span><code>READY</code><span> ステータスでない</span></li><li>ステータスはImagePullBackOff</li><li>CrashLoopBackOffとは異なり、再起動はない（厳密にはPodは起動すらしていない）</li></ul><br /><pre class="prettyprint">$ 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"</pre><br /><img alt="ErrImagePull and ImagePullBackOff timeline" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-02.png" src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-02.png" data-ll-status="loaded" /><em>ErrImagePullとImagePullBackOffのタイムライン</em><br /><br /><h2>ErrImagePullとImagePullBackOffのデバッグ</h2>Image Pull Errorが発生する原因にはいくつか考えられます。以下はその例です。<br /><br /><ul><li>イメージが間違っている</li><li>イメージタグが正しくない</li><li>イメージのダイジェストが間違っている</li><li>ネットワークの問題、またはイメージリポジトリが利用できない</li><li>プライベートレジストリからのプルであるが、imagePullSecret が提供されていない</li></ul><br />これは考えられる原因のリストですが、あなたのソリューションに基づくと、他にも多くの原因があるかもしれないことに注意してください。一番の対策は、確認することでしょう：<br /><br /><pre class="prettyprint">$ kubectl describe pod podname

$ kubect logs podname –all-containers

$ kubectl get events --field-selector involvedObject.name=podname</pre><br />次の例では、イメージエラーが見つかったログを掘り下げる方法を見ることができます。ErrImagePullとImagePullBackOffのデバッグオプションがある3つの端末です。<br /><br /><img alt="Three terminals with debugging options for ErrImagePull and ImagePullBackOff" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-03.png" src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-03.png" data-ll-status="loaded" /><br /><h2>その他のイメージエラー</h2><h3>ErrImageNeverPull</h3>このエラーは、kubeletがノード内のイメージのプルに失敗し、imagePullPolicyがNeverに設定されている場合に表示されます。このエラーを修正するには、Pull Policyを変更してイメージを外部からプルできるようにするか、正しいイメージをローカルに追加してください。<br /><br /><h3>Pending</h3>ErrImagePullと関連するImagePullBackOffは、Pod上のPendingステータスと異なる場合があることに留意してください。<br /><br />Pendingステータスは、ほとんどの場合、kube-schedulerがあなたのPodを作業中または適格なNodeに割り当てることができない結果です。<br /><br /><h2>Prometheusでイメージプルエラーを監視する</h2>PrometheusとKube State Metrics（KSM）を使えば、ImagePullBackOffやErrImagePullステータスのコンテナを持つPodを簡単に追跡することができます。<br /><br /><pre class="prettyprint">kube_pod_container_status_waiting_reason{reason="ErrImagePull"}
kube_pod_container_status_waiting_reason{reason="ImagePullBackOff"}</pre><br />実はこの2つのメトリクスは、以下のPrometheusのクエリーを見ればわかるように、補完関係にあります。<br /><br /><img alt="Monitoring ErrImagePull and ImagePullBackOff in Prometheus" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-04-1.png" src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-04-1.png" data-ll-status="loaded" /><em>PrometheusでErrImagePullとImagePullBackOffを監視する</em><br /><br />ImagePullBackOffの待機期間と、ErrImagePullを返すイメージプル再試行の間でPodが移動しているのです。<br /><br />また、ImagePullPolicyをNeverに設定したコンテナを使用している場合は、ErrImageNeverPullとしてエラーを追跡する必要があることを忘れないでください。<br /><br /><pre class="prettyprint">kube_pod_container_status_waiting_reason{reason="ErrImageNeverPull"}</pre><br /><h2>まとめ</h2>コンテナイメージは、クラウドアプリケーションのニーズをキックスタートするための素晴らしい方法です。そのおかげで、すぐに起動してスケーリングできる何千ものアプリケーションにアクセスすることができます。<br /><br />しかし、設定ミスや不整合、リポジトリの問題などが原因で、イメージのエラーが出始めるかもしれません。イメージの定義が不正であったり、セットアップにエラーがあったりすると、コンテナは正常に起動できなくなります。<br /><br />Kubernetesはイメージプルエラーが発生した場合、猶予期間を設けています。このImage Pull Backoffは、イメージ定義の問題を修正する時間を与えてくれるため、かなり便利です。しかし、あなたのクラスターでこれがいつ起こるのか、そしてその都度何を意味するのかを認識する必要があります。<br /><br />
<hr /><h2>
Sysdig MonitorでImage Pullエラーのトラブルシューティングを行う</h2>Sysdig MonitorのAdvisorに仕組みを使えば、Kubernetesクラスターで発生しているImage Pull Errorsを簡単に確認することができます。<br /><br />Sysdig Advisorは、ライブログ、パフォーマンスデータ、推奨される修正ステップにより、平均解決時間（MTTR）を短縮します。Kubernetesのトラブルシューティングのための簡単なボタンです。<br /><br /><img src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-05.png" alt="Troubleshooting ErrImagePull and ImagePullBackOff in Sysdig Monitor" width="1200" height="600" class="img-lightbox aligncenter size-full wp-image-53161 u-no-shadow entered lazyloaded" data-lazy-src="https://sysdig.com/wp-content/uploads/ErrImagePull-ImagePullbackOff-05.png" data-ll-status="loaded" /><em>Sysdig MonitorのErrImagePullとImagePullBackOffのトラブルシューティング</em><br /><br /><a href="https://sysdig.com/company/free-trial-monitor/">30日間無料でお試しください！</a>