#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像? 原创

键客李大白
发布于 2022-6-13 20:17
浏览
2收藏

[本文正在参加星光计划3.0–夏日挑战赛]
活动链接:https://ost.51cto.com/posts/13641#comment

前言

Harbor因为kubernetes而兴起,作为镜像存储仓库,那要如何才能使用呢?本篇文章分析kubernetes集群中,Pod中容器的镜像是如何从Harbor中拉取镜像的,看到这篇文章,相比你对kubernetes多多少少都有了解吧!

1、Pod中拉取Harbor中镜像的两种情况

k8s集群在部署pod过程中,有以下两种情况来拉取镜像:

1.1、拉取Harbor中的公有镜像

公有镜像,即供任何人都可以访问使用的镜像,如library公有项目下的镜像。pod部署到的主机(宿主机)的网络能跟Harbor服务器能通就行,不需要做特殊的配置。

1.2、拉取Harbor中的私有镜像

在Harbor的生成使用环境中,因为有很多不同的系统使用Harbor来存储、拉取镜像,为防止各个系统间造成影响,harbor管理员会为每个系统创建一个项目(project)和一个用户(user),然后将项目设置为私有项目,并且该项目对用户授权。

该系统在部署Pod的时候,要拉取分配的私有项目中的私有镜像时,还能直接拉取吗?在kubernetes中,可以通过Secrets资源对象(认证)来配置镜像拉取凭证,然后在imagePullSecrets字段(参数)指定对应的拉取凭证来拉取私有镜像。
#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

​# 2、主机配置​
Pod在拉取Harbor中的镜像是通过节点主机的容器运行时(CRI)来拉取的,本处以docker为例。需要对docker做些配置。
kubernetes集群中的每个节点都需要配置,至少要保证使用该镜像的Pod所在的节点都配置。

2.1、修改docker配置文件并重启服务

  • ​修改配置:
[root@sc-node1 ~]# vim  /etc/docker/daemon.json 
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": ["https://registry.docker.cn.com"],
    "insecure-registries": ["192.168.2.250:443"]      # 此处添加Harbor仓库地址(安全加密端口) 
}

2.1、修改docker配置文件并重启服务

• ​修改配置:

[root@sc-node1 ~]# vim  /etc/docker/daemon.json 
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": ["https://registry.docker.cn.com"],
    "insecure-registries": ["192.168.2.250:443"]      # 此处添加Harbor仓库地址(安全加密端口) 
}

• ​重新加载配置

[root@sc-node1 ~]# systemctl daemon-reload

重新启动docker服务

[root@sc-node1 ~]# systemctl restart docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

2.2 节点主机命令行登录Harbor

本处以test-1私有项目、用户lidabai/Lidabai123为演示。
1)命令行登录harbor

[root@sc-node1 ~]# docker login https://192.168.2.250:443 -u lidabai  -p Lidabai123
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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

如果登录报错,需要检查docker的配置及网络与Harbor是否正常。
注:
Pod所在节点主机均需要登录成功!登录成功后,会在当前用户下生成 .docker/config.json 文件,该文件记录了相关的登录信息,后面会基于该文件来制作镜像拉取凭证。

[root@sc-node1 ~]# pwd
/root
[root@sc-node1 ~]# ls  -la .docker/
总用量 4
drwx------  2 root root  25 4月   4 11:07 .
dr-xr-x---. 4 root root 178 4月   4 11:07 ..
-rw-------  1 root root 155 4月   4 11:07 config.json     # 该文件记录了相关的登录信息

2)查看登录的密钥数据

[root@sc-node1 ~]# cat ~/.docker/config.json 
{
  "auths": {
    "192.168.2.250:443": {
      "auth": "bGlkYWJhaTpMaWRhYmFpMTIz"
    }
  },
  "HttpHeaders": {
    "User-Agent": "Docker-Client/19.03.8 (linux)"
  }
}[root@sc-node1 ~]#

3) 对密钥进行加密
用BASE64编码dockercfg内容,注意一下要用到编码后的子串。

[root@sc-node1 ~]#  cat ~/.docker/config.json  | base64 -w 0
ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjIuMjUwOjQ0MyI6IHsKCQkJImF1dGgiOiAiYkdsa1lXSmhhVHBNYVdSaFltRnBNVEl6IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy44IChsaW51eCkiCgl9Cn0=[root@sc-node1 ~]#

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区
​ -w 0 表示生成秘钥不转行,默认转行不是正确的格式会出错!

3、创建Secret资源对象​

在kubernetes集群管理节点操作!

3.1 编写资源清单文件

[root@sc-master1 ~]# vim  harbor-image-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: harbor-pull-secret
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjIuMjUwOjQ0MyI6IHsKCQkJImF1dGgiOiAiYkdsa1lXSmhhVHBNYVdSaFltRnBNVEl6IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy44IChsaW51eCkiCgl9Cn0=

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

3.2 更新资源清单文件

