Docker 搭建可视化私有仓库——Harbor

Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

Harbor 核心组件解释

  • Proxy:他是一个nginx的前端代理,代理Harbor的registry,UI, token等服务。
  • db:负责储存用户权限、审计日志、Dockerimage分组信息等数据。
  • UI:提供图形化界面,帮助用户管理registry上的镜像, 并对用户进行授权。
  • jobsevice:jobsevice是负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log。
  • Adminserver:是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候回需要加载adminserver的配置。
  • Registry:镜像仓库,负责存储镜像文件。
  • Log:为了帮助监控Harbor运行,负责收集其他组件的log,供日后进行分析。

Harbor 和 Registry 的比较

Harbor 和 Registry 都是 Docker 的镜像仓库,但是 Harbor 作为更多企业的选择,是因为相比较于 Regisrty 来说,它具有很多的优势。

  • 提供分层传输机制,优化网络传输——Docker 镜像是是分层的,而如果每次传输都使用全量文件(所以用 FTP 的方式并不适合),显然不经济。必须提供识别分层传输的机制,以层 的 UUID 为标识,确定传输的对象。
  • 提供 WEB 界面,优化用户体验——只用镜像的名字来进行上传下载显然很不方便,需要有一个用户界面可以支持登陆、搜索功能,包括区分公有、私有镜像。
  • 支持水平扩展集群——当有用户对镜像的上传下载操作集中在某服务器,需要对相应的访问压力作分解。
  • 良好的安全机制——企业中的开发团队有很多不同的职位,对于不同的职位人员,分配不同的权限,具有更好的安全性。
  • Harbor 提供了基于角色的访问控制机制,并通过项目来对镜像进行组织和访问权限的控制。kubernetes 中通过 namespace 来对资源进行隔离,在企业级应用场景中,通过将两者进行结合可以有效将 kubernetes 使用的镜像资源进行管理和访问控制,增强镜像使用的安全性。尤其是在多租户场景下,可以通过租户、namespace 和项目相结合的方式来实现对多租户镜像资源的管理和访问控制。

Harbor 部署

在部署 Harbor 之前,需要先安装好 docker-compose。关于 docker-compose 安装部分请自行 Google。

下载 Harbor 离线包

安装有两种方式,off-line(离线) 和 on-line(在线),离线安装需要下载的安装包较大,在线安装下载的安装包很小,请根据自己的情况选择,本文基于 harbor-offline-installer-v1.8.0、docker package to 17.06.0+。

curl -O -k https://soft.ryana.cn/%E5%85%B6%E4%BB%96/Harbor/harbor-offline-installer-v1.8.0.tgz

修改 harbor.yml

按实际情况修改 hostnameport 及其他选项。

# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
# 访问地址,可以使用ip、域名,不可以设置为127.0.0.1或localhost
hostname: reg.mydomain.com

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
# 端口号,请根据情况修改,防火墙也要放开相应端口
  port: 80

# 如果使用https请修改该配置
# https related config
# https:
#   # https port for harbor, default is 443
#   port: 443
#   # The path of cert and key files for nginx
#   certificate: /your/certificate/path
#   private_key: /your/private/key/path

# 如果要使用外部代理,请修改该配置,(适用于要使用宿主机的nginx等其他代理)
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433

  
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
# 启动Harbor后,管理员UI登录的密码,默认是Harbor12345
harbor_admin_password: Harbor12345

# Harbor DB configuration
database:
  # The password for the root user of Harbor DB. Change this before any production use.
# 数据库密码,默认root123
  password: root123

# The default data volume
# 镜像默认存储位置
data_volume: /data
...
...
...

修改后保存,执行 ./prepare,更新一下配置文件,再执行 ./install.sh,开始安装并启动。

到此便安装完成了,直接打开浏览器登陆即可,默认用户密码是:admin/Harbor12345。

1420b2b07852e2d2ba3358795b11a123

Harbor 使用

1420b2b07852e2d2ba3358795b11a123

在 Harbor 仓库中,任何镜像在被 push 到 regsitry 之前都必须有一个自己所属的项目。这里有两种仓库的形式:

  • 公共:任何使用者都可以获取这个仓库中的镜像。
  • 私有:只有被授予权限的用户可以获取这个仓库中的镜像。

当你登陆进入 Harbor 后,你可以新建一个项目,这里你可以选择在公开前面打钩来进行公共项目创建,如果不打钩,则默认为私有项目,当项目设为公开后,任何人都有此项目下镜像的读权限。命令行用户不需要 docker login 就可以拉取此项目下的镜像。如下图:

33a07ac35182c1f28edd85c435b7f2bf

在项目创建完毕后,你可以浏览这个项目的镜像仓库,成员,复制,标签,日志,配置管理,如下图:

33a07ac35182c1f28edd85c435b7f2bf

功能:

  • 日志,可以查看到当前项目所有的日志信息。
  • 高级检索,可以根据时间段,操作动作来匹配日志。
  • 添加不同的角色的成员在项目中,但是成员必须是在 Harbor 上注册过的用户,这里可以选择项目管理员,开发人员,游客。
  • 镜像复制,用来复制仓库从一个 Harbor 实例到另一个。
  • 标签管理。

