Docker实践记录(二):使用Harbor搭建Docker私有仓库

  categories:资料  author:

写在前面:

针对于公司内部使用的镜像,我们希望推送到本地的私有docker仓库中,以供公司内部相关人员下载使用,所以准备研究使用harbor完成此功能,此文章只是研究,实际生产环境需要采用高可用的架构,之后也会搭建研究。

Harbor介绍:

Harbor是VMware公司开源的企业级DockerRegistry项目,项目地址为https://github.com/vmware/harbor。其目标是帮助用户迅速搭建一个企业级的Dockerregistry服务。它以Docker公司开源的registry为基础,提供了管理UI,基于角色的访问控制(Role Based Access Control),AD/LDAP集成、以及审计日志(Auditlogging) 等企业用户需求的功能,同时还原生支持中文。Harbor的每个组件都是以docker容器的形式构建的,使用Docker Compose来对它进行部署。

Harbor的特点:

  • 基于角色的访问控制 – 用户与Docker镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
  • 镜像复制 – 镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
  • 图形化用户界面 – 用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
  • AD/LDAP 支持 – Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
  • 审计管理 – 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
  • 国际化 – 已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
  • RESTful API – RESTful API 提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
  • 部署简单 – 提供在线和离线两种安装工具,也可以安装到vSphere平台(OVA方式)虚拟设备。

Harbor基于Docker Registry做了增强,添加了很多企业级管理需要的能力,使原来能力较弱的Docker Registry更适合于生产环境中使用。

Harbor整体架构:

20170810165828

Harbor在架构上主要由五个组件构成:

  • Proxy:Harbor的registry, UI, token等服务,通过一个前置的反向代理统一接收浏览器、Docker客户端的请求,并将请求转发给后端不同的服务。
  • Registry: 负责储存Docker镜像,并处理dockerpush/pull 命令。由于我们要对用户进行访问控制,即不同用户对Docker image有不同的读写权限,Registry会指向一个token服务,强制用户的每次docker pull/push请求都要携带一个合法的token,Registry会通过公钥对token 进行解密验证。
  • Core services: 这是Harbor的核心功能,主要提供以下服务:UI:提供图形化界面,帮助用户管理registry上的镜像(image), 并对用户进行授权。 webhook:为了及时获取registry上image状态变化的情况, 在Registry上配置webhook,把状态变化传递给UI模块。token服务:负责根据用户权限给每个docker push/pull命令签发token.Docker客户端向Regiøstry服务发起的请求,如果不包含token,会被重定向到这里,获得token后再重新向Registry进行请求。
  • Database:为coreservices提供数据库服务,负责储存用户权限、审计日志、Docker image分组信息等数据。
  • Log collector:为了帮助监控Harbor运行,负责收集其他组件的log,供日后进行分析。

这几个Contianer 通过 Docker link 的形式连接在一起,在容器之间通过容器名字互相访问。对终端用户而言,只需要暴露 proxy(即Nginx)的服务端口即可。

Harbor认证流程:

20170810161227

  • 首先,请求被代理容器监听拦截,并跳转到指定的认证服务器。
  • 如果认证服务器配置了权限认证,则会返回401。通知dockerclient在特定的请求中需要带上一个合法的token。而认证的逻辑地址则指向架构图中的core services。
  • 当docker client接受到错误code。client就会发送认证请求(带有用户名和密码)到coreservices进行basic auth认证。
  • 当上面的请求发送给ngnix以后,ngnix会根据配置的认证地址将带有用户名和密码的请求发送到core serivces。
  • coreservices获取用户名和密码以后对用户信息进行认证(自己的数据库或者介入LDAP都可以)。成功以后,返回认证成功的信息。
  • 从上面的docker registry 和 Harbor的架构图、流程图可以看出Harbor的扩展部分为coreservices。这部分实现了用户的认证,添加了UI模块已经webhook。

Harbor的核心概念:

20170810165951

以上是Harbor的核心概念。一个项目可以看成一个用户的小私库,项目成员按照其角色,可以上传,下载,删除镜像,或添加删除成员等。系统管理员可以创建镜像库复制目标,为项目设置复制策略,可以从其它的镜像库复制镜像过来。复制策略会产生复制任务。项目下面可拥有多个镜像,而每个镜像则可以有多个镜像标签。项目包含日志。

