Kubernetes私有倉庫可以提供更加安全和可控的鏡像管理方式,避免了直接從公共倉庫下載鏡像可能帶來的安全風(fēng)險(xiǎn)。本教程將介紹如何使用 Secret 從私有的鏡像倉庫或代碼倉庫拉取鏡像來創(chuàng)建 Pod。 有很多私有鏡像倉庫正在使用中,這個(gè)任務(wù)使用的鏡像倉庫是 Docker Hub。
一、準(zhǔn)備
1、必須擁有一個(gè) Kubernetes 的集群,同時(shí)必須配置 kubectl 命令行工具與集群通信。 建議在至少有兩個(gè)不作為控制平面主機(jī)的節(jié)點(diǎn)的集群上運(yùn)行本教程。 如果還沒有集群,可以通過 Minikube 構(gòu)建一個(gè)自己的集群,或者可以使用下面的 Kubernetes 練習(xí)環(huán)境之一:
- Killercoda
- 玩轉(zhuǎn) Kubernetes
2、要進(jìn)行此練習(xí),需要 docker 命令行工具和一個(gè)知道密碼的 Docker ID。
3、如果要使用不同的私有的鏡像倉庫,需要有對(duì)應(yīng)鏡像倉庫的命令行工具和登錄信息。
二、登錄Docker鏡像倉庫
在個(gè)人電腦上,要想拉取私有鏡像必須在鏡像倉庫上進(jìn)行身份驗(yàn)證。
使用 docker 命令工具來登錄到 Docker Hub。
docker login
當(dāng)出現(xiàn)提示時(shí),輸入 Docker ID 和登錄憑據(jù)(訪問令牌或 Docker ID 的密碼)。登錄過程會(huì)創(chuàng)建或更新保存有授權(quán)令牌的 config.json 文件。 查看 Kubernetes 如何解析這個(gè)文件。
查看 config.json 文件:
cat ~/.docker/config.json
輸出結(jié)果包含類似于以下內(nèi)容的部分:
{ "auths": { "https://index.docker.io/v1/": { "auth": "c3R...zE2" } } }
如果使用 Docker 憑據(jù)倉庫,則不會(huì)看到 auth 條目,看到的將是以倉庫名稱作為值的 credsStore 條目。 在這種情況下,可以直接創(chuàng)建一個(gè) Secret。
三、創(chuàng)建Secret
1、創(chuàng)建一個(gè)基于現(xiàn)有憑據(jù)的 Secret
Kubernetes 集群使用 kubernetes.io/dockerconfigjson 類型的 Secret 來通過鏡像倉庫的身份驗(yàn)證,進(jìn)而提取私有鏡像。
如果已經(jīng)運(yùn)行了 docker login 命令,可以復(fù)制該鏡像倉庫的憑據(jù)到 Kubernetes:
kubectl create secret generic regcred \ --from-file=.dockerconfigjson=<path/to/.docker/config.json> \ --type=kubernetes.io/dockerconfigjson
如果需要更多的設(shè)置(例如,為新 Secret 設(shè)置名字空間或標(biāo)簽), 則可以在存儲(chǔ) Secret 之前對(duì)它進(jìn)行自定義。 請(qǐng)務(wù)必:
- 將 data 項(xiàng)中的名稱設(shè)置為 .dockerconfigjson;
- 使用 base64 編碼方法對(duì) Docker 配置文件進(jìn)行編碼,然后粘貼該字符串的內(nèi)容,作為字段 data[“.dockerconfigjson”] 的值;
- 將 type 設(shè)置為 kubernetes.io/dockerconfigjson
示例:
apiVersion: v1 kind: Secret metadata: name: myregistrykey namespace: awesomeapps data: .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== type: kubernetes.io/dockerconfigjson
如果收到錯(cuò)誤消息:error: no objects passed to create, 這可能意味著 base64 編碼的字符串是無效的。如果收到類似 Secret “myregistrykey” is invalid: data[.dockerconfigjson]: invalid value … 的錯(cuò)誤消息,則表示數(shù)據(jù)中的 base64 編碼字符串已成功解碼, 但無法解析為 .docker/config.json 文件。
2、在命令行上提供憑據(jù)來創(chuàng)建 Secret
創(chuàng)建 Secret,命名為 regcred:
kubectl create secret docker-registry regcred \ --docker-server=<鏡像倉庫服務(wù)器> \ --docker-username=<用戶名> \ --docker-password=<密碼> \ --docker-email=<郵箱地址>
在這里:
- <your-registry-server> 是私有 Docker 倉庫全限定域名(FQDN)。 DockerHub 使用 https://index.docker.io/v1/;
- <your-name> 是 Docker 用戶名;
- <your-pword> 是 Docker 密碼;
- <your-email> 是 Docker 郵箱。
這樣就成功地將集群中的 Docker 憑據(jù)設(shè)置為名為 regcred 的 Secret。
四、檢查Secret regcred
要了解創(chuàng)建的 regcred Secret 的內(nèi)容,可以用 YAML 格式進(jìn)行查看:
kubectl get secret regcred –output=yaml
輸出和下面類似:
apiVersion: v1 kind: Secret metadata: ... name: regcred ... data: .dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0= type: kubernetes.io/dockerconfigjson
.dockerconfigjson 字段的值是 Docker 憑據(jù)的 base64 表示。要了解 dockerconfigjson 字段中的內(nèi)容,請(qǐng)將 Secret 數(shù)據(jù)轉(zhuǎn)換為可讀格式:
kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
輸出和下面類似:
{"auths":{"your.private.registry.example.com":{"username":"janedoe","password":"xxxxxxxxxxx","email":"jdoe@example.com","auth":"c3R...zE2"}}}
要了解 auth 字段中的內(nèi)容,請(qǐng)將 base64 編碼過的數(shù)據(jù)轉(zhuǎn)換為可讀格式:
echo "c3R...zE2" | base64 --decode
輸出結(jié)果中,用戶名和密碼用 : 鏈接,類似下面這樣:
janedoe:xxxxxxxxxxx
注意:Secret 數(shù)據(jù)包含與本地 ~/.docker/config.json 文件類似的授權(quán)令牌。這樣就已經(jīng)成功地將 Docker 憑據(jù)設(shè)置為集群中的名為 regcred 的 Secret。
五、創(chuàng)建用Secret的Pod
下面是一個(gè) Pod 配置清單示例,該示例中 Pod 需要訪問 Docker 憑據(jù) regcred:
apiVersion: v1 kind: Pod metadata: name: private-reg spec: containers: - name: private-reg-container image: <your-private-image> imagePullSecrets: - name: regcred
將上述文件下載到計(jì)算機(jī)中:
curl -L -o my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml
在 my-private-reg-pod.yaml 文件中,使用私有倉庫的鏡像路徑替換 <your-private-image>,例如:
your.private.registry.example.com/janedoe/jdoe-private:v1
要從私有倉庫拉取鏡像,Kubernetes 需要憑據(jù)。 配置文件中的 imagePullSecrets 字段表明 Kubernetes 應(yīng)該通過名為 regcred 的 Secret 獲取憑據(jù)。
創(chuàng)建使用了 Secret 的 Pod,并檢查它是否正常運(yùn)行:
kubectl apply -f my-private-reg-pod.yaml kubectl get pod private-reg
要為 Pod(或 Deployment,或其他有 Pod 模板的對(duì)象)使用鏡像拉取 Secret, 需要確保合適的 Secret 確實(shí)存在于正確的名字空間中。 要使用的是定義 Pod 時(shí)所用的名字空間。
此外,如果 Pod 啟動(dòng)失敗,狀態(tài)為 ImagePullBackOff,查看 Pod 事件:
kubectl describe pod private-reg
如果看到一個(gè)原因設(shè)為 FailedToRetrieveImagePullSecret 的事件, 那么 Kubernetes 找不到指定名稱(此例中為 regcred)的 Secret。 如果指定 Pod 需要拉取鏡像憑據(jù),kubelet 在嘗試?yán)$R像之前會(huì)檢查是否可以訪問該 Secret。
確保指定的 Secret 存在,并且其名稱拼寫正確。
Events: ... Reason ... Message ------ ------- ... FailedToRetrieveImagePullSecret ... Unable to retrieve some image pull secrets (<regcred>); attempting to pull the image may not succeed.