Harbor介绍及实践
以Docker为代表的容器技术的出现,改变了传统的交付方式。通过把业务及其依赖的环境打包进Docker镜像,解决了开发环境和生产环境的差异问题,提升了业务交付的效率。如何高效地管理和分发Docker镜像?是众多企业需要考虑的问题。
1
Harbor简介
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,可以用来构建企业内部的Docker镜像仓库。
它在Docker的开源项目 Distribution的基础上,添加了一些企业需要的功能特性,如镜像同步复制、漏洞扫描和权限管理等。
它的主要功能包括:
2
Harbor架构
Harbor集成了很多功能组件,以实现上面提到的功能特性。但有些组件并不是必需的,可以根据自己的实际情况,进行选择使用。比如:Vulnerability Scanning组件是用来对镜像进行漏洞扫描的,如果你确信镜像不会有漏洞,或者你已经用其它工具扫描过了,那可以不使用这个组件。
当前,最新版本(v1.2)的架构图如下
(图片来源于
——<<采用Harbor开源企业级Registry实现高效安全的镜像运维>> 张海宁)
3
Docker镜像权限管理
企业中的软件研发团队往往划分为诸多角色,如项目经理、产品经理、测试、运维等。在实际的软件开发和运维过程中,这些角色对于镜像的使用需求是不一样的。从安全的角度,也是需要通过某种机制来进行权限控制的。
例如,测试人员通常只需要镜像的读权限(pull),开发人员需要读写权限(push/pull),项目经理除了拥有开发人员的权限之外,还可以增加和删除项目成员,设定他们的角色。
Harbor提供了基于project的镜像权限控制功能。如下图,在一个project里,可以有Guest, Developer和Admin等角色:Guest只有读权限,Developer有读写权限,Admin是project的管理者,除了读写权限外,它还可以给project添加成员,启动漏洞扫描等权限。
(图片来源于https://github.com/vmware/harbor/blob/master/docs/user_guide.md)
4
Docker镜像管理参考流程
在使用Harbor管理Docker镜像时,可以把所有镜像都存放在一个Harbor实例中,也可以把镜像分类,存放到不同Harbor实例中。例如:开发、测试和运维都使用同一个Harbor,这样“简单粗暴”的方式比较适合小团队或简单的项目。其他情况,在条件允许的情况下,最好使用多个Harbor以区分不同的用途。如下图,容器镜像管理的参考流程。
(图片来源于
——<<采用Harbor开源企业级Registry实现高效安全的镜像运维>> 张海宁)
一个生产镜像的产生,需要经过四个步骤:
1) 当开发人员提交代码后,触发CI系统编译代码,并打包生成镜像,推送到Dev Registry;
2) 开发人员自测没有问题后,可以推送到Test Registry;
3) 测试人测试没有问题后,可以推送到Staging Registry;
4) 再经过相应的审批,可以将推送到Product Registry。
5
Docker镜像远程同步复制功能
如下图所示,Harbor提供了基于策略的镜像同步复制功能。以项目为单位,通过配置复制同步策略,可以实现在多个Harbor实例间进行镜像同步复制。Harbor的镜像同步功能支持错误或失败重传,支持镜像增量同步复制。
(图片来源于
——<<采用Harbor开源企业级Registry实现高效安全的镜像运维>> 张海宁)
该功能目前只支持镜像的同步复制,其它信息,如用户、复制规则等,还不支持同步复制。
6
Harbor实践
高可用负载均衡方案
Harbor官方提供的安装包,默认是单机部署的,各组件都只有一个容器,存在单点故障的风险。在要求不高的场合下,可以使用;但在生产环境中,一般是不能直接使用的。
Harbor有很多种高可用负载均衡方案,结合公司目前的情况,使用基于镜像同步复制的高可用方案,方案框架图如下。
图中的Harbor包含了除DB(Mysql镜像)外的Harbor其它组件。Keepalived和HAproxy用来实现流量入口的高可用和负载均衡。
两个Harbor实例(除DB外)组件的高可用,两个实例之间需要配置镜像同步复制规则,以实现镜像的备份。两个实例需要共享DB,但同一时刻内只会有一个实例会访问DB。DB由DBA提供高可用方案。
使用此方案有个明显的问题。两个Harbor实例都需要配置到目标实例的镜像同步复制规则,但由于两个实例属于共享一个数据库,所以就会出现把镜像同步给自己的问题,从而导致失败,且一直会重试。一个解决方法是在镜像同步复制的代码中判断一下目标实例是否为自己,如果是,则直接返回成功即可。
镜像自动化删除
默认情况下,Harbor将镜像存储在本地磁盘,随着镜像越来越多,可能会导致磁盘空间不够。为了提供磁盘的利用率,需要把不用或者多余的镜像删除。Harbor提供了删除镜像的功能,但需要手动去处理。
可以采用cron job定期去运行镜像删除脚本来实现镜像自动化删除。脚本通过调用Harbor的RESTful API,来获取要删除镜像的名称和tag。删除镜像的过程如下:
1) 获取所有project并解析project_id字段,得到project的个数;
2) 获取每个project的repo名称;
3) 根据repo名称获取每个repo下的tag并统计个数;
4) 若tag数大于规定的个数,进行排序,删除最早的tag(并不会删除镜像);
5) 删除镜像,命令如下:
docker-compose stop;
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.1-photon garbage-collect /etc/registry/config.yml;
docker-compose start;
对接公司OA系统
Harbor有自己的登录界面,但新用户需要先去注册,或者由管理员创建后,才可登录,不方便使用。通过对接公司的OA系统,可以用OA的用户名和密码登录Harbor。
Harbor使用go语言开发,WEB框架采用beego,beego支持自定义过滤中间件,例如安全验证,强制跳转等。
实现对接OA系统功能的要点:
1) 添加beego过滤器函数,添加Harbor所有页面:
beego.InsertFilter("/*",beego.BeforeRouter, PageFilter)
2) 实现PageFilter函数,其内部流程大致如下:
7
总结和展望
Harbor的github社区活跃度很高,凭借其实用的功能,也吸引了众多企业。目前,Harbor官方并未给出具体的高可用部署方案,用户需要根据自己的情况来设计合适的高可用方案并完成部署。文中提到的高可用方案,也只是一种简单的实现。
本文简单地介绍了Harbor及一些实践,后续还有很多可以做的工作,如对接CI/CD系统、使用分布式存储系统(如ceph)作为 Harbor后端存储等等。
参考文档
[1] https://github.com/vmware/harbor
[2] <<采用Harbor开源企业级Registry实现高效安全的镜像运维>> 张海宁
关于作者
琚汝强@vivo