5

在Kubernetes中pull私有镜像

 3 years ago
source link: https://note.qidong.name/2019/01/pull-private-images-in-k8s/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在Kubernetes中pull私有镜像

2019-01-12 08:51:37 +08  字数:1330  标签: K8s Docker

Kubernetes在自动pull私有镜像时,经常出现问题,导致ImagePullBackOff。 查看kubectl describe pod ...,还经常发现这类错误:

Failed create pod sandbox: rpc error: code = Unknown desc = failed pulling image ...
Error response from daemon: pull access denied for ...
repository does not exist or may require 'docker login'

这是因为没有正确配置pull权限所致。

~/.docker/config.json无效

首先,不要寄望于~/.docker/config.json。 与Docker Swarm不同,Kubernetes不会使用这里的配置来pull

当然,用docker login测试过账户、密码、Registry、镜像均无误后,再走下一步,是更好的选择。

使用imagePullSecrets

通过创建docker-registry类的secrets,可以实现类似docker login的功能。

kubectl create secret docker-registry regcred \
    --docker-server=<your-registry-server> \
    --docker-username=<your-name> \
    --docker-password=<your-pword> \
    --docker-email=<your-email>

其中,server、username和password都是必填项,email可以不填。

在使用时,把imagePullSecrets添加到Pod配置中。


apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: your-private-image
  imagePullSecrets:  - name: regcred

其中,regcredsecrets名称,可随意指定。

注意Namespace

即使创建了secrets、配置了imagePullSecrets,有时仍然无法pull镜像。 比如Calico的相关镜像,如果被同步到了本地一个私有Registry中,一般配置时无效的。

这是因为,Calico属于系统Network组件,Namespacekube-system。 而一般创建的secrets,属于default。 通过以下命令可以查看特定secrets的详细信息。


# kubectl get secret regcred -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJodHRwOi8vaGFyYm9yLnR1cmluZy1jaS5oaXNpbGljb24uY29tIjp7IlVzZXJuYW1lIjoiY2hyaXN0b3BoZXIiLCJQYXNzd29yZCI6IlFpZGRZYWZkQmF2YTYjIiwiRW1haWwiOiJ5MDA0NDU0ODBAbm90ZXNtYWlsLmh1YXdlaS5jb20ifX19
kind: Secret
metadata:
  creationTimestamp: "2019-01-10T08:51:03Z"
  name: regcred
  namespace: default
  resourceVersion: "100110"
  selfLink: /api/v1/namespaces/default/secrets/regcred
  uid: dc96580b-14b4-11e9-9f81-e435c87f8d90
type: kubernetes.io/dockerconfigjson

在创建secrets时需要指定Namespace

kubectl --namespace kube-system \
    create secret docker-registry regcred \
    --docker-server=<your-registry-server> \
    --docker-username=<your-name> \
    --docker-password=<your-pword> \
    --docker-email=<your-email>

不同Namespacesecrets可以同名,所以仍然可以叫regcred

注意:或者,在secrets创建后可以修改一些内容:

kubectl edit secret regcred --namespace=kube-system

但不能修改Namespace。 所以,必须在创建时准确指定。

用patch避免设置imagePullSecrets

每个私有镜像在使用前,都需要设置imagePullSecrets,这是一件非常繁琐的事。 在迁移服务时,它能有效地提醒secrets的迁移。 这是一个优点,但能被良好的迁移文档所解决。

patch可以避免这么繁琐。

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "regcred"}]}'

这相当于,在default这个Namespace中的所有镜像pull操作,都自动具备了regcred这个账户密码。

终于,和docker login一样了。

注意:这里的示例只针对default这个Namespace。 其它的Namespace需要一一执行patch。 某些场景下,比如网络组件Calico,似乎只能老老实实地写imagePullSecrets

对k8s系统镜像无效

系统镜像中,kube-proxypause是在所有Slave节点都需要使用的。 如果这些系统镜像被设为私有,则无法下载。 以上方法无效,原因不明。

所以,k8s系统镜像,即使同步到了本地Registry,也不要设为私有。

参考


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK