時折、ErrImagePull / ImagePullBackOffエラーが発生する
Kubernetesがコンテナイメージのダウンロードに失敗する原因を探る - Oct Tech Blog
体裁を整えて記事にした
#Kubernetes #EKS
#TroubleShooting
/icons/hr.icon
AWSサポートに助けを求めて問答した結果、やはり--image-pull-progress-deadlineではないかと言われた。
つまりこのIssue
Occasional ImagePullBackOff Errors when pulling large docker images · Issue #59376 · kubernetes/kubernetes
Issue内でも対処として挙がっている、
kubeletの--image-pull-progress-deadlineを10分に伸ばす対処をサポートから勧められた(デフォルトは1分)。
10分は長すぎないか?とも思ったが、一旦はその通りにしてみると、改善したようだ。
code:shell
vi /etc/systemd/system/kubelet.service
systemctl daemon-reload
systemctl restart kubelet
/icons/hr.icon
遭遇時のエラー
code:shell
pulling image "xxxx"
Failed to pull image "xxxx": rpc error: code = Canceled desc = context canceled
Error: ErrImagePull
Back-off pulling image "xxxx"
Error: ImagePullBackOff
(これとは違う request canceled while waiting for connectionでもno basic auth credentialsでもない)
レジストリにイメージは存在する。
imagePullPolicyはAlwaysでもIfNotPresentでも発生する。
原因かもしれないもの?→確信は得られず
これが起こっていないノードでもErrImagePullは起きてた。ImageGCFailedはあくまでWarningだしConditionsのOutOfDiskもFalseだったからディスクが一杯でプルできないわけではなさそう。
code:shell
Normal NodeHasSufficientDisk 55m (x161 over 4d6h) kubelet, ip-192-168-217-55.ap-northeast-1.compute.internal Node ip-192-168-217-55.ap-northeast-1.compute.internal status is now: NodeHasSufficientDisk
Normal NodeHasSufficientMemory 55m (x161 over 4d6h) kubelet, ip-192-168-217-55.ap-northeast-1.compute.internal Node ip-192-168-217-55.ap-northeast-1.compute.internal status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 55m (x161 over 4d6h) kubelet, ip-192-168-217-55.ap-northeast-1.compute.internal Node ip-192-168-217-55.ap-northeast-1.compute.internal status is now: NodeHasNoDiskPressure
Normal NodeReady 55m (x201 over 4d6h) kubelet, ip-192-168-217-55.ap-northeast-1.compute.internal Node ip-192-168-217-55.ap-northeast-1.compute.internal status is now: NodeReady
Warning ImageGCFailed 16m (x16 over 4d3h) kubelet, ip-192-168-217-55.ap-northeast-1.compute.internal failed to get image stats: rpc error: code = DeadlineExceeded desc = context deadline exceeded
怪しげな要素としては
このノードにErrorなPodがいる
Jobから生成されたもので、JobはCompleteしていない
Jobをdeleteしてみた→ErrorなPodは消える(当然)。ErrImagePull/ImagePullBackOffなPodには、すぐには変化なし。NodeのEventsもすぐには変化なし。→NotReadyを経てReadyになった
再度ReadyになったあとErrImagePull/ImagePullBackOffなPodを削除してみる
別のエラーが出る
Failed create pod sandbox: rpc error: code = Unknown desc = failed to create a sandbox for pod "pod_name": operation timeout: context deadline exceeded
ErrorなPodを生んだJobは直接の原因ではないかも?別のトラブルがノードで起こっている?
怪しいノードをdrainしてから再起動してuncordonしたら治まったように見えた。気のせいかもしれない。
/icons/hr.icon
エラーの箇所はここか?
https://github.com/kubernetes/kubernetes/blob/d24fe8a801748953a5c34fd34faa8005c6ad1770/pkg/kubelet/images/image_manager.go#L135
ここに来たということはpullImageがエラーを返した
pullImage
https://github.com/kubernetes/kubernetes/blob/d24fe8a801748953a5c34fd34faa8005c6ad1770/pkg/kubelet/images/puller.go#L47
これがエラーを返したということはPullImageがエラーを返した
PullImage
https://github.com/kubernetes/kubernetes/blob/v1.12.10/pkg/kubelet/dockershim/libdocker/kube_docker_client.go#L360
イメージ取得リクエストのレスポンスにエラーメッセージが入っていた(JSONのデコードエラーではなく)
progressReporter.start()
deadlineまでに進捗がなければp.cancel()→これがHTTPリクエストをキャンセルしエラーメッセージを書き込む(推測)
https://github.com/kubernetes/kubernetes/blob/v1.12.10/pkg/kubelet/dockershim/libdocker/kube_docker_client.go#L330
ふんわり所感
イメージサイズを小さくすると、回避しやすくなった、気が…する…
でも2桁MB前半くらいのイメージでも失敗することはあった。
がむしゃらにリトライする場合 やらない方が良い(疲れる)
問題なくイメージをプルできて、
すんなりRunning状態に到達してくれるPodができるまで、
ImagePullBackOffなPodをdeleteし続ける。
※単にImagePullBackOffに陥ると次にプルを試行するまでの待ち時間が伸び続けるのでdeleteして即やり直しをさせるだけ。しかし躍起になってdeleteしててもうまくいかないときはいかない。というかうまくいく方が少ない。
観念して待つと全PodいつのまにかRunningになってる。
https://github.com/kubernetes/kubernetes/issues/59376
Occasionally we'll run into ImagePullBackOff errors on our alpha GKE cluster on kube v1.8.5-gke.0 when pulling large docker images for containers within a pod. It sometimes won't work for 30+ mins and then start working again later. The larger docker images we occasionally have issues with are around 1-2GB.
30分強その状態が続いた後で問題が解消することがある
大きい、のサイズ感は1-2GBである
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-363249685
It randomly solves itself after a couple retries.
同じ問題に遭ったことがあり、何度かやり直して解決
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-363873139
Docker Hubで起きていて、GCRでも起きた
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-366547002
ECSでも起きた(ECRの間違いか?)
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-366735718
プライベートレジストリのイメージでも起きた
イメージは2GB超だった
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-366946404
AWSバニラクラスター(EC2で自前構築?)とDocker Hubの組み合わせで起きた
PodのイベントでErrImagePull とともに rpc error: code = Canceled desc = context canceledというエラー
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-367100430
--image-pull-progress-deadlineをkubeletに設定したかい?(:hooray:reactionがついている)
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-377572999
https://github.com/kubernetes/kubernetes/blob/915798d229b7be076d8e53d6aa1573adabd470d2/pkg/kubelet/dockershim/libdocker/kube_docker_client.go#L374
code:kube_docker_client.go
reporter := newProgressReporter(image, cancel, d.imagePullProgressDeadline)
Dockerから何らかのプルステータスの更新を取得することを期待しているようで、1分間Dockerから新しいメッセージがない場合にのみ中止
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-384584645
ECRのイメージで起きた
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-385669242
上記のGoコード箇所
期限までに進捗がなければ中止
Docker側からは、下記のように進捗を報告
https://github.com/moby/moby/blob/53683bd8326b988977650337ee43b281d2830076/distribution/pull_v2.go#L234
512kbダウンロードごとに進捗メッセージ送信
https://github.com/moby/moby/blob/3a633a712c8bbb863fe7e57ec132dd87a9c4eff7/pkg/progress/progressreader.go#L34
デフォルトの60秒の期限内に512kbダウンロードできなければ、プルは失敗
レジストリかDockerかネットワークに問題があるのでは?
https://github.com/kubernetes/kubernetes/issues/59376#issuecomment-394455458
docker pullはうまくいくのに発生することが興味深い
https://github.com/kubernetes/test-infra/issues/15102
1.13にしたら起きなくなったと思ったが、そんなことはなかったらしい
cf.
https://stackoverflow.com/questions/51870797/kubernetes-imagepullbackoff-errors-when-pulling-docker-images