[root@sc-master1 ~]# kubectl apply -f harbor-image-secret.yaml
secret/harbor-pull-secret created
[root@sc-master1 ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-qkbdw   kubernetes.io/service-account-token   3      9d
harbor-pull-secret    kubernetes.io/dockerconfigjson        1      13s   # 是这个!!!

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

扩展:命令行创建secret

# kubectl create secret docker-registry image-secret \
--docker-server=https://192.168.2.250:443  \
--docker-username=lidabai  --docker-password=lidabai123

4、容器中指定镜像拉取凭证​

Secret制作的镜像拉取凭证制作好后,就可以在创建Pod时使用了。
本处以拉取test-1私有项目下的​192.168.2.250:443/test-1/traefik:2.6.2​私有镜像为例,lidabai用户以“开发者”的角色拥有对test-1项目的镜像上传、拉取权限。

4.1 环境说明

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区
#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区
#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

4.2 编写测试资源清单文件

[root@sc-master1 ~]# vim traefik.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
       - name: nginx
         image: 192.168.2.250:443/test-1/traefik:2.6.2
         imagePullPolicy: IfNotPresent
      imagePullSecrets:           # 镜像拉取凭证
       - name: harbor-pull-secret  # 镜像拉取凭证的名称,填入刚才创建的secret名称!!!
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
           - labelSelector:
               matchExpressions:
               - key: app
                 operator: In
                 values:
                 - nginx
             topologyKey: kubernetes.io/hostname

4.3、更新资源清单文件

[root@sc-master1 ~]# kubectl apply -f traefik.yaml
deployment.apps/traefik created

4.4、查看资源部署状态(验证)

[root@sc-master1 ~]# kubectl get  pods  -owide
NAME                       READY   STATUS         RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
traefik-599b969746-5xc6r   1/1     Running        0          56s   10.244.119.243   sc-node1   <none>           <none>
traefik-599b969746-9pw72   0/1     ErrImagePull   0          56s   10.244.242.136   sc-node2   <none>           <none>

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

可以看到,有个Pod创建失败了,因为镜像拉取失败!

4.4、故障分析

我的kubernetes集群是1master,2node节点,2个pod副本分别调度到两个node节点,之前在主机登录docker的时候,master和node1均有操作,但node2没有登录到harbor,从而没有生成~/.docker/config.json文件。

[root@sc-master1 ~]# kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
sc-master1   Ready    control-plane,master   9d    v1.20.6
sc-node1     Ready    <none>                 9d    v1.20.6
sc-node2     Ready    <none>                 15h   v1.20.6
[root@sc-node2 ~]# pwd
/root
[root@sc-node2 ~]# ls  -la  
总用量 110552
dr-xr-x---.  3 root root       191 4月   3 20:12 .
dr-xr-xr-x. 17 root root       224 2月   8 17:05 ..
-rw-------.  1 root root      1216 2月   8 17:06 anaconda-ks.cfg
-rw-------.  1 root root      3047 4月   4 11:16 .bash_history
-rw-r--r--.  1 root root        18 12月 29 2013 .bash_logout
-rw-r--r--.  1 root root       176 12月 29 2013 .bash_profile
-rw-r--r--.  1 root root       176 12月 29 2013 .bashrc
-rw-r--r--.  1 root root       100 12月 29 2013 .cshrc
-rw-r--r--   1 root root 113171272 8月  30 2021 docker-ce-rpm.tar.gz
drwxr-----   3 root root        19 2月  18 18:01 .pki
-rw-r--r--.  1 root root       129 12月 29 2013 .tcshrc
-rw-------   1 root root      1712 3月  16 09:42 .viminfo

解决: node2节点在命令行登录harbor!

[root@sc-node2 ~]# docker login https://192.168.2.250:443 -u lidabai  -p Lidabai123
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://192.168.2.250:443/v2/: x509: cannot validate certificate for 192.168.2.250 because it doesn't contain any IP SANs
[root@sc-node2 ~]# vim /etc/docker/daemon.json 
[root@sc-node2 ~]# systemctl daemon-reload 
[root@sc-node2 ~]# systemctl restart docker
[root@sc-node2 ~]# docker login https://192.168.2.250:443 -u lidabai  -p Lidabai123
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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
[root@sc-node2 ~]# ls  -la  
drwx------   2 root root        25 4月   4 12:07 .docker

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

再次查看Pod状态:

[root@sc-master1 ~]# kubectl get  pod  -owide
NAME                       READY   STATUS             RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
traefik-599b969746-5xc6r   1/1     Running            0          13m   10.244.119.243   sc-node1   <none>           <none>
traefik-599b969746-9pw72   0/1     ImagePullBackOff   0          13m   10.244.242.140   sc-node2   <none>           <none>
[root@sc-master1 ~]# kubectl get  pod  -owide
NAME                       READY   STATUS    RESTARTS   AGE   IP               NODE       NOMINATED NODE   READINESS GATES
traefik-599b969746-5xc6r   1/1     Running   0          16m   10.244.119.243   sc-node1   <none>           <none>
traefik-599b969746-9pw72   1/1     Running   0          16m   10.244.242.140   sc-node2   <none>           <none>

#夏日挑战赛# k8s节点如何从Harbor中拉取私有镜像?-鸿蒙开发者社区

可以看到,node2上的pod也拉取到Harbor私有仓库的镜像了。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-6-13 20:18:05修改
7
收藏 2
回复
举报
3条回复
按时间正序
/
按时间倒序
seiichi123
seiichi123

感谢分享。学习!

回复
2022-7-29 10:39:19
冷月星
冷月星

感谢分享。

回复
2022-7-29 17:35:52
wx62cbd5dd59205
wx62cbd5dd59205

这三个节点都需要安装docker,不太合适。

只有harbor所在节点需要有harbor, 其他节点使用containerd拉取镜像。

 

回复
2022-9-6 16:13:11
回复
    相关推荐