Kubernetes 如何从私有镜像仓库拉取镜像

How does kubernetes pull images from a private image repository

Posted by alovn on November 27, 2020

为了安全考虑,我们上传镜像用的harbor仓库或者其它镜像仓库一般都要设置访问权限, 这样的K8S就会下载不到镜像,那应该怎么解决呢?

方法一

先在K8S中设置一个docker仓库的密钥

1
2
3
4
5
6
7
8
kubectl create secret docker-registry harbar-secret \
    --docker-server=harbor.lab.org \
    --docker-username=user1 \
    --docker-password=xxxxxx \
    [email protected]

//查看是否创建成功
kubectl get secrets

harbar-secret: 密钥的名称 docker-server: 镜像仓库的地址 docker-username: 登录镜像仓库的帐号 docker-password: 登录镜像仓库的帐号密码 docker-email: 邮件地址,选填

然后在yaml描述文件中增加imagePullSecrets

1
2
3
4
5
6
7
8
spec:
  containers:
  - name: api
    image: harbor.lab.org/library/api:v1.0.2
    ports:
    - containerPort: 18081
  imagePullSecrets:
    - name: harbor-secret

imagePullSecrets: 声明拉取镜像时要用的密钥, name指定的名称要和上面步骤中指定的名称相同,这里用的是harbor-secret。

方法二

每次都要在yaml声明文件中引入镜像仓库的密钥,显得有些麻烦,当然还有另外一种方式可以自动帮我们引入密钥的方式: 那就是在将密钥关联到 ServiceAccount 上。

如果你是使用的 default 账户,需要先导出默认帐号的YAML描述清单:

1
kubectl get serviceaccounts default -o yaml > ./sa.yaml

打开 sa.yaml 文件,删除带有键名 resourceVersion 的行,添加带有 imagePullSecrets 配置,最后保存文件。

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-11-22T05:25:33Z"
  name: default
  namespace: default
  uid: e7c0d6b6-1b87-43d9-b29a-ab99fa3568c2
secrets:
- name: default-token-hc484
imagePullSecrets:
- name: harbar-secret

最后,用新的更新的 sa.yaml 文件替换服务账号。

1
kubectl replace serviceaccount default -f ./sa.yaml

现在,在当前命名空间中创建的每个使用默认服务账号的新 Pod 会自动设置其 .spec.imagePullSecrets 字段, 可以验证一下:

1
2
kubectl run nginx --image=nginx --restart=Never
kubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'

不出意外会正常输出:harbar-secret,现在已经可以自动添加imagePullSecrets了。

参考文档

Add ImagePullSecrets to a service account