在這篇文章中,我將向你展示如何在 Kubernetes 中使用 imagePullSecrets。
Kubernetes 在每個 Pod 或每個 Namespace 的基礎上使用 imagePullSecrets 對私有容器登入檔進行身份驗證。要做到這一點,你需要建立一個祕密與憑據:
{% note warning %}
⚠️ 警告:
現在隨著公共映象倉庫(如:docker.io 等)開始對匿名使用者進行限流,設定公共倉庫的身份認證也變得有必要。
{% endnote %}
kubectl create secret docker-registry image-pull-secret \
-n <your-namespace> \
--docker-server=<your-registry-server> \
--docker-username=<your-name> \
--docker-password=<your-password> \
--docker-email=<your-email>
例如設定 docker.io 的 pull secret:
kubectl create secret docker-registry image-pull-secret-src \
-n imagepullsecret-patcher \
--docker-server=docker.io \
--docker-username=caseycui \
--docker-password=c874d654-xxxx-40c6-xxxx-xxxxxxxx89c2 \
[email protected]
{% note info %}
ℹ️ 資訊:
如果 docker.io 啟用了「2 階段認證」,可能需要建立 Access Token(對應上面的 docker-password
,建立連結在這裡:賬號 -> 安全
{% endnote %}
現在我們可以在一個 pod 中使用這個 secret 來下載 docker 映象:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: private-registry-test
spec:
containers:
- name: my-app
image: my-private-registry.infra/busybox:v1
imagePullSecrets:
- name: image-pull-secret
另一種方法是將它新增到名稱空間的預設 ServiceAccount 中:
kubectl patch serviceaccount default \
-p "{\"imagePullSecrets\": [{\"name\": \"image-pull-secret\"}]}" \
-n <your-namespace>
我找到了一個叫做 imagepullsecret-patch
的工具,它可以在你所有的名稱空間上做這個:
wget https://raw.githubusercontent.com/titansoft-pte-ltd/imagepullsecret-patcher/185aec934bd01fa9b6ade2c44624e5f2023e2784/deploy-example/kubernetes-manifest/1_rbac.yaml
wget https://raw.githubusercontent.com/titansoft-pte-ltd/imagepullsecret-patcher/master/deploy-example/kubernetes-manifest/2_deployment.yaml
kubectl create ns imagepullsecret-patcher
編輯下載的檔案,一般需要修改image-pull-secret-src
的內容,這個 pull secret 就會應用到 K8S 叢集範圍。
nano 1_rbac.yaml
nano 2_deployment.yaml
kubectl apply -f 1_rbac.yaml
kubectl apply -f 2_deployment.yaml
這裡背後建立的資源有:
imagepullsecret-patcher
ServiceAccountimagepullsecret-patcher
ClusterRole,具有對 service account 和 secret 的所有許可權imagepullsecret-patcher
ClusterRoleBinding,為 imagepullsecret-patcher
ServiceAccount 賦予 imagepullsecret-patcher
ClusterRole 的許可權。image-pull-secret-src
,裡面是你的 K8S 全域性包含的所有的映象庫地址和認證資訊。imagepullsecret-patcher
,指定 ServiceAccount 是 imagepullsecret-patcher
就有了操作 service account 和 secret 的所有許可權,並將上面的 secret 掛載到 Deployment pod 內。可以包含多個映象庫地址和認證資訊,如:
{
"auths": {
"docker.io": {
"username": "caseycui",
"password": "c874xxxxxxxxxxxxxxxx1f89c2",
"email": "[email protected]",
"auth": "Y2FzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxWMy"
},
"quay.io": {
"auth": "ZWFzdxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxlXWmpNPQ==",
"email": ""
}
}
}
base64 編碼後寫到 secret 的 .dockerconfigjson
欄位即可:
apiVersion: v1
kind: Secret
metadata:
name: image-pull-secret-src
namespace: imagepullsecret-patcher
data:
.dockerconfigjson: >-
eyJhdXRocyI6eyJkb2NrZXIuaW8iOnsidXNlcm5hbWUiOiJjYXNleWN1aSIsInB.............................................IiwiZW1haWwiOiIifX19
type: kubernetes.io/dockerconfigjson
啟動後的 pod 會在所有 NameSpace 下建立 image-pull-secret
secret(內容來自於image-pull-secret-src
) 並把它 patch 到 default
service account 及該 K8S 叢集的所有 ServiceAccount 裡,紀錄檔如下:
time="2022-01-12T16:07:30Z" level=info msg="Application started"
time="2022-01-12T16:07:30Z" level=info msg="[default] Created secret"
time="2022-01-12T16:07:30Z" level=info msg="[default] Patched imagePullSecrets to service account [default]"
time="2022-01-12T16:07:30Z" level=info msg="[kube-system] Created secret"
time="2022-01-12T16:07:31Z" level=info msg="[kube-system] Patched imagePullSecrets to service account [node-controller]"
...
time="2022-01-12T16:07:37Z" level=info msg="[kube-public] Created secret"
time="2022-01-12T16:07:37Z" level=info msg="[kube-public] Patched imagePullSecrets to service account [default]"
time="2022-01-12T16:07:38Z" level=info msg="[kube-node-lease] Created secret"
time="2022-01-12T16:07:38Z" level=info msg="[kube-node-lease] Patched imagePullSecrets to service account [default]"
time="2022-01-12T16:07:38Z" level=info msg="[prometheus] Created secret"
time="2022-01-12T16:07:39Z" level=info msg="[prometheus] Patched imagePullSecrets to service account [default]"
...
time="2022-01-12T16:07:41Z" level=info msg="[imagepullsecret-patcher] Created secret"
time="2022-01-12T16:07:41Z" level=info msg="[imagepullsecret-patcher] Patched imagePullSecrets to service account [default]"
time="2022-01-12T16:07:41Z" level=info msg="[imagepullsecret-patcher] Patched imagePullSecrets to service account [imagepullsecret-patcher]"
今後我們只需要更新 image-pull-secret-src
這一個即可了。