上传下载镜像

登录

注: 在登陆时要求采用 https 协议,因为 docker 从 1.3.X 之后,与 docker registry 交互默认使用的是 https,而 harbor 默认使用 http 连接,如果不是走的 https 协议,则需要修改 docker 配置增加参数默认使用 http 访问,详见附

# 登陆
# docker login -u admin -p Harbor12345 115.47.124.247:8088
[root@test harbor]# docker login 115.47.124.247:8088
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
# 下载busybox镜像,做测试用
[root@test harbor]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
53071b97a884: Pull complete 
Digest: sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d
Status: Downloaded newer image for busybox:latest
# 给镜像打tag
[root@cn-bj harbor]# docker tag busybox 115.47.124.247:8088/test/busybox:latest
[root@test harbor]# docker images
REPOSITORY                         TAG                        IMAGE ID            CREATED             SIZE
busybox                            latest                     64f5d945efcc        13 days ago         1.2MB
115.47.124.247:8088/test/busybox   latest                     64f5d945efcc        13 days ago         1.2MB
# push镜像到仓库
[root@test harbor]# docker push 115.47.124.247:8088/test/busybox
The push refers to repository [115.47.124.247:8088/test/busybox]
d1156b98822d: Pushed 
latest: digest: sha256:4fe8827f51a5e11bb83afa8227cbccb402df840d32c6b633b7ad079bc8144100 size: 527
[root@test harbor]# 

上传完毕后,登录 Web Harbor,选择项目,项目名称 test ,就可以查看刚才上传的 busybox 镜像了。

1420b2b07852e2d2ba3358795b11a123

创建用户并分配权限

我们刚一直是用 admin 操作,实际应用中我们使用每个人自己的账户登录。所以就需要新建用户,同时为了让用户有权限操作已经创建的项目,还必须将该用户添加到该项目成员中。

我们来创建一个普通用户,例:test,(系统管理-> 用户管理-> 创建用户)。

a43ba8743373523ecf4dab92228f20ab

然后就可以使用 test 账户本地模拟操作 pull 刚上传的 busybox 镜像。

修改 docker 配置文件

适用 docker 版本 1.13 及以下

vi /usr/lib/systemd/system/docker.service

找到 ExecStart,在该行最后新增 --insecure-registry 115.47.124.247:5000

ExecStart=/usr/bin/dockerd  --insecure-registry 115.47.124.247:8088

重启 docker,生效。

systemctl daemon-reload
systemctl restart docker

适用 docker-ce 版本 1.17 及以上

修改 /etc/docker/daemon.json

echo '{ "insecure-registries":["115.47.124.247:8088"] }' > /etc/docker/daemon.json
# 确认
cat /etc/docker/daemon.json

重启 docker,生效。

systemctl daemon-reload
systemctl restart docker

可能遇到的问题

502 Bad Gateway

在登陆仓库的时候遇到 502 Bad Gateway。这是时候用 docker ps 检查服务,看 registry (运行在5000端口) 这个服务是否挂了,重启该服务即可。

[root@test harbor]# docker login 115.47.124.247:8088
Username: admin
Password: 
Error response from daemon: login attempt to http://115.47.124.247:8088/v2/ failed with status: 502 Bad Gateway

blob upload unknown

docker 通过代理上传 https 协议的私服地址报错 unknown blob。检查 nginx 配置文件中是否有 proxy_set_header HOST $HOST; 去掉就可以了,原因 HOST 会把当前访问的 host 带到 harbor 启动 nginx 镜像,导致了这个问题(不一定对)。

proxy_set_header HOST $HOST;
[root@test home]# docker push reg.mydomain.com/test/busybox
The push refers to repository [reg.mydomain.com/test/busybox]
d1156b98822d: Pushing [==================================================>]  1.199MB/1.199MB
blob upload unknown

error parsing HTTP 413

可能是因为镜像过于庞大,需要在nginx 配置中设置上传大小。

client_max_body_size 2048M;
error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>413 Request Entity Too Large</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>413 Request Entity Too Large</h1></center>\r\n<hr><center>nginx/1.14.1</center>\r\n</body>\r\n</html>\r\n"
[root@c1c3f57be06144920921ac61dcc3ee3cc-node1 home]# docker push reg.mydomain.com/test/busybox

Docker 搭建私有仓库

Docker hub 是用于管理公共镜像的仓库,跟代码库托管到 GitHub 是一个道理。在一些场景下,我们需要拥有一个私有的镜像仓库用于管理我们自己的镜像,本文就来介绍搭建私有 Docker 仓库。

运行

docker pull registry

参数解释:

  • -v /opt/registry:/var/lib/registry 表示将本地目录 /opt/registry 映射到仓库容器中的 /var/lib/registry 目录,该目录中存储仓库中的镜像文件。
docker run --name registry \
-p 5000:5000 \
-v /opt/registry:/var/lib/registry \
--restart=always \
-d registry

打开浏览器输入 http://127.0.0.1:5000/v2,返回 {} 说明 registry 运行正常。

测试

接下来我们就要操作把一个本地镜像 push 到搭建的私有仓库中。

