Harbor仓库Label和Repo驱动的镜像同步机制最佳实践
一、前言
Harbor仓库除了直接使用Docker Registry的Tag作为镜像的标签之外,额外还提供了一种Label标签机制,分为全局和项目两种形式,并以此可作为镜像同步的筛选机制。
我们可以利用Label来为不同的仓库设定不同的同步机制。这里提供了一套实践方法,大家可以参考并讨论。至于标题“最佳实践”,是噱头,哈哈,看大家自己的理解和适配,欢迎一起讨论优化。
二、Label和Repo驱动的同步机制
仓库设置如下:
(1)Harbor Dev:开发仓库,存放开发环境的镜像,开放SSO登录,直接面向所有开发用户,开发可以推送镜像,也可以拉取自己项目下的镜像,docker-compose独立部署,镜像存S3;
(2)Harbor QA:测试仓库,存放FAT和UAT环境的镜像,只有管理员及应用运维可以登录操作,在K8S环境部署,镜像存S3;
(3)Harbor PROD:生产仓库,存放生产在用的镜像,在K8S环境部署,镜像存S3;
(4)Harbor BAK:生产备份仓库,存放生产备份仓库以及Harbor及Kubernetes自身的镜像,docker-compose独立部署,镜像存S3。
镜像上传及同步机制:
- 普通开发用户通过Jenkins推送镜像到开发环境harbor的自己所属项目目录(例如library),默认是DEV标签
- 开发用户经过验证后可登录开发harbor仓库项目目录下将自己项目贴上UAT或者FAT标签
- 开发环境harbor仓库项目目录根据事件以及标签推送镜像到测试环境harbor仓库的中(带标签)
- 测试环境K8S集群将从测试仓库拉取镜像进行FAT和UAT测试
- 测试通过后开发通知管理人员或应用运维人员登录测试环境harbor仓库贴PROD标签
- 生产harbor仓库定时主动遍历并同步拉取测试环境harbor仓库library中Label为RPOD的镜像
- 生产harbor备份仓库定时备份生产的镜像数据
FAQ
1.为什么要区分生产和测试仓库?
生产毕竟是生产,尽量保持镜像的干净,用户也好,镜像也好,都尽量少,保持简单,这样出问题的概率小很多,一些企业对生产和测试管控也非常严格,特别是金融行业,不允许测试调生产的数据,所以我们图中也是生产主动pull测试仓库镜像,而不是测试push镜像到生产仓库。
.
2.为什么要区分开发和测试仓库?
因为harbor集成CI之后特别是微服务框架的项目,构建镜像非常频繁,镜像Tab标签非常多,一个项目动辄就到几百上千个Tag,镜像多了之后容易出各自问题,而我们不想因为开发问题影响到正常的测试环境,测试环境虽然不是生产,但也是构建生产的一个重要环节。而且也是和生产仓库同步的一个通道,如果测试环境被玩坏了,那么到生产大通道就堵死了。
.
3.为什么要分两种方式部署harbor仓库?
将Harbor搬进Kubernetes会带来极端情况下的一种问题就是死循环,Kubernetes里面harbor的镜像拉取的是Kubernetes里面的应用地址,有一个办法就是将harbor应用固定在某几个固定的节点上,并确保该些节点本地应用有harbor的镜像,但毕竟不够优雅,所以我们直接将harbor以及k8s自身的镜像放到集群外,通过docker-compose来部署即可,毕竟那属于应急的,单节点问题不大,排查起来也容易。
.
4.右下角的Image Dashboard是个什么鬼?
那个其实仅仅是一个生产镜像的Dashboard,用户可以去查看自己的镜像是否在生产/测试仓库是否存在,因为我们只有开发仓库是开放SSO方式给开发去登录的,测试环境和生产环境仓库我们是不允许用户登录的,因为harbor的访客权限依然是具有pull的权限(harbor1.10推出了Limit Guest账户,不过看起来也还是具有pull权限),而我们不想放开测试仓库和生产仓库的pull权限给到普通用户,只允许CI/CD或者管理员这种账户进行操作。所以为了给用户自助式检查自己生产仓库的镜像,我们推出了Image Dashboard看板,让用户自己检索自己的镜像是否存在,ImageDashboard会调用harbor api去检查,仅此而已。
三、Jenkins构建镜像自动给镜像贴Label
那么,如何让开发在Jenkins构建镜像的时候就自动给镜像贴Label标签呢?
1、在Harbor中建立全局的Label
首先,由管理员在Harbor仓库的配置管理-‘标签’当中建立4个全局标签,分别为dev、fat、uat、prod。
2、在Harbor中建一个专门的用户用来贴标签
为了区分和做权限隔离,我们创建一个专门的用户做贴标签的事情,如:harbor-label
3、在Jenkins里面创建Harbor仓库的全局凭据
在Jenkins设置“凭据”-“系统”-“全局凭据”当中创建类型为“Username with password”类型的凭据,输入刚在Harbor仓库建立的帐号密码信息
4、开发在Jenkins项目设置当中使用该凭据
(1)将该凭据加入到项目中
打开Jenkins中你的项目,在Build Environment当中勾选“use secret text(s) or file(s)”,点击“Add”,选择“Username and password (conjoined)”,然后选择上一步创建的Credentials,输入你想给这个Credential的引用变量名称,比如“HARBOR_LABEL_CREDENTIAL”,如下图所示。完成设置后保存,即可将此凭据当作环境变量用于你的项目。
(2)引用凭据调用Harbor API打Label标签
那么如何引用这个环境变量呢?有几种方式,具体看你的项目的设置
如果你的项目是Jenkins中的普通Job,那么可以在你Jenkins中项目的设置里“Build”模块“Excute Shell”当中直接引用该环境变量,并通过该环境变量调用Harbor API。以下为使用范例:
#!/bin/bash
repo=harbor.xxxx.com.cn
group=test
app=${your-project-name-in-harbor}
tag=$(cat version)-build${BUILD_NUMBER}
image=${repo}/${group}/${app}:${tag}
# allowd label value is dev/fat/uat/prod
label=fat
docker build -t $image -f ./Dockerfile .
docker push $image
# stick harbor image label
if [ "${label}"x = "dev"x ]; then
label_id=1
elif [ "${label}"x = "fat"x ]; then
label_id=2
elif [ "${label}"x = "uat"x ]; then
label_id=3
elif [ "${label}"x = "prod"x ]; then
label_id=4
else
echo "not support label, set to default dev"
label_id=1
fi
curl -X POST "http://${repo}/api/repositories/${group}%2F${app}/tags/${tag}/labels" --basic -u ${HARBOR_LABEL_CREDENTIAL} -H "accept: application/json" -H "Content-Type:application/json" \
-d "{\"id\": ${label_id}}"
如果你的项目是PipeLine项目,那么应用环境变量请参考如下:
# 声明式Declarative Pipeline
stage('Example') {
environment {
HARBOR_LABEL_CREDENTIAL = credentials('HARBOR_LABEL_CREDENTIAL')
}
steps {
echo 'done'
}
}
# 脚本式Script Pipeline
withCredentials([usernamePassword(credentialsId: 'HARBOR_LABEL_CREDENTIAL', passwordVariable: 'HARBOR_LABEL_CREDENTIAL_PWD)', usernameVariable: 'HARBOR_LABEL_CREDENTIAL_USER')]) {
// the code in here can access $pass and $user
}
5、Harbor中查看效果
完成后通过Jenkins构建镜像后可以登录Harbor查看Label:
更多推荐
所有评论(0)