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
-
執(zhí)行命令
kubectl describe pod monitor-6c7fdcd477-jvqjc -n kube-system或者
kubectl get events,查看是否能發(fā)現(xiàn)具體的錯誤信息,由于kubernetes中錯誤信息不是很明顯,通常只會展示error。 在宿主機上執(zhí)行docker login 檢查用戶名密碼是否正確,接著執(zhí)行docker pull imageId,操作均成功,表示鏡像倉庫服務正常。
由于kubernetes中的pod網絡可能與宿主機網絡不一致,進入某個kubernetes的pod中,可以通過部署curl的pod用于網絡測試,檢查鏡像倉庫地址是否預期一致,不一致請把鏡像倉庫正確的域名或者host配置在集群dns中。
查看應用部署中的deployment對應yaml中的imagePullPolicy,如果機器上無鏡像,同時imagePullPolicy為Never,則鏡像無法拉取。
-
查看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 -
當前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中,也會導致鏡像下載失敗。 -
發(fā)現(xiàn)secret中信息不對,則可以將該secret刪除,然后重新創(chuàng)建,假設deployment中對應的imagePullSecrets中的name為hub.test.company.com.key。
刪除secretkubectl 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)建成功之后,重新部署即可。