imagePullSecrets 确实是一个数组。 当你需要从多个不同的私有仓库(如 ://reg1.com, ://reg2.com, ://reg3.com)拉取镜像时,Kubernetes 提供了两种标准的应对策略。
可以根据团队的维护习惯,选择以下任意一种方式来对应这三个私有仓库:
🟢 方案一:一键合并(推荐,维护最清爽)
你不需要为每个仓库创建单独的 Secret。K8s 允许你在一个 Secret 里面包含多个仓库的账号密码。
- 创建包含三个仓库凭证的合集 Secret
使用 kubectl 创建时,重复输入 –docker-server、–docker-username 和 –docker-password 参数:
kubectl create secret docker-registry all-in-one-registry-secret \
--docker-server=://reg1.com --docker-username=userA --docker-password=passA \
--docker-server=://reg2.com --docker-username=userB --docker-password=passB \
--docker-server=://reg3.com --docker-username=userC --docker-password=passC \
-n <target-namespace>
- 将其 Patch 到 ServiceAccount
因为所有凭证都在这一个 Secret 里,你只需要在数组中填这一个名字:
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "all-in-one-registry-secret"}]}' -n <target-namespace>
🛠️ K8s 底层如何对应?
这个 Secret 的底层文件(.dockerconfigjson)其实是一个 JSON 字典,它会把域名当作 Key 存起来:
{
"auths": {
"://reg1.com": { "auth": "base64加密串A" },
"://reg2.com": { "auth": "base64加密串B" },
"://reg3.com": { "auth": "base64加密串C" }
}
}
当 Pod 拉取://reg1.com时,CRI 运行时(如 containerd)会拿着镜像里的域名 ://reg1.com 去这个 JSON 字典里自动匹配对应的解密凭证。
🟡 方案二:独立拆分(利用数组特性,职责更清晰)
如果这三个仓库是由不同团队管理的,账号密码经常独立变更,你也可以分别创建三个独立的 Secret,然后利用 imagePullSecrets 的数组(Array)特性把它们并列写进去。
- 分别创建三个独立的 Secret
kubectl create secret docker-registry secret-a --docker-server=://reg1.com --docker-username=userA --docker-password=passA -n <target-namespace>
kubectl create secret docker-registry secret-b --docker-server=://reg2.com --docker-username=userB --docker-password=passB -n <target-namespace>
kubectl create secret docker-registry secret-c --docker-server=://reg3.com --docker-username=userC --docker-password=passC -n <target-namespace>
- 将三个 Secret 一起 Patch 到 ServiceAccount(发挥数组作用)
利用方括号 [ 和 ],在数组中塞入三个对象,用逗号隔开:
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "secret-a"}, {"name": "secret-b"}, {"name": "secret-c"}]}' -n <target-namespace>
🛠️ K8s 底层如何对应?
当 Pod 去拉取://reg2.com镜像时,Kubelet 会把这三个 Secret 的凭证全部打包传给底层的容器运行时(containerd 或 docker)。
运行时在拉取时会采用轮询/匹配策略:它会依次检查这些 Secret 里的 server 域名,当发现 secret-b 里的域名正好是 ://reg2.com时,就会准确地掏出 secret-b 的账号密码去完成认证。
⚖️ 两种方案怎么选?
- 如果这些仓库都是你自己公司内部的(比如基础镜像库、开发测试库、生产成品库),强烈推荐 方案一(一键合并),因为将来写 Pod YAML 或者 Patch 的时候只需要管一个名字,极不容易出错。
- 如果某些仓库是外部第三方供应商提供的,或者是跨多部门合作的,推荐 方案二(独立拆分),方便哪天某个仓库改密码时,你只需要单独更新或删除某一个 Secret,不会影响到其他仓库。
- 标签 k8s