Harbor的安全机制

企业中的软件研发团队往往划分为诸多角色,如项目经理、产品经理、测试、运维等。在实际的软件开发和运维过程中,这些角色对于镜像的使用需求是不一样的。从安全的角度,也是需要通过某种机制来进行权限控制的。

举例来说,开发人员显然需要拥有对镜像的读写(PULL/PUSH)权限以更新和改正代码;测试人员中需要读取(PULL)权限;而项目经理需要对上述的角色进行管理。

Harbor为这种需求提供了用户和成员两种管理概念。

在Harbor中,用户主要分为两类。一类为管理员,另一类为普通用户。两类用户都可以成为项目的成员。而管理员可以对用户进行管理。

成员是对应于项目的概念,分为三类:管理员、开发者、访客。

管理员可以对开发者和访客作权限的配置和管理。

测试和运维人员可以访客身份读取项目镜像,或者公共镜像库中的文件。
从项目的角度出发,显然项目管理员拥有最大的项目权限,如果要对用户进行禁用或限权等,可以通过修改用户在项目中的成员角色来实现,甚至将用户移除出这个项目。

20170810184342

Harbor的镜像同步

为什么需要镜像同步

由于对镜像的访问是一个核心的容器概念,在实际使用过程中,一个镜像库可能是不够用的,下例情况下,我们可能会需要部署多个镜像仓库:

  • 国外的公有镜像下载过慢,需要一个中转仓库进行加速
  • 容器规模较大,一个镜像仓库不堪重负
  • 对系统稳定性要求高,需要多个仓库保证高可用性
  • 镜像仓库有多级规划,下级仓库依赖上级仓库

更常用的场景是,在企业级软件环境中,会在软件开发的不同阶段存在不同的镜像仓库,

  • 在开发环境库,开发人员频繁修改镜像,一旦代码完成,生成稳定的镜像即需要同步到测试环境。
  • 在测试环境库,测试人员对镜像是只读操作,测试完成后,将镜像同步到预上线环境库。
  • 在预上线环境库,运维人员对镜像也是只读操作,一旦运行正常,即将镜像同步到生产环境库。
  • 在这个流程中,各环境的镜像库之间都需要镜像的同步和复制。
Harbor的镜像同步机制

有了多个镜像仓库,在多个仓库之间进行镜像同步马上就成为了一个普遍的需求。比较传统的镜像同步方式,有两种:

第一种方案,使用Linux提供的RSYNC服务来定义两个仓库之间的镜像数据同步。

第二种方案,对于使用IaaS服务进行镜像存储的场景,利用IaaS的配置工具来对镜像的同步进行配置。

这两种方案都依赖于仓库所在的存储环境,而需要采用不同的工具策略。Harbor则提供了更加灵活的方案来处理镜像的同步,其核心是三个概念:

用Harbor自己的API来进行镜像下载和传输,作到与底层存储环境解耦。

利用任务调度和监控机制进行复制任务的管理,保障复制任务的健壮性。在同步过程中,如果源镜像已删除,

Harbor会自动同步删除远端的镜像。在镜像同步复制的过程中,Harbor会监控整个复制过程,遇到网络等错误,会自动重试。

提供复制策略机制保证项目级的复制需求。在Harbor中,可以在项目中创建复制策略,来实现对镜像的同步。与Docker Registry的不同之处在于,Harbor的复制是推(PUSH)的策略,由源端发起,而Docker Registry的复制是拉(PULL)的策略,由目标端发起。

20170810184523

Harbor的多级部署

在实际的企业级生产运维场景,往往需要跨地域,跨层级进行镜像的同步复制,比如集团企业从总部到省公司,由省公司再市公司的场景。

这一部署场景可简化如下图:

20170810184607

更复杂的部署场景如下图:

20170810184623

PS:以上内容转载自网络

环境准备:

系统版本:Centos7.3
docker版本:1.17.06
harbor版本:1.1.2
docker-cmopose版本:1.14.0
python版本:2.7.5
harbor server IP地址:192.168.162.54

一、安装docker

安装方法请参考之前文章:http://www.jiagoumi.com/work/1204.html

二、安装docker-compose

# curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# docker-compose –version
docker-compose version 1.14.0, build c7bdf9e
注意:
如果执行docker-compose –version命令后报如下错误:
Cannot open self /usr/local/bin/docker-compose or archive /usr/local/bin/docker-compose.pkg
解决办法:
可能是使用curl下载下来的文件是不完整导致,可以登录https://github.com/docker/compose/releases之间选择版本下载,例如我要安装docker-cmopose版本的版本为1.14.0,则我需要下载docker-compose-Linux-x86_64,替换原来的,如下:
# mv /usr/local/bin/docker-compose /usr/local/bin/docker-compose.bak
# mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
# du -sh  /usr/local/bin/docker-compose*
8.5M /usr/local/bin/docker-compose       —->新
2.2M /usr/local/bin/docker-compose.bak    —->旧
可以看到新的文件比原来的大很多,接着执行命令就正常了
# docker-compose –version
docker-compose version 1.14.0, build c7bdf9e

三、搭建Harbor服务

官方系统需求: On a Linux host: docker 1.10.0+ and docker-compose 1.6.0+ .
1、下载源代码:
网上很多文章采用git方式下载,但是如果你按照这种方式下载的话,解压后你再按照网上的文章安装的话,最终你是没办法正常访问harbor的页面的,坑很大!推荐下载源码的方式安装,如下图所示:
20170810131750
源码包下载地址:https://github.com/vmware/harbor/releases
选择下图中的包下载上传到服务器后解压。
20170811103512
# tar zxf harbor-offline-installer-v1.1.2.tgz
# mv harbor /opt/
2、修改harbor.cfg配置
harbor.cfg常用配置参数解释:
hostname: 配置目标主机的主机名, 被用来访问Harbor ui 和镜像仓库的,可以配置为ip地址和全域名,比如 192.168.1.10 or reg.yourdomain.com. 不要使用 localhost or 127.0.0.1 为主机名
ui_url_protocol: (http or https. 默认协议为 http) 该协议被用来访问 the UI and the token/notification 服务. 默认是 http. 想要设置https协议,请看链接 配置Harbor支持https协议.
Email settings: 配置Harbor来发送邮件,当然改配置并不是必须的 .注意:默认的ssl链接没有被启用,如果SMTP需要ssl支持,可以设置以下参数以支持。
email_ssl = true
  * email_server = smtp.mydomain.com
  * email_server_port = 25
  * email_username = sample_admin@mydomain.com
  * email_password = abc
  * email_from = admin <sample_admin@mydomain.com> 
  * email_ssl = false       
