0
点赞
收藏
分享

微信扫一扫

k8s节点如何从Harbor中拉取镜像的?镜像拉取凭证的配置

k8s节点如何从Harbor中拉取镜像的?镜像拉取凭证的配置_kubernetes


前言

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中拉取镜像的?镜像拉取凭证的配置_docker_02


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仓库地址(安全加密端口)
}
  • 重新加载配置
[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 44 11:07 .
dr-xr-x---. 4 root root 178 44 11:07 ..
-rw------- 1 root root 155 44 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中拉取镜像的?镜像拉取凭证的配置_kubernetes_03

-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中拉取镜像的?镜像拉取凭证的配置_centos_04


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中拉取镜像的?镜像拉取凭证的配置_系统/运维_05

扩展:命令行创建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中拉取镜像的?镜像拉取凭证的配置_kubernetes_06

k8s节点如何从Harbor中拉取镜像的?镜像拉取凭证的配置_系统/运维_07

k8s节点如何从Harbor中拉取镜像的?镜像拉取凭证的配置_docker_08


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中拉取镜像的?镜像拉取凭证的配置_harbor_09

可以看到,有个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 43 20:12 .
dr-xr-xr-x. 17 root root 224 28 17:05 ..
-rw-------. 1 root root 1216 28 17:06 anaconda-ks.cfg
-rw-------. 1 root root 3047 44 11:16 .bash_history
-rw-r--r--. 1 root root 18 1229 2013 .bash_logout
-rw-r--r--. 1 root root 176 1229 2013 .bash_profile
-rw-r--r--. 1 root root 176 1229 2013 .bashrc
-rw-r--r--. 1 root root 100 1229 2013 .cshrc
-rw-r--r-- 1 root root 113171272 830 2021 docker-ce-rpm.tar.gz
drwxr----- 3 root root 19 218 18:01 .pki
-rw-r--r--. 1 root root 129 1229 2013 .tcshrc
-rw------- 1 root root 1712 316 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 44 12:07 .docker

k8s节点如何从Harbor中拉取镜像的?镜像拉取凭证的配置_harbor_10

再次查看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中拉取镜像的?镜像拉取凭证的配置_centos_11

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


      ~本文完~


举报

相关推荐

0 条评论