Kubernetes 集群拉取 Docker 镜像报错 “pul

2020-12-30  本文已影响0人  awker

问题现象:

使用 kubectl create -f release.yaml 创建 deployment 时,启动的 pod 无法拉取镜像,报错 Unknown desc = Error response from daemon: pull access denied for cr.registry.platform.foobar.cn/prod/foobar, repository does not exist or may require 'docker login' 如下:

# kubectl describe pod foobar-699df4f77b-8zkvj
省略其他……
Events:
  Type     Reason     Age                 From                                                  Message
  ----     ------     ----                ----                                                  -------
  Normal   Scheduled  80s                 default-scheduler                                     Successfully assigned default/foobar-699df4f77b-8zkvj to cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8
  Normal   Pulling    72s (x3 over 108s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8  Pulling image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Warning  Failed     72s (x3 over 108s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8  Failed to pull image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11": rpc error: code = Unknown desc = Error response from daemon: pull access denied for cr.registry.platform.foobar.cn/prod/foobar, repository does not exist or may require 'docker login'
  Warning  Failed     72s (x3 over 108s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8  Error: ErrImagePull
  Normal   BackOff    37s (x6 over 107s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8  Back-off pulling image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Warning  Failed     37s (x6 over 107s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc8  Error: ImagePullBackOff

直接在 node 节点上 docker pull 可以拉取镜像。

# docker pull cr.registry.platform.foobar.cn/prod/foobar:1.5.11
1.5.11: Pulling from prod/foobar
840caab23da4: Pull complete 
c73e835deefd: Pull complete 
2eec68d27246: Pull complete 
c5cfd8d4e231: Pull complete 
db1ee2b864ce: Pull complete 
8d01cb45f656: Pull complete 
b47d363c0228: Pull complete 
0dd590ba0e0b: Pull complete 
b15216aaf651: Pull complete 
da20bc470edc: Pull complete 
ae966cba2cfc: Pull complete 
642b4b98622b: Pull complete 
Digest: sha256:f523eb8b8f1c1da7c659a6a2a60bfc611ef7287e42e724eb4e99e8a37076f53e
Status: Downloaded newer image for cr.registry.platform.foobar.cn/prod/foobar:1.5.11

原因分析:

cr.registry.platform.foobar.cn/prod/foobar:1.5.11 存放在自建的私有镜像仓库中。kubernetes 并不能直接使用 docker 的 /root/.docker/config.json 凭证拉取这个镜像,需要单独配置自己的凭证来拉取镜像。

解决办法:

方式一:使用密钥编排容器,在 Pod 上指定 ImagePullSecrets。

// 查看 kubernetes 的 secret
# kubectl get secret -o wide
NAME                      TYPE                                  DATA   AGE
aliyun-acr-credential-a   kubernetes.io/dockerconfigjson        1      24d
aliyun-acr-credential-b   kubernetes.io/dockerconfigjson        1      24d
default-token-x9m7q       kubernetes.io/service-account-token   3      24d

// 创建 kubernetes 拉取私有镜像仓库的凭证 foobar-registry。
# kubectl create secret docker-registry foobar-registry --docker-server=私有镜像仓库地址 --docker-username=用户名 --docker-password=密码 --docker-email=邮箱
secret/foobar-registry created

# kubectl get secret -o wide
NAME                      TYPE                                  DATA   AGE
aliyun-acr-credential-a   kubernetes.io/dockerconfigjson        1      24d
aliyun-acr-credential-b   kubernetes.io/dockerconfigjson        1      24d
default-token-x9m7q       kubernetes.io/service-account-token   3      24d
foobar-registry             kubernetes.io/dockerconfigjson        1      2s

// 在 Pod 上指定 ImagePullSecrets 为 foobar-registry 来拉取镜像。
# vim release.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foobar
  labels:
    app: foobar
spec:
  replicas: 2
  selector:
    matchLabels:
      app: foobar
  template:
    metadata:
      labels:
        app: foobar
    spec:
      containers:
      - name: foobar
        image: cr.registry.platform.foobar.cn/prod/foobar:1.5.11
        imagePullPolicy: Always
      imagePullSecrets:
      - name: foobar-registry


# kubectl create -f release.yaml
// 查看 kubernetes pod 事件,可以知道成功拉取了私有镜像仓库的镜像
# kubectl describe pod foobar-699df4f77b-8zkvj
省略其他……
Events:
  Type     Reason     Age                From                                                  Message
  ----     ------     ----               ----                                                  -------
  Normal   Pulling    31s (x3 over 45s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Pulling image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Normal   Pulled     31s (x3 over 45s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Successfully pulled image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Normal   Created    31s (x3 over 45s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Created container foobar
  Normal   Started    31s (x3 over 45s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Started container foobar

方式二:实现无密钥编排,为服务账户添加 ImagePullSecrets。

// 查看 kubernetes 的 serviceaccounts 
# kubectl get serviceaccounts default -o yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-12-04T10:04:26Z"
  name: default
  namespace: default
  resourceVersion: "344"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 1740b59c-3618-11eb-848c-00163e01064f
secrets:
- name: default-token-x9m7q

// 导出 服务账户 的配置文件
# kubectl get serviceaccounts default -o yaml > /tmp/sa.yaml
# cat /tmp/sa.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-12-04T10:04:26Z"
  name: default
  namespace: default
  resourceVersion: "344"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 1740b59c-3618-11eb-848c-00163e01064f
secrets:
- name: default-token-x9m7q

// 删除了 resourceVersion 字段,添加了 imagePullSecrets 字段,name 为上述添加的 secret foobar-registry
# vim /tmp/sa.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-12-04T10:04:26Z"
  name: default
  namespace: default
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 1740b59c-3618-11eb-848c-00163e01064f
secrets:
- name: default-token-x9m7q
imagePullSecrets:
- name: foobar-registry

// 替换现有的 服务账户 的配置文件
# kubectl replace serviceaccount default -f /tmp/sa.yaml 
serviceaccount/default replaced
# kubectl get serviceaccounts default -o yaml 
apiVersion: v1
imagePullSecrets:
- name: foobar-registry
kind: ServiceAccount
metadata:
  creationTimestamp: "2020-12-04T10:04:26Z"
  name: default
  namespace: default
  resourceVersion: "5918451"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: 1740b59c-3618-11eb-848c-00163e01064f
secrets:
- name: default-token-x9m7q

// 在 Pod 上不用单独指定 ImagePullSecrets 来拉取镜像。因为配置了 serviceaccounts 的 ImagePullSecrets,可以直接拉取镜像。
# vim release.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foobar
  labels:
    app: foobar
spec:
  replicas: 2
  selector:
    matchLabels:
      app: foobar
  template:
    metadata:
      labels:
        app: foobar
    spec:
      containers:
      - name: foobar
        image: cr.registry.platform.foobar.cn/prod/foobar:1.5.11
        imagePullPolicy: Always

# kubectl create -f release.yaml
// 查看 kubernetes pod 事件,可以知道成功拉取了私有镜像仓库的镜像
# kubectl describe pod foobar-699df4f77b-ngg7f
Events:
  Type     Reason     Age                From                                                  Message
  ----     ------     ----               ----                                                  -------
  Normal   Pulling    26s (x3 over 41s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Pulling image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Normal   Pulled     26s (x3 over 41s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Successfully pulled image "cr.registry.platform.foobar.cn/prod/foobar:1.5.11"
  Normal   Created    26s (x3 over 41s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Created container foobar
  Normal   Started    26s (x3 over 40s)  kubelet, cn-shanghai-foobar-d01.i-a0z01nzs2pkled5iikc9  Started container foobar

参考:

  1. 使用私有仓库:https://kubernetes.io/zh/docs/concepts/containers/images/#using-a-private-registry
  2. 在 Pod 上指定 ImagePullSecrets:https://kubernetes.io/zh/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
  3. 为服务账户添加 ImagePullSecrets:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
  4. 在Kubernetes集群如何支持私有镜像:https://help.aliyun.com/knowledge_detail/86562.html
上一篇下一篇

猜你喜欢

热点阅读