harbor_admin_password: 设置管理员内部密码,该密码紧紧在第一次启动Harbor的时候生效.在之后这个设置被忽略,管理员的密码将在UI中重新设置。 默认的用户名和密码如下: admin/Harbor12345 .
auth_mode: 被用来认证的方式,默认使用的是 db_auth,该认证会被肢解存储到数据库中。 如果需要设置LDAP方式认证需要使用ldap_auth.
ldap_url: LDAP认证方式的URL (e.g. ldaps://ldap.mydomain.com). 当 auth_mode 被设置为ldap_auth 的时候。
ldap_searchdn: 链接LDAP/AD服务的用户域(e.g. uid=admin,ou=people,dc=mydomain,dc=com).
ldap_search_pwd: 为上面设定的用户域设置密码 ldap_searchdn.
ldap_basedn: 基础域为方便寻找一个用户e.g. ou=people,dc=mydomain,dc=com. 仅当 auth_mode is 设置为ldap_auth的时候才使用
ldap_filter:用户搜索过滤 (objectClass=person).
ldap_uid: 该参数被用来匹配一个LDAP搜索的用户,可以使uid,cn,email或者其他的方式。 
ldap_scope: 用户搜索范围, 1-LDAP_SCOPE_BASE, 2-LDAP_SCOPE_ONELEVEL, 3-LDAP_SCOPE_SUBTREE. Default is 3.
db_password: mysql数据库root用户密码 db_auth.
self_registration: (on or off. Default is on) 启用和关闭用户注册功能.当被关闭,新用户职能通过admin用户去创建。 _注意: 当 auth_mode 被设置为 ldap_auth, self-registration 会被一直关闭,该参数也会被忽略。
use_compressed_js: (on or off. 默认为 on) 生产中使用,建议将该参数设置为 on. 在部署模式中将参数设置为off 以至于js 文件能够被分开去修改.
max_job_workers: (默认为 3) 设置在任务服务中最大的工作副本, 每一个image副本任务,会有一个worker从仓库中将所有的tag同步到远端。增大这个值回允许更多当前的副本任务,然而因为每个worker都会去消耗一定的网络/cpu/io等资源,必须根据系统的资源进行合理设置该值。
secretkey_path: 默认是/data,其下的secretkey文件存储值为加解密在副本策略中远端仓库的密码,长度为16位字符。生产中必需修改该值. NOTE: After changing this key, previously encrypted password of a policy can not be decrypted.
token_expiration: token过期时间,默认30分钟
verify_remote_cert: (on or off. 默认 on) 该参数决定了当harbor盒远端的registry实例交互的时候是否使用SSL/TLS .设置为off 的时候,一般远端的registry会采用自签名或者未受信任的证书。
customize_crt: (on or off. 默认为on) 当设置为on的时候,会使用脚本去创建私钥和root证书去认证registry的toke
以下参数:
crt_country,
crt_state,
crt_location, 
crt_organization, 
crt_organizationalunit, 
crt_commonname, 
crt_email 
被用来省城key。设置为off的时候,key和root证书可以被应用在外部的源中。
以上信息引用自:https://my.oschina.net/xxbAndy/blog/786712
根据以上参数介绍,结合自己的环境可自行修改,当然你也可以在搭建完成后,通过web页面修改这些参数,一般线上环境建议使用域名方式访问,同时将默认密码更改。此处我先只更改以下一个参数:
# vim /opt/harbor/harbor.cfg
hostname = 192.168.162.54
3.更改docker配置,重启docker服务:
注意:因为harbor配置中默认使用http连接,而docker默认采用https方式连接,所以如果上面的配置文件中你采用默认参数“ui_url_protocol = http ”,Docker认为是不安全的,push镜像会报错,还需要修改docker配置,而关于harbor如何采用https方式连接,本文不做讨论。(其实,如果是公司内部自己使用,个人觉得没必要设置https方式)
# vim /usr/lib/systemd/system/docker.service  #添加–insecure-registry=ip地址
ExecStart=/usr/bin/dockerd –insecure-registry=192.168.162.54
# systemctl daemon-reload && systemctl restart docker
4、修改Harbor的Docker镜像存放路径
默认情况下,Harbor是把镜像存储在本地文件系统中的,存储在/data/registry目录下,映射到docker容器里面的/storage目录下。但是有时候我们想把镜像存储在本地空间较大的硬盘上,这时候就需要修改配置文件,这个参数是在/opt/harbor/docker-compose.yml文件中指定的,需要在执行install.sh脚本运行之前修改,例如我修改为/opt/data/registry目录(ps:无需提前创建此目录),操作如下图:
# cp /opt/harbor/docker-compose.yml{,.bak}
# vim /opt/harbor/docker-compose.yml
20170809151000
5.执行安装脚本并启动harbor服务:
# cd /opt/harbor/
# ./install.sh
✔ ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at http://192.168.162.54. 
For more details, please visit https://github.com/vmware/harbor .

输出如上信息代表启动正常,此时会启动几个Contianer,如下图:

20170810134601
之后如果想停止或启动harbor的话,可以使用如下命令:
停止:
# docker-compose stop
启动:
# docker-compose start
6、访问harbor界面
在浏览器访问栏直接输入该harbor.cfg中配置的hostname参数即可,默认用户密码是:admin/Harbor12345,如下图所示
 20170810133828

四、验证使用Harbor

 1、从docker hub上下载hello-world镜像
# docker run hello-world
2、给镜像打标签,名称格式(registryAddress[:端口]/项目/imageName[:tag],其中library是harbor默认提供的项目
# docker tag hello-world 192.168.162.54/library/hello-world
3、登录镜像私服
# docker login -u admin -p ‘Harbor12345′ 192.168.162.54
4、上传镜像
# docker push 192.168.162.54/library/hello-world
5、web登录验证
在浏览器上访问192.168.162.54,登录完成后,点击library这个项目,即可看到上传的hello-world,如下图
20170810155618

至此基于http访问方式的harbor服务搭建完毕!

 来源: http://www.jiagoumi.com/work/1221.html


快乐成长 每天进步一点点