Kubernetes 集群拉取 Docker 镜像报错 “pull access denied”

问题现象:

使用 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 generic aliyun-registry-ee \
//  --from-file=.dockerconfigjson=/root/.docker/config.json \
//  --type=kubernetes.io/dockerconfigjson
# 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

Kubernetes 查看 docker secret 明文账号密码

kubectl get secrets foobar-registry -n default --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode

参考:

  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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容