简介
Harbor是VMware公司最近开源的企业级Docker Registry项目, 项目地址为https://github.com/vmware/harbor 其目标是帮助用户迅速搭建一个企业级的Docker registry服务。它以Docker公司开源的registry为基础,提供了管理UI, 基于角色的访问控制(Role Based Access Control),AD/LDAP集成、以及审计日志(Audit logging) 等企业用户需求的功能,同时还原生支持中文。Harbor的每个组件都是以Docker容器的形式构建的,使用Docker Compose来对它进行部署。用于部署Harbor的Docker Compose模板位于 /Deployer/docker-compose.yml,由5个容器组成:
Proxy: 由Nginx 服务器构成的反向代理。
Registry:由Docker官方的开源registry 镜像构成的容器实例。
UI: 即架构中的core services, 构成此容器的代码是Harbor项目的主体。
Mysql: 由官方MySql镜像构成的数据库容器。
Log: 运行着rsyslogd的容器,通过log-driver的形式收集其他容器的日志。
这几个容器通过Docker link的形式连接在一起,在容器之间通过容器名字互相访问。对终端用户而言,只需要暴露proxy (即Nginx)的服务端口。
快速部署方法
Harbor使用Docker-compose部署,后续所有的配置以及部署均在$HARBOR_HOME/Deploy/`目录下完成,因此若无特别说明,工作目录都在该目录下。
首先需要进行简单的配置,配置文件为harbor.cfg,配置项如下:
hostname:hostname为外部可访问的地址,即bind addr,通常设置为本地公有IP,若内部使用DNS,可设置为主机名。
auth_mode:Harbor支持两种认证方式,默认为本地存储,即账号信息存储在mysql下,本文先使用本地存储方式,另外一种认证方式LDAP将在后续章节单独介绍。
设置完毕后,配置文件为:
hostname = 42.62.x.x
ui_url_protocol = http
##The password of Harbor admin, change this before any production use. harbor_admin_password= admin
##By default the auth mode is db_auth, i.e. the credentials are stored in a local database. #Set it to ldap_auth if you want to verify a user’s credentials against an LDAP server. auth_mode = ldap_auth
#The password for the root user of mysql db, change this before any production use. db_password = root123
#Switch for self-registration feature
self_registration = on
运行./prepare脚本更新配置。完成配置后,就可以使用docker-compose快速部署harbor:
docker-compose up -d
安装完成后,访问Web UI,地址:http://bind_addr,即配置的hostname地址,端口为80。如图:
使用harbor
使用harbor
Web UI
安装完成后,打开Web UI,点击登录,默认账户admin/Harbor12345,登录成功后进入项目管理界面:
管理界面用户可以点击“我的项目”进行项目管理,比如新建项目、用户以及权限管理等。点击项目名称,进入该项目下的镜像管理界面,可以查看、检索镜像
docker client
以上是UI界面的使用,接下来介绍如何使用docker client进行镜像的管理,由于harbor只支持Registry V2 API,因此Docker client版本必须>= 1.6.0。
由于我们配置认证服务使用的是http,Docker认为是不安全的,要使用我们部署的镜像仓库,需要配置本地docker,修改配置文件(/etc/default/docker)为:
DOCKER_OPTS=”$DOCKER_OPTS –insecure-registry 42.62.x.x”
其中42.62.x.x是我们部署Harbor的地址,即hostname配置项值。配置完后需要重启docker服务。
验证能否登录:
docker login 42.62.x.x
# docker login -u admin -p Harbor12345 -e test@gmail.com 42.62.x.x
登录成功后显示如下:
登录成功接下来我们上传一个镜像,以ubuntu镜像为例,首先从docker hub拉取ubuntu镜像:
docker pull ubuntu:14.04
然后为该镜像打上新的标签,标签格式为:Harbor地址/项目名/镜像名称:镜像标签,如
42.62.x.x/library/ubuntu:14.04:
docker tag ubuntu:14.04 42.62.x.x/library/ubuntu:14.04
push我们的镜像到harbor仓库中:
docker push ubuntu:14.04 42.62.x.x/library/ubuntu:14.04
push镜像
push成功后,我们就可以从harbor仓库中使用docker pull拉取我们的镜像了,注意如果是私有项目,必须先使用docker login登录:
docker pull 42.62.x.x/library/ubuntu:14.04
使用harbor作为mirror registry
Mirror Registry简介
Mirror是Docker Registry的一种特殊类型,它起到了类似代理服务器的缓存角色,在用户和Docker Hub之间做Image的缓存。 官方定义为:
Such a registry is provided by a third-party hosting infrastructure but is targeted at their customers only. Some mechanism ensures that public images are pulled from a sponsor registry to the mirror registry, to make sure that the customers of the third-party provider can docker pull those images locally.
其基本工作原理是,当用户pull一个镜像时,若镜像在mirror 服务器存在,则直接从mirror服务器拉取,否则若不存在该镜像,则由mirror server自动代理往dockerhub(可配置)中拉取镜像,并缓存到mirror服务器中,当客户再次拉取这个镜像时,直接从mirror server中拉取,不需要再次从dockerhub中拉取。
注意Mirror跟Private Registry有本质区别,参考DaoCloud宣布Docker Hub Mirror服务永久免费 :
Private Registry是开发者或者企业自建的Image存储库,通常用来保存企业内部的Docker Image,用于内部开发流程和产品的发布、版本控制。Mirror是一种代理中转服务,我们提供的Mirror服务,直接对接Docker Hub的官方Registry,Docker Hub上有数以十万计的各类Docker Image。在使用Private Registry时,需要在Docker Pull,或Dockerfile中直接键入Private Registry的地址,通常这样会导致跟Private Registry的绑定,缺少灵活性。
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
我们在运行./prepare之前修改config/registry/config.yml文件,追加以下配置:
proxy:
remoteurl: https://registry-1.docker.io
如果需要访问私有仓库,需要填写dockerhub的用户名和密码:
proxy:
remoteurl: https://registry-1.docker.io
username: [username]
password: [password]
然后重新启动harbor服务:
# 注意不要执行./prepare,否则会覆盖修改的配置
docker-compose stop
docker-compose rm -f
docker-compose up -d
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
除了设置harbor(或者registry),还需要配置本地docker服务,指定–registry-mirror参数,修改docker配置文件(/etc/default/docker):
DOCKER_OPTS=”$DOCKER_OPTS –registry-mirror=http://42.62.x.x –insecure-registry 42.62.x.x”
注意替换42.62.x.x为你的registry地址。
注意:修改了docker配置文件,必须重启docker服务才能生效。
harbor由于引进了认证功能,因此push操作时,必须保证project存在,比如push krystism/ffmpeg,必须保证harbor创建了krystism project,否则会失败。为了能够正常push/pull dockerhub的官方镜像,务必创建library project,如图:
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
2.架构介绍
1) 主要组件
Harbor在架构上主要由6个组件构成:
· Proxy:Harbor的registry, UI, token等服务,通过一个前置的反向代理统一接收浏览器、Docker客户端的请求,并将请求转发给后端不同的服务。
· Registry: 负责储存Docker镜像,并处理docker push/pull 命令。由于我们要对用户进行访问控制,即不同用户对Docker image有不同的读写权限,Registry会指向一个token服务,强制用户的每次docker pull/push请求都要携带一个合法的token, Registry会通过公钥对token 进行解密验证。
· Core services: 这是Harbor的核心功能,主要提供以下服务:
o UI:提供图形化界面,帮助用户管理registry上的镜像(image), 并对用户进行授权。
o webhook:为了及时获取registry 上image状态变化的情况, 在Registry上配置webhook,把状态变化传递给UI模块。
o token 服务:负责根据用户权限给每个docker push/pull命令签发token. Docker 客户端向Regiøstry服务发起的请求,如果不包含token,会被重定向到这里,获得token后再重新向Registry进行请求。
· Database:为core services提供数据库服务,负责储存用户权限、审计日志、Docker image分组信息等数据。
Job Services:提供镜像远程复制功能,可以把本地镜像同步到其他Harbor实例中。
· Log collector:为了帮助监控Harbor运行,负责收集其他组件的log,供日后进行分析。
各个组件之间的关系如下图所示:
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
2) 实现
Harbor的每个组件都是以Docker 容器的形式构建的,因此很自然地,我们使用Docker Compose来对它进行部署。
在源代码中(https://github.com/vmware/harbor), 用于部署Harbor的Docker Compose 模板位于 /Deployer/docker-compose.yml. 打开这个模板文件,会发现Harbor由5个容器组成:
· proxy: 由Nginx 服务器构成的反向代理。
· registry:由Docker官方的开源registry 镜像构成的容器实例。
· ui: 即架构中的core services, 构成此容器的代码是Harbor项目的主体。
· mysql: 由官方MySql镜像构成的数据库容器。
job services: 通过状态机机制实现远程镜像复制功能,包括镜像删除也可以同步到远端Harbor实例。
· log: 运行着rsyslogd的容器,通过log-driver的形式收集其他容器的日志。
这几个容器通过Docker link的形式连接在一起,这样,在容器之间可以通过容器名字互相访问。对终端用户而言,只需要暴露proxy (即Nginx)的服务端口。
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
-
docker login
假设我们将Harbor部署在IP 为192.168.1.10的虚机上。用户通过docker login命令向这个Harbor服务发起登录请求:
# docker login 192.168.1.10
当用户输入所需信息并点击回车后,Docker 客户端会向地址 “192.168.1.10/v2/” 发出HTTP GET请求。 Harbor的各个容器会通过以下步骤处理:
(a) 首先,这个请求会由监听80端口的proxy容器接收到。根据预先设置的匹配规则, 容器中的Nginx会将请求转发给后端的registry 容器;
(b) 在registry容器一方,由于配置了基于token的认证,registry会返回错误代码401,提示Docker客户端访问token服务绑定的URL。在Harbor中,这个URL指向Core Services;
(c) Docker 客户端在接到这个错误代码后,会向token服务的URL发出请求,并根据HTTP协议的Basic Authentication规范,将用户名密码组合并编码,放在请求头部(header);
(d)类似地,这个请求通过80端口发到proxy容器后,Nginx会根据规则把请求转发给ui容器,ui容器监听token服务网址的处理程序接收到请求后,会将请求头解码,得到用户名、密码;
(e) 在得到用户名、密码后,ui容器中的代码会查询数据库,将用户名、密码与mysql容器中的数据进行比对(注:ui 容器还支持LDAP的认证方式,在那种情况下ui会试图和外部LDAP服务进行通信并校验用户名/密码)。比对成功,ui容器会返回表示成功的状态码, 并用密钥生成token,放在响应体中返回给Docker 客户端。
这个过程中组件间的交互过程如下图所示:
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
至此,一次docker login 成功地完成了,Docker客户端会把步骤(c)中编码后的用户名密码保存在本地的隐藏文件中。
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
至此,一次docker login 成功地完成了,Docker客户端会把步骤 (c) 中编码后的用户名密码保存在本地的隐藏文件中。
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.
2. docker push
用户登录成功后用docker push命令向Harbor 推送一个Docker image:
# docker push 192.168.1.10/library/hello-world
(a) 首先,docker 客户端会重复login的过程,首先发送请求到registry,之后得到token 服务的地址;
(b) 之后,Docker 客户端在访问ui容器上的token服务时会提供额外信息,指明它要申请一个对image library/hello-world进行push操作的token;
(c) token 服务在经过Nginx转发得到这个请求后,会访问数据库核实当前用户是否有权限对该image进行push。如果有权限,它会把image的信息以及push动作进行编码,并用私钥签名,生成token返回给Docker客户端;
(d) 得到token之后 Docker客户端会把token放在请求头部,向registry发出请求,试图开始推送image。 Registry 收到请求后会用公钥解码token并进行核对,一切成功后,image的传输就开始了。
我们省去proxy转发的步骤,下图描述了这个过程中各组件的通信过程:
4.参考材料
原理如图:mirror原理图Harbor目前不支持pull cache功能,已提交issue #120。不过我们只需要手动修改下配置即可完成,具体配置可参考官方Registry as a pull through cache.