# 下载 busybox 镜像
docker pull busybox
# 修改 busybox 镜像的 tag
docker tag busybox 115.47.124.247:5000/busybox
# 上传到私有仓库
docker push 115.47.124.247:5000/busybox

不过会 push 失败,因为 docker 从 1.3.X 之后,与 docker registry 交互默认使用的是 https,然而此处搭建的私有仓库只提供 http 服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动 docker server 时增加启动参数为默认使用 http 访问。

The push refers to a repository [115.47.124.247:5000/busybox]
Get https://115.47.124.247:5000/v1/_ping: http: server gave HTTP response to HTTPS client

修改 docker 启动配置文件

vi /usr/lib/systemd/system/docker.service

找到 ExecStart,在该行最后新增 --insecure-registry 115.47.124.247:5000

ExecStart=/usr/bin/dockerd  --insecure-registry 115.47.124.247:5000

重启 docker,即可生效

systemctl daemon-reload
systemctl restart docker

查看镜像

curl -XGET http://registry:5000/v2/_catalog

删除镜像

# name:镜像名称
# reference: 镜像对应sha256值
curl -I -X DELETE /v2/<name>/manifests/<reference>

# 例
curl -I -X DELETE http://115.47.124.247:5000/v2/busybox/manifests/sha256:897638d338e0a6b7e9d7fe77df840fb35ef6e225aa3eb185b5e3f7e565615ecf

上面搭建的 docker 私有仓库是命令行界面的,很丑陋。有个开源项目叫 harbor,是 在 docker registry 基础上带了个 web 界面,还支持冗余等,是个非常不错的项目,下篇将介绍搭建 harbor。

Nacos VS Eureka

什么是 Nacos ?

Nacos 是阿里巴巴推出来的一个新开源项目,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

三大主要功能

  • 任务发现与服务管理

    • 在采用以“服务 (Service)”为中心的诸如微服务及云原生方式的现代应用架构时,动态服务发现至关重要。 Nacos 同时支持基于 DNS 和基于 RPC(如 Dubbo/gRPC)的服务发现,并为您提供服务的实时的健康检查以防止将请求发送给不健康的主机,基于 Nacos 您也可以更方便的实现服务断路器。Nacos 提供的强大的服务的元数据管理,路由及流量管理策略也能够帮助您更好的构建更强壮的微服务平台。
  • 动态配置管理

    • 动态配置服务允许您在所有环境中以集中和动态的方式管理所有应用程序或服务的配置。动态配置消除了配置更新时重新部署应用程序和服务的需要。可以更方便的帮助您实现无状态服务,更轻松地实现按需弹性扩展服务实例。
  • 动态 DNS 服务

    • 支持权重路由的动态 DNS 服务使您可以更轻松地在数据中心内的生产环境中实施中间层负载平衡,灵活的路由策略,流量控制和简单的 DNS 解析服务,动态 DNS 服务也帮你更容易的实现以 DNS 协议为基础的服务发现,以消除耦合到厂商私有服务发现 API 上的风险。

基本架构及概念

nacos-Arch

  • 服务 (Service)

服务是指一个或一组软件功能(例如特定信息的检索或一组操作的执行),其目的是不同的客户端可以为不同的目的重用(例如通过跨进程的网络调用)。Nacos 支持主流的服务生态,如 Kubernetes Service、gRPC|Dubbo RPC Service 或者 Spring Cloud RESTful Service。

  • 服务注册中心 (Service Registry)

服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查 API 来验证它是否能够处理请求。

  • 服务元数据 (Service Metadata)

服务元数据是指包括服务端点(endpoints)、服务标签、服务版本号、服务实例权重、路由规则、安全策略等描述服务的数据

  • 配置管理 (Configuration Management)

在数据中心中,系统中所有配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动统称为配置管理。

等等... ...

Nacos 对比 Eureka

相对于 Spring Cloud Eureka 来说,Nacos 更强大。可以这么理解,Nacos = Spring Cloud Eureka + Spring Cloud Config。

  • 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。
  • 通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。

优缺点对比

Spring Cloud Nacos

  • 优点

    • 开箱即用,适用于dubbo,spring cloud等。
    • AP模型,数据最终一致性。
    • 注册中心,配置中心二合一(二合一也不一定是优点),提供控制台管理。
    • 纯国产,各种有中文文档,久经双十一考验。
  • 缺点

    • 刚刚开源不久,社区热度不够,依然存在bug。

Spring Cloud Eureka

  • 优点

    • Spring Cloud 官方推荐。
    • AP模型,数据最终一致性。
    • 开箱即用,具有控制台管理。
  • 缺点

    • 客户端注册服务上报所有信息,节点多的情况下,网络,服务端压力过大,且浪费内存。
    • 客户端更新服务信息通过简单的轮询机制,当服务数量巨大时,服务器压力过大。
    • 集群伸缩性不强,服务端集群通过广播式的复制,增加服务器压力。
    • Eureka2.0 闭源(Spring Cloud最新版本还是使用的1.X版本的Eureka)。

Null

有些事情注定要经历,

被耽搁的终究还要继续。

不忘初心!