k8s集群pod鏡像拉取失敗解決方法

Docker Hub以及利用開源harbor項目搭建的鏡像倉庫服務,對于Docker Client發(fā)起的docker login、docker push、docker pull等命令都會做基本的用戶認證,
最簡單常用的認證方式就是Basic Auth,即在發(fā)起的http請求頭中添加一個Authorization,其值為base64(username:password),當前Docker Client都是這么處理。

在Kubernetes中,Secret資源對象用來存儲和管理一些敏感信息,比如密碼、Auth Token以及SSH keys,把這些敏感信息放入Secret對象中,相對來說更安全更靈活。
Kubernetes可以通過環(huán)境變量、文件掛載等方式將Secret信息推到每一個Pod中,通過文件掛載形式還能使Secret在pod中實時更新,Kubernetes統(tǒng)一管理。

Kubernetes中調度Pod成功之后,則開始拉取指定鏡像啟動容器,在Deployment對象中有幾個與鏡像拉取相關的重要配置參數(shù)。

  • spec.template.spec.containers[n].image,容器啟動時的鏡像
  • spec.template.spec.imagePullSecrets,Secret中定義了鏡像所在倉庫的用戶名密碼
  • spec.template.spec.containers[n].imagePullPolicy,定義了鏡像拉取策略

imagePullPolicy決定了是否發(fā)起鏡像下拉請求,它的值范圍Always、Never、IfNotPresent,默認為IfNotPresent,但標簽為:latest的鏡像默認為Always。

  • Always,不管宿主機上鏡像是否存在,都會發(fā)起一次下拉鏡像請求
  • Never,不管宿主機上鏡像是否存在,都不會發(fā)起下拉鏡像請求
  • IfNotPresent,如果宿主機上鏡像不存在,則向倉庫發(fā)起下拉鏡像請求

在Kubernetes中執(zhí)行應用部署命令之后,通過命令kubectl get pods查看pod狀態(tài)時,經常會遇見Pod的狀態(tài)是ErrImagePull或者ImagePullBackOff,出現(xiàn)這種情況就一步一步分析。

kube-system       monitor-6c7fdcd477-jvqjc                 0/1       ImagePullBackOff   0          1h
  1. 執(zhí)行命令

    kubectl describe pod monitor-6c7fdcd477-jvqjc -n kube-system
    

    或者kubectl get events,查看是否能發(fā)現(xiàn)具體的錯誤信息,由于kubernetes中錯誤信息不是很明顯,通常只會展示error。

  2. 在宿主機上執(zhí)行docker login 檢查用戶名密碼是否正確,接著執(zhí)行docker pull imageId,操作均成功,表示鏡像倉庫服務正常。

  3. 由于kubernetes中的pod網絡可能與宿主機網絡不一致,進入某個kubernetes的pod中,可以通過部署curl的pod用于網絡測試,檢查鏡像倉庫地址是否預期一致,不一致請把鏡像倉庫正確的域名或者host配置在集群dns中。

  4. 查看應用部署中的deployment對應yaml中的imagePullPolicy,如果機器上無鏡像,同時imagePullPolicy為Never,則鏡像無法拉取。

  5. 查看deployment對應yaml中的imagePullSecrets,其中的name就是secret的名字,如果拉取的是私有鏡像,imagePullSecrets是必須的,沒有secret,拉取鏡像時請求
    倉庫的http請求頭Authorization則為空,倉庫授權校驗肯定不通過直接返回401錯誤,而kubernetes則可能直接顯示error。
    注意secret是區(qū)分namespace的,容器啟動時都是使用當前容器所在pod的namespace中的secret,執(zhí)行命令檢查secret是否存在。

    kubectl get secret xxx -n kube-system -o yaml
    
  6. 當前namespace下對應的secret也存在,那就繼續(xù)檢查secret中的信息,取出上一步執(zhí)行結果中顯示的dockercfg字段對應的value值,應該是一長串base64編碼的字符串,
    類似eyJodWIua2NlLmtzeXVeikkskseYELSH8sse,解碼看一下具體的信息。

    echo 'eyJodWIua2NlLmtzeXVeikkskseYELSH8sse' | base64 --decode
    

    解碼之后數(shù)據(jù)(mock數(shù)據(jù),并非真實數(shù)據(jù))

    {"hub.test.company.com":{"username":"98766743","password":"somebaby","email":"localhost","auth":"xxeieESrweSXs="}}
    

    檢查用戶名、密碼是否正確,用戶名密碼正確,還要查看域名是否與image包含的域名一致,如果deployment對應的yaml中的image為hub.test2.company.com/nginx/nginx:1.12.1,
    如果這樣,即使用戶名、密碼正確,kubernetes也不會將Authorization放在請求倉庫的http header中,也會導致鏡像下載失敗。

  7. 發(fā)現(xiàn)secret中信息不對,則可以將該secret刪除,然后重新創(chuàng)建,假設deployment中對應的imagePullSecrets中的name為hub.test.company.com.key。
    刪除secret

    kubectl delete secret hub.test.company.com.key -n kube-system
    

    新建secret

    kubectl create secret docker-registry hub.test.company.com.key -n kube-system --docker-server=hub.test.company.com  
    --docker-username=2380997 --docker-password=RABC123456 --docker-email=test@company.com
    

    注意創(chuàng)建時沒指定namespace,那么默認為default。secret創(chuàng)建成功之后,重新部署即可。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1、基礎架構 1.1 Master Master節(jié)點上面主要由四個模塊組成:APIServer、scheduler...
    阿斯蒂芬2閱讀 11,148評論 0 44
  • 一、 K8s 是什么? Kubernetes(k8s)是自動化容器操作的開源平臺,這些操作包括部署,調度和節(jié)點集群...
    loveroot閱讀 6,712評論 1 21
  • 寫這篇文章主要是為了今后畢業(yè)論文素材上的整理,同時對docker進行鞏固溫習。大綱: docker簡介docker...
    胡圖仙人閱讀 7,774評論 2 96
  • 從凌晨開始的大雨,斷斷續(xù)續(xù)下了一天。 渴望清涼的夏天。
    和塵之塵閱讀 480評論 4 15
  • 選擇正確的剛需,對于我們每個人來說都是至關重要的。就拿學英語這事兒來說吧,我們大部分為什么學不會、學不好呢? 在文...
    無畏的小強閱讀 338評論 1 0

友情鏈接更多精彩內容