Harbor介绍
Harbor是VMware开源的一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution;作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全;提升用户使用Registry构建和运行环境传输镜像的效率。
首先了解Harbor各组件的作用
架构图
各组件作用
- Proxy
是一个nginx前端代理,提供API路由功能,Harbor的组件(例如核心,注册表,Web门户和令牌服务等)都位于此反向代理之后,代理将来自浏览器和Docker客户端的请求转发到各种后端服务。
- Core
Harbor的核心功能,主要提供以下服务:
认证与授权
Config Management
项目管理
配额管理
标签保留
图表服务
内容信任
镜像复制
扫描管理
Webhook
- Job Service
一种通用执行队列服务,允许其他组件/服务通过简单的静态API同时提交运行异步任务的请求
- Registry
第三方注册表服务器,负责存储Docker镜像并处理Docker推/拉命令,由于Harbor需要强制执行对镜像的访问控制,因此注册表将引导客户端使用令牌服务,以便为每个请求请求提供有效的令牌。
存储
- 键值存储Redis
提供数据缓存功能并支持作业服务的临时持久化作业元数据。
- 数据库PostgreSQL:
存储Harbor的相关元数据,例如项目,用户,角色,复制策略,标签保留策略,扫描仪,图表和镜像。
从应用市场安装
Harbor已经发布到了好雨公有应用市场,可以从应用市场一键安装:
本次应用市场发布的Harbor版本为1.9.4
等待一段时间,Harbor就部署在了Rainbond集群中了,部署完成后需要修改一些配置
- registry组件
在环境配置
–>配置文件设置
中挂载了一份配置文件,需要将PROXY_DOMAIN
部分更改为proxy组件的对外访问域名
,修改完成之后更新并重启组件。
- core组件
在环境配置中找到EXT_ENDPOINT
这个变量,将变量值设置为proxy
组件的对外访问地址,如果为http协议需要添加端口:80
更新core组件,稍等一段时间就可以访问了
- proxy组件
在环境配置
–>配置文件设置
删除挂载路径为/etc/nginx/nginx.conf
的配置文件, 更新proxy组件。
- 应用网关调整
Rainbond应用网关rbd-gateway生成的域名中nginx的配置client_max_body_size
的值默认为1M,在上传较大镜像时会出现报错,所以需要调整该值,在UI控制台调整即可
左侧导航栏打开应用网关
–>访问控制
,找到proxy组件的域名,进行编辑,将上传限制值设置为0,不做任何限制,更改完毕直接点击确定即刻生效。
客户端使用Harbor
默认使用http协议
docker 从docker 仓库中推送或获取镜像都是默认走https协议。
启动完成后,可以直接访问组件proxy的对外访问
地址访问harbor的ui界面,使用的是80端口;
默认账号为admin
,密码为Harbor12345
。
使用Harbor上传下载镜像
harbor支持http和https,但如果使用http的话,在拉取镜像的时候,会抛出仓库不受信任的异常。需要在所有的docker客户端的docker配置文件/etc/docker/daemon.json中添加如下配置:
{
"insecure-registries": [
"80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80"#修改为自己的域名+端口
]
}
- 重启docker服务
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
- 命令行登录
docker login http://80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80
- 推拉镜像
docker pull nginx
docker tag nginx 80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/library/nginx:latest
docker push 80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/library/nginx:latest
- 在ui界面查看镜像是否push成功
配置https协议使用harbor
前提条件
需要有一个自己的域名,和其对应的ssl证书,这里以www.insteate.cn
域名为例。
使用阿里云签发ssl证书文档请参阅: Rainbond应用域名绑定ssl证书,使用https协议
- 首先更改网关上传限制,设置值为0,不限制
- registry组件
在环境配置
–>配置文件设置
中挂载了一份配置文件,需要将PROXY_DOMAIN
部分更改为绑定的https域名,修改完成之后更新并重启组件。
- core组件
在环境配置中找到 EXT_ENDPOINT
这个变量,将值设置为访问域名,更新组件
- proxy组件
在环境配置
–>配置文件设置
添加配置文件,挂载到/etc/nginx/nginx.conf
目录, 如下图所示,配置文件内容复制下方代码块内容即可,更新proxy组件。
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;
tcp_nodelay on;
keepalive_timeout 65;
# this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1;
upstream core {
server 127.0.0.1:8080;
}
upstream portal {
server 127.0.0.1:8081;
}
log_format timed_combined '$remote_addr - '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
access_log /dev/stdout timed_combined;
server {
listen 80;
server_tokens off;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# Add extra headers
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'";
# costumized location config file can place to /etc/nginx/etc with prefix harbor.http. and suffix .conf
include /etc/nginx/conf.d/harbor.http.*.conf;
location / {
proxy_pass http://portal/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /c/ {
proxy_pass http://core/c/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /api/ {
proxy_pass http://core/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /chartrepo/ {
proxy_pass http://core/chartrepo/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /v1/ {
return 404;
}
location /v2/ {
proxy_pass http://core/v2/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto https;
proxy_buffering off;
proxy_request_buffering off;
}
location /service/ {
proxy_pass http://core/service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /service/notifications {
return 404;
}
}
}
到此完成https的配置,可直接在命令行登录并推拉镜像了
Harbor应用制作
项目地址: https://gitee.com/Aaron-23/harbor
Harbor官方推荐的部署方式是使用docker-compose部署,这样导致一个问题是在rainbond部署时多组件端口之间的冲突,为了解决这个问题,在部署时将harbor各组件的端口进行了调整,调整方式为更改组件配置文件,各组件端口如下所示:
组件 | 端口 |
---|---|
proxy | 80 |
core | 8080 |
portal | 8081 |
registryctl | 8083 |
jobservices | 8084 |
registry | 5000 |
redis | 6379 |
PostgreSQL | 5432 |
通过官方的docker-compose文件了解了所有组件的依赖关系及配置后开始部署
- PostgreSQL部署
使用官方的postgresql镜像做了进一步处理,可以自动初始化Harbor所需要的数据库。
部署的方式使用了基于 Dockerfile 的源码构建,项目地址:https://gitee.com/Aaron-23/harbor.git,db目录下
关键Dockerfile部分解析:
FROM postgres:9.6.15-alpine
MAINTAINER zhangz@goodrain.com
ENV TZ Aisa/Shanghai
ENV LANG en_US.utf8
VOLUME /var/lib/postgresql/data
COPY ./docker-healthcheck.sh /docker-healthcheck.sh
# 下面的步骤,会将初始化数据用的sql脚本放置在指定目录下
COPY ./initial-notaryserver.sql /docker-entrypoint-initdb.d/
COPY ./initial-notarysigner.sql /docker-entrypoint-initdb.d/
COPY ./initial-registry.sql /docker-entrypoint-initdb.d/
ENV POSTGRESQL_HOST=127.0.0.1 POSTGRESQL_PORT=5432 POSTGRESQL_USERNAME=postgres POSTGRESQL_PASSWORD=root123 POSTGRESQL_DATABASE=registry POSTGRESQL_SSLMODE=disable
RUN chown -R postgres:postgres /docker-entrypoint.sh /docker-healthcheck.sh /docker-entrypoint-initdb.d \
&& chmod u+x /docker-entrypoint.sh /docker-healthcheck.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
HEALTHCHECK CMD ["/docker-healthcheck.sh"]
EXPOSE 5432
CMD ["postgres"]
自动初始化的原理参见:https://hub.docker.com/_/postgres 中的 Initialization scripts
部分,这样做的好处是,基于此镜像的容器在首次启动时,不需要其他操作,就会自动执行sql脚本完成初始化。对于Rainbond部署而言,在将这样的数据库作为应用的一部分发布到应用市场后,执行一键安装可以达到即安即用的效果。
- proxy
它是一个nginx
反向代理,代理Notary client(镜像认证)、Docker client(镜像上传下载等)和浏览器的访问请求(Core Service)给后端的各服务;在这里对nginx的配置文件做了一些修改,将后端代理的core
组件portal
组件的连接地址更改为127.0.0.1
,这样做的原因是因为proxy
组件依赖了core
及portal
服务,他在连接后端服务时会通过代理连接,代理的连接地址为127.0.0.1
。
upstream core {
server 127.0.0.1:8080;
}
upstream portal {
server 127.0.0.1:8081;
}
- registry部署
使用harbor
官方的registry
镜像作为基础镜像,修改了配置文件,特别需要注意的是auth:token
模块,这里定义的仓库认证的方式及地址,地址必须填写proxy
组件对外访问的地址,存储镜像的目录为/storage
,这里将其持久化出来。
- core部署
core
使用harbor
官方的core镜像作为基础镜像,环境变量EXT_ENDPOINT
所定义的值是在UI界面快速复制pull命令时的值,所以需要手动修改,在配置文件中更改了默认的端口号为8080
appname = Harbor
runmode = dev
enablegzip = true
[dev]
httpport = 8080
EnableXSRF = true
XSRFKey = vwdR0JchXoOHwAkM7f9wDLAWsAwhKfqOW74rPR3F
XSRFExpire = 3600
- jobservice
jobservice 是 harbor中用来处理 job 的组件,负责镜像复制工作的,依赖core
,postgresql
,redis
三个组件,连接地址及相关配置都在config.yaml文件中定义
- redis部署
直接使用harbor官方的redis镜像,未作修改
问题汇总
我在测试时创建了nginx的项目,将镜像tag修改为80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/nginx:1.16
,导致push时失败,报如下错误
[root@ docker]#: docker push 80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/nginx:1.16
The push refers to repository [80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/nginx]
37ec257a56ed: Retrying in 1 second
567538016328: Retrying in 1 second
488dfecc21b1: Retrying in 1 second
received unexpected HTTP status: 500 Internal Server Error
查阅资料得知是镜像目录不符合要求:必须是两级目录以上才可以, 如 80.grf9b616.iyl0r2oh.0196bd.grapps.cn:80/nginx/nginx:1.16
更多harbor使用请参阅用户指南
Harbor概述
Harbor官方网站
GitHub项目地址