概述

Harbor使用了基于角色的访问控制策略,当从Harbor中拉去镜像的时候,首先要进行身份认证,认证通过后才可以拉取镜像。在命令行模式下,需要先执行docker login,登陆成功后,才可以docker pull。通常情况下,在私有云环境中使用kubernetes时,我们要从docker registry拉取镜像的时候,都会给docker daemo配置–insecure-registry属性来告诉docker daemo我们所使用的docker registry是可信的,这样才能从私有的docker registry中拉取镜像,但是如果要使用Harbor作为kubernetes的镜像仓库的话,这种方式就不适用了,下面让我们看看如何来使用Harbor作为kubernetes的镜像仓库。

测试

首先在docker login成功登录的情况下,不做其他任何配置看k8s能否从Harbor私有仓库拉取镜像:
以coredns为例:将本地的coredns:1.2.6镜像上传到harbor私有仓库,删除本地reg.harbor.com/k8s/coredns:1.2.6镜像,确保镜像会从私有仓库拉取。

docker login -u admin -p Harbor12345 reg.harbor.com
docker tag coredns/coredns:1.2.6 reg.harbor.com/k8s/coredns:1.2.6
docker push reg.harbor.com/k8s/coredns:1.2.6
docker rmi reg.harbor.com/k8s/coredns:1.2.6

修改coredns.yaml配置文件image: reg.harbor.com/k8s/coredns:1.2.6
启动:

# kubectl -n kube-system get pod
NAME                                    READY   STATUS         RESTARTS   AGE
coredns-78b7cdf8ff-qtb8t                0/1     ErrImagePull   0          5s

describe查看报错:

Failed to pull image "reg.harbor.com/k8s/coredns:1.2.6": rpc error: code = Unknown desc = Error response from daemon: pull access denied for reg.harbor.com/k8s/coredns, repository does not exist or may require 'docker login'

镜像拉取失败。

实现探索

我们在命令行方式下,输入docker login登陆成功后,会在/root/.docker/目前下生成一个config.json文件。打开后可以看到如下的内容:

# cat /root/.docker/config.json 
{
		"auths": {
				"reg.harbor.com": {
						"auth": "YWRtaW46SGFyYm9yMTIzNDU="
				}
		},
		"HttpHeaders": {
				"User-Agent": "Docker-Client/18.09.0 (linux)"
		}
}

这里的内容就是docker daemon用来与docker registry进行认证的,其中,reg.harbor.com是docker registry server的地址,auth部分是加密后的认证信息,当输入命令docker pull的时候,docker daemon会获取该文件中的信息,并将auth部分的信息携带在请求的头部向docker registry server发送请求,docker registry server对请求认证通过后,就可以开始拉取镜像了。

那么如何使kubernetes通过docker registry的认证来获取镜像呢?
Harbor与K8s的集成,一个核心概念是k8s的secret。作为kubernetes中一个重要的资源secret,它的设计初衷是为了解决容器在访问外部网络或外部资源时验证的问题,例如访问一个Git仓库,连接一个数据库,设置一些密码配置等,需要额外验证的场景Secret存储了敏感数据,例如能允许容器接受请求的权限令牌。通过将Harbor的用户信息与K8s的Secret相关联,即达成了两者的集成。

步骤: 首先在Harbor中创建创建用户,项目,将项目设置为私有,将创建的用户加入到项目中,设置用户的角色为开发者或者为项目管理员。确保该账户具有拉取该仓库镜像的权限。然后创建K8s下的Secret,其中secret中的用户名、密码和邮箱地址信息为在Harbor中创建的用户的信息

使用Harbor私库中的镜像在K8s的Namespace中部署应用,指定镜像下载时使用上面创建的Secret如果只需要能够拉取Harbor的镜像在K8s中部署应用,Harbor中的userD需要在项目中有最低权限的访客成员角色。

imagePullSecret在K8s中用来保存镜像仓库的认证信息,以方便Kubelet在启动Pod时,能够获得镜像仓库的认证信息,确保能Kubelet够有权限从镜像仓库中下载Pod所需的镜像。
创建k8s中的ImagePull类型的Secret:https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

实践

创建Secret:

# kubectl create secret docker-registry registry-secret \
	--namespace=kube-system \
	--docker-server=reg.harbor.com \
	--docker-username=admin \
	--docker-password=Harbor12345

# kubectl edit secret  registry-secret -n kube-system

引用Secret:

# vim coredns.yaml
  ....
  containers:
  - name: coredns
    image: reg.harbor.com/k8s/coredns:1.2.6
    imagePullPolicy: IfNotPresent
  ....
  imagePullSecrets:
  - name: registry-secret

再次启动测试:

# kubectl apply -f coredns.yaml

# kubectl -n kube-system get pod                     
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-cf4db5d8c-hfc7g                 1/1     Running   0          2m48s

Harbor提供了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制。kubernetes中通过namespace来对资源进行隔离,在企业级应用场景中,通过将两者进行结合可以有效将kubernetes使用的镜像资源进行管理和访问控制,增强镜像使用的安全性。尤其是在多租户场景下,可以通过租户、namespace和项目相结合的方式来实现对多租户镜像资源的管理和访问控制。

参考链接

https://www.kubernetes.org.cn/164.html
https://www.kubernetes.org.cn/1738.html

Logo

开源、云原生的融合云平台

更多推荐