harbor镜像仓库原理和安装

 源地址:harbor镜像仓库原理和安装

目录

------------------------------------------------------------------------

 
一:Harbor简介
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器。
Harbor和Registry都是Docker的镜像仓库,但是Harbor作为更多企业的选择,是因为相比较于Regisrty来说,它具有很多的优势。
 
1. docker registry的缺点:
  • 缺少认证机制,任何人都可以随意拉取及上传镜像,安全性缺失
  • 缺乏镜像清理机制,镜像可以push却不能删除,日积月累,占用空间会越来越大
  • 缺乏相应的扩展机制
 
2. Harbor优点
a.提供分层传输机制,优化网络传输
Docker镜像是是分层的,而如果每次传输都使用全量文件(所以用FTP的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层的UUID为标识,确定传输的对象。
b.提供WEB界面,优化用户体验
只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
c.支持水平扩展集群
当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
d.良好的安全机制
企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。
e.Harbor提供了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制。
kubernetes中通过namespace来对资源进行隔离,在企业级应用场景中,通过将两者进行结合可以有效将kubernetes使用的镜像资源进行管理和访问控制,增强镜像使用的安全性。尤其是在多租户场景下,可以通过租户、namespace和项目相结合的方式来实现对多租户镜像资源的管理和访问控制。
 
3. Harbor介绍
镜像的存储harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。harbor在docker distribution的基础上增加了一些安全、访问控制、管理的功能以满足企业对于镜像仓库的需求。harbor以docker-compose的规范形式组织各个组件,并通过docker-compose工具进行启停。
docker的registry是用本地存储或者s3都是可以的,harbor的功能是在此之上提供用户权限管理、镜像复制等功能,提高使用的registry的效率。Harbor的镜像拷贝功能是通过docker registry的API去拷贝,这种做法屏蔽了繁琐的底层文件操作、不仅可以利用现有docker registry功能不必重复造轮子,而且可以解决冲突和一致性的问题。
Harbor官方网站:http://vmware.github.io/harbor/
Harbor源码地址:https://github.com/vmware/harbor/
 
 
二:Harbor主要组件
Proxy:对应启动组件nginx。它是一个nginx反向代理,代理Notary client(镜像认证)、Docker client(镜像上传下载等)和浏览器的访问请求(CoreService)给后端的各服务;
UI(Core Service):对应启动组件harbor-ui。底层数据存储使用mysql数据库,主要提供了四个子功能:
  • UI:一个web管理页面ui;
  • API:Harbor暴露的API服务;
  • Auth:用户认证服务,decode后的token中的用户信息在这里进行认证;auth后端可以接db、ldap、uaa三种认证实现;
  • Token服务(上图中未体现):负责根据用户在每个project中的role来为每一个docker push/pull命令issuing一个token,如果从docker client发送给 registry的请求没有带token,registry会重定向请求到token服务创建token。
Registry:对应启动组件registry。负责存储镜像文件,和处理镜像的pull/push命令。Harbor对镜像进行强制的访问控制,Registry会将客户端的每个pull、push请求转发到token服务来获取有效的token。
Admin Service:对应启动组件harbor-adminserver。是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候需要加载adminserver的配置;
Job Sevice:对应启动组件harbor-jobservice。负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log;
Log Collector:对应启动组件harbor-log。日志汇总组件,通过docker的log-driver把日志汇总到一起;
Volnerability Scanning:对应启动组件clair。负责镜像扫描
Notary:对应启动组件notary。负责镜像认证
DB:对应启动组件harbor-db,负责存储project、 user、 role、replication、image_scan、access等的metadata数据。
 
需要说明的是,harbor的每个组件都是以Docker容器的形式构建的,可以使用Docker Compose来进行部署,当然,如果你的环境中使用了kubernetes,harbor也提供了kubernetes的配置文件。
docker镜像:harbor-jobservice, nginx, harbor-core, redis, harbor-portal, harbor-db, registry, registryctl, harbor-log
harbor共有8个容器组成:
  • ui:harbor的核心服务。
  • log:运行着rsyslog的容器,进行日志收集。
  • mysql:由官方mysql镜像构成的数据库容器
  • nginx:使用Nginx做反向代理
  • registry:官方的Docker registry
  • adminserver:harbor的配置数据管理器
  • jobservice:Harbor的任务管理服务。
  • redis:用于存储session
 
 

-------------------

 
三:Harbor架构
 
1. Harbor登录过程
假设Harbor部署在IP为192.168.1.10的主机上。用户运行docker命令将登录请求发送到Harbor:
$ docker login 192.168.1.10
用户输入所需凭证后,Docker客户端向地址“192.168.1.10/v2/”发送HTTP GET请求。Harbor的不同容器将按照以下步骤进行处理:
(a)首先,该请求由监听端口80的代理容器接收。容器中的Nginx将请求转发到后端的registry容器。
(b)Registry容器已配置为基于令牌的身份验证,因此它返回错误代码401,通知Docker客户端从指定的URL获取有效的令牌。在Harbor,这个URL指向核心服务的令牌服务;
(c)Docker客户端收到此错误代码后,会根据HTTP规范的基本认证向令牌服务URL发送请求,将请求头部嵌入用户名和密码;
(d)通过端口80将该请求发送到代理容器后,Nginx会根据预先配置的规则再次将该请求转发给UI容器。UI容器内的令牌服务接收请求,解码请求并获取用户名和密码;
(e)获取用户名和密码后,令牌服务将检查数据库,并通过MySql数据库中的数据验证用户。当令牌服务配置为LDAP / AD身份验证时,它将对外部LDAP / AD服务器进行身份验证。认证成功后,令牌服务返回一个表示成功的HTTP代码。HTTP响应体包含由私钥生成的令牌。
 
2. Docker push 的过程
(我们省略了代理转发步骤,上图显示了Docker推送过程中不同组件之间的通信)
用户成功登录后,Docker Image将通过Docker Push命令发送到Harbor:
# docker push 192.168.1.10/library/hello-world
(a)首先,码头客户端通过向注册表发送请求重复类似登录的过程,然后取回令牌服务的URL;
(b)随后,当接触令牌服务时,Docker客户端提供附加信息以在image(library/ hello-world)上应用推送操作的令牌;
(c)收到Nginx转发的请求后,令牌服务查询数据库查询用户的角色和权限,以推送image。如果用户具有适当的权限,则对Push操作的信息进行编码,并用私钥对其进行签名,并向Docker客户端生成一个令牌;
(d)在Docker客户端获取令牌之后,它向包含令牌的头部向Registry发送推送请求。一旦Registry接收到请求,它将使用公钥解码令牌并验证其内容。公钥对应于令牌服务的私钥。如果Registry找到令牌有效推送Image,则Image传输过程开始。
 
 
 
四:harbor镜像仓库部署
1. 安装harbor环境
系统版本: centos7.6
确认docker 和 docker-compose版本号(docker和docker-compose安装
[root@harbor harbor]# docker version
Client: Docker Engine - Community
 Version:           18.09.7
Server: Docker Engine - Community
  Version:          18.09.7
[root@harbor harbor]# docker-compose --version
docker-compose version 1.24.1, build 4667896
 
2. 安装harobr镜像仓库
github官网地址 https://github.com/goharbor/harbor/releases
[root@harbor ~]#  wget https://github.com/goharbor/harbor/releases/download/v1.9.3/harbor-offline-installer-v1.9.3.tgz
[root@harbor ~]# tar -zxvf harbor-offline-installer-v1.9.1.tgz 
[root@harbor ~]# cd harbor/
[root@harbor harbor]# ls
harbor.v1.9.1.tar.gz  harbor.yml  install.sh  LICENSE  prepare
[root@harbor harbor]# ls keys/   #自己制作证书的位置
ikan.key  ikan.pem
 
 
3.修改主机名,开启https认证并安装
不需要添加域名,到时候nginx直接转发过来即可,和主机名同时支持
数据默认放置在data_volume: /data下,日志在/var/lib/harbor下
[root@harbor harbor]# vim harbor.yml #修改以下这些地方
hostname: harbor1.ikan.com
https:
  port: 443
  certificate: /root/harbor/keys/ikan.pem
  private_key: /root/harbor/keys/ikan.key

[root@harbor harbor]# ./prepare 
prepare base dir is set to /root/harbor
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
loaded secret from file: /secret/keys/secretkey
Generated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crt
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir
[root@harbor harbor]# ./install.sh 
 
[Step 0]: checking installation environment ...
 
Note: docker version: 19.03.2
 
Note: docker-compose version: 1.24.1
 
[Step 1]: loading Harbor images ...
cad87ea2da29: Loading layer [==================================================>]  77.02MB/77.02MB
 
安装完成后,它会提示你访问harbor的地址是多少,你就可以直接在浏览器中访问这个地址了。
  • 停止服务: docker-compose stop
  • 开始服务: docker-compose start
 
五:Harbor使用
1. 通过界面登陆harbor
https://harbor1.ikan.com ,开启https后默认只走这个
 
默认用户名和密码 admin Harbor12345
 
2. 创建镜像项目kubernetes
路径:项目 -> 新建项目 -> 项目名称 kubernetes -> 确认
 
3. 测试harbor仓库可用性
[root@harbor2 ~]# docker login harbor1.ikan.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
 
Login Succeeded
[root@harbor2 ~]# # 登陆成功后,token会存放在 ~/.docker/config.json.文件里
 
[root@harbor2 ~]# docker tag busybox harbor.ikan.com/kubernetes/busybox:v0.3
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.3
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Layer already exists 
v0.3: digest: sha256:24fd20af232ca4ab5efbf1aeae7510252e2b60b15e9a78947467340607cd2ea2 size: 527
 
 
报错1:镜像直接上传到harbor正常,但是通过nginx一直显示超时:
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.3
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Retrying in 10 seconds 
解决:需要修改安装包里面Nginx配置文件,删掉scheme的那几行,在反向代理的配置上如果有写的话
 
报错2: 在拉取镜像的时候,会抛出仓库不受信任的异常。
解决:需要在所有的docker客户端的docker配置文件/etc/docker/daemon.json中添加如下配置:
{ "insecure-registries": ["https://harbor1.ikan.com"], }
 
 
六:harbor镜像仓库高可用
高可用方案有两种:
1. 双主复制
所谓的双主复制其实就是复用主从同步实现两个harbor节点之间的双向同步,来保证数据的一致性,然后在两台harbor前端顶一个负载均衡器将进来的请求分流到不同的实例中去,只要有一个实例中有了新的镜像,就是自动的同步复制到另外的的实例中去,这样实现了负载均衡,也避免了单点故障,在一定程度上实现了Harbor的高可用性:
这个方案有一个问题就是有可能两个Harbor实例中的数据不一致。假设如果一个实例A挂掉了,这个时候有新的镜像进来,那么新的镜像就会在另外一个实例B中,后面即使恢复了挂掉的A实例,Harbor实例B也不会自动去同步镜像,这样只能手动的先关掉Harbor实例B的复制策略,然后再开启复制策略,才能让实例B数据同步,让两个实例的数据一致。
在实际生产使用中,主从复制有时候会出现报错。
 
2. 多harbor实例共享后端存储,
共享后端存储算是一种比较标准的方案,就是多个Harbor实例共享同一个后端存储,包括数据库,redis和本地存储数据;任何一个实例持久化到存储的镜像,都可被其他实例中读取。通过前置LB进来的请求,可以分流到不同的实例中去处理,这样就实现了负载均衡,也避免了单点故障:
 
这个方案在实际生产环境中部署需要考虑三个问题:
    1. 共享存储的选取,Harbor的后端存储目前支持AWS S3、Openstack Swift, Ceph等,在我们的实验环境里,就直接使用nfs
    2. Session在不同的实例上共享,这个现在其实已经不是问题了,在最新的harbor中,默认session会存放在redis中,我们只需要将redis独立出来即可。可以通过redis sentinel或者redis cluster等方式来保证redis的可用性。在我们的实验环境里,仍然使用单台redis
    3. Harbor多实例数据库问题,这个也只需要将harbor中的数据库拆出来独立部署即可。让多实例共用一个外部数据库,数据库的高可用也可以通过数据库的高可用方案保证。
 
目前,Harbor官方并未给出具体的高可用部署方案,用户需要根据自己的情况来设计合适的高可用方案并完成部署。主从同步高可用方案,只是一种简单的实现。
 
0.1 已经有了另一台镜像仓库harbor2
1. 创建用户
 
2. 项目中添加用户
 
3. 仓库管理中添加目标
  1. 选择系统管理中的仓库管理,点击“新建目标”,如下图
  2. 输入对应信息。
    1. 目标名和描述随意,
    2. 目录URL为另一台地址,如果为https协议,则证书需要安全。(制作免费的https证书.note
    3. Access ID和Access Secret为有同步权限的账号即可
  1. 点击“测试链接”,显示“测试链接成功”,则表示权限通过,点解“确认”添加即可
 
4. 添加复制规则
  1. 在系统管理的复制管理里,点击“新建规则”,如下图
  2. 添加规则信息
    1. 名称和描述随意
    2. 选择复制模式:Push-based 从本地仓库推送到远程仓库,Pull-based 拉去镜像到本地仓库
    3. 镜像过滤规则,包括包含名称,标签等
    4. 选择远程镜像仓库和命名空间
    5. 选择触发模式,分为手动/定时/事件,镜像是否强制覆盖,是否启动规则等
 
5. 测试harbor仓库可用性
这时你推送镜像到镜像仓库harbor1,则在镜像仓库harbor2上也能看到
[root@harbor2 ~]# docker tag busybox harbor.ikan.com/kubernetes/busybox:v0.4
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.4
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Layer already exists 
v0.3: digest: sha256:24fd20af232ca4ab5efbf1aeae7510252e2b60b15e9a78947467340607cd2ea2 size: 527
 
镜像自动化删除
默认情况下,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;
 
 
问题:registry https://192.168.70.120 is unhealthy: unhealthy
解决:证书自签名,不被信任。
 
posted @ 2019-12-21 14:24  会跑的蚂蚁  阅读(5789)  评论(0编辑  收藏  举报