Kubernetes拉取Harbor私有仓库的镜像

1. 前言

k8s在默认情况下,只能拉取harbor镜像仓库的公有镜像,如果拉取私有仓库镜像,则是会报 ErrImagePullImagePullBackOff 的错误:

Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  13s   default-scheduler  Successfully assigned learn/web-7c9c86c7d-hkh79 to k8s-master1
  Normal   Pulling    12s   kubelet            Pulling image "192.168.18.100:80/lnmp/nginx:v2"
  Warning  Failed     12s   kubelet            Failed to pull image "192.168.18.100:80/lnmp/nginx:v2": rpc error: code = Unknown desc = Error response from daemon: pull access denied for 192.168.18.100:80/lnmp/nginx, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
  Warning  Failed     12s   kubelet            Error: ErrImagePull
  Normal   BackOff    11s   kubelet            Back-off pulling image "192.168.18.100:80/lnmp/nginx:v2"
  Warning  Failed     11s   kubelet            Error: ImagePullBackOff

解决办法:

  1. 在harbor仓库中把镜像的项目设置为公开。
  2. 创建认证登录秘钥,拉取镜像时带上该秘钥。

2. k8s使用秘钥拉取harbor私有镜像

2.1 登录Docker

在服务器上,要想拉取私有镜像必须先在镜像仓库上进行身份验证,即登录harbor仓库:

[root@k8s-master ~]# docker login 192.168.18.100:80
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

我这里已经登录过了,所以会更新保存有授权令牌的 config.json 文件,这个就是登录Harbor的秘钥文件。从提示中可以看到是在 /root/.docker/config.json 中。这个文件内容如下:

[root@k8s-master ~]# cat /root/.docker/config.json 
{
	"auths": {
		"192.168.18.100:80": {
			"auth": "YWRtaW46SGFyYm9yMTIzNDU="
		}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.9 (linux)"
	}
}

2.2 对秘钥文件进行base64加密

[root@k8s-master ~]# cat ~/.docker/config.json |base64 -w 0
ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjE4LjEwMDo4MCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy45IChsaW51eCkiCgl9Cn0=

2.3 k8s创建secret秘钥

创建 docker-secret.yaml 文件

apiVersion: v1
kind: Secret
metadata:
  name: docker-login
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjE4LjEwMDo4MCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy45IChsaW51eCkiCgl9Cn0=

创建secret:

[root@k8s-master ~]# kubectl create -f docker-secret.yaml

查看secret:

[root@k8s-master ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-dbmds   kubernetes.io/service-account-token   3      28d
docker-login          kubernetes.io/dockerconfigjson        1      5h53m

2.4 创建应用,拉取Harbor私有仓库镜像

文件 nginx.yaml 内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web02
  labels:
    app: web02
  namespace: learn
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web02
  template:
    metadata:
      labels:
        app: web02
    spec:
      containers:
      - image: 192.168.18.100:80/lnmp/nginx:v2
        imagePullPolicy: IfNotPresent
        name: nginx
      imagePullSecrets:
      - name: docker-login
      dnsPolicy: ClusterFirst
      restartPolicy: Always

可以看到镜像成功拉取,Pod正常运行了:

[root@k8s-master ~]# kubectl -n learn get pods
NAME                     READY   STATUS    RESTARTS   AGE
web02-76969fc49b-j6fb4   1/1     Running   0          41s
[root@k8s-master ~]# kubectl -n learn get deployment 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
web02   1/1     1            1           49s

上面yaml文件中,拉取镜像下面携带秘钥的字段是 imagePullSecrets ,值填的是上面创建secret的名字。

上一篇:Docker 学习笔记


下一篇:centos部署harbor教程