3.3 harbor
生成式 AI 说,Harbor 是一个企业级的 Docker 镜像仓库管理工具,它提供了以下主要功能:
- 镜像托管与分发
- 支持 Docker 和 OCI 标准的镜像格式存储和分发
- 提供安全的镜像存储和传输,包括 HTTPS 和 Token 认证等
- 镜像生命周期管理
- 支持镜像的自动扫描和漏洞修复
- 提供基于角色的访问控制(RBAC)和审计功能
- 支持镜像复制和镜像垃圾回收等高级管理功能
- 多租户和项目管理
- 支持创建多个项目,每个项目拥有独立的镜像仓库
- 支持基于项目的权限管理,实现细粒度的访问控制
- 高可用和可扩展性
- 支持集群部署,可通过负载均衡实现高可用
- 支持 HA 数据库、对象存储等各个组件的水平扩展
- 集成与扩展
- 提供 API 接口,可与 CI/CD 系统等外部系统集成
- 支持插件扩展,可集成云服务商的认证系统等
不过简单来讲,它是一套工具集,核心的功能是基于 registry 和 chartmuseum 封装出的支持多用户的私有镜像仓库和 Helm Chart 仓库,我们可以使用使用它代替 DockerHub,构建一个完全离线的镜像仓库~前提是有稳定的 S3 存储、PostgresSQL 数据库和 Redis 缓存。
我维护过的 Harbor 最多存储了 260 多万个容器镜像,占用接近 30TB 的 S3 存储, 缓存镜像 layer 数据的 Redis 内存占用超过 50G,且 PostgreSQL 数据库并没有做什么调优,代价是偶发 5xx 错误,加载镜像列表缓慢,就这样的前提下,经过一些调整还撑了一年多时间,只能说,Harbor 确实是一个优秀的开源软件。
每个容器从业者都应该有一个自己的镜像仓库,这里简单讲下如何在 K3s 中部署 Harbor。
Harbor 的组件数量较多,而且配置有些复杂,最简单的办法是使用 Helm 部署,然后再调优或者手动升级,我们希望使用已有的 S3 存储、Postgres 数据库,并使用 ingressroute 暴露服务,在部署前需要做一些准备工作:
- 在 Minio 中创建一个 harbor 专用的 bucket、accesskey、secretkey
- 在 Postgres 中创建一个 harbor 专用账号,以及三个数据库:coreDatabase、notaryServerDatabase、notarySignerDatabase
Redis 使用 Harbor 的 Helm Chart 自带配置部署,因为 Harbor 会固定占用 Redis 的 0~5 号数据库,这里就不和公共的 Redis 混杂在一起了。
接下来添加 Harbor 的 Helm Repo 并下载 Chart,这里使用的是 1.9.3 版本的 Chart(对应 2.5.3 版本的 Harbor):
helm repo add harbor https://helm.goharbor.io
helm repo update
helm fetch harbor/harbor --untar --version 1.9.3
进入 harbor 目录可以看到以下文件:
➜ harbor ls -lh
total 252K
drwxr-xr-x 2 root root 4.0K Aug 14 15:05 cert
-rw-r--r-- 1 root root 566 Aug 14 15:05 Chart.yaml
drwxr-xr-x 2 root root 4.0K Aug 14 15:05 conf
-rw-r--r-- 1 root root 12K Aug 14 15:05 LICENSE
-rw-r--r-- 1 root root 189K Aug 14 15:05 README.md
drwxr-xr-x 16 root root 4.0K Aug 14 15:05 templates
-rw-r--r-- 1 root root 32K Aug 14 15:05 values.yaml
编辑 values.yaml,执行以下修改:
- 配置 expose,选择 clusterIP 的方式暴露服务并设置 tls 的 enabled 为 false,这样就会创建一个 harbor 的 service,指向 nginx 的 80 端口,这个 nginx 会将请求自动分流到 harbor-core、harbor-portal、harbor-chartmuseum 等
- 配置 externalURL,设置需要暴露到外网的域名
- 设置 imageChartStorage 的类型为 s3,这样 Helm Chart 以及容器镜像都会存储到 Minio,注意 region 默认为 us-east-1
- 设置 database 的类型为 external,填写 harbor 专用的账号及数据库名
- 关闭不常用的服务:trivy、notary 和 trace,如果需要接入 Prometheus 监控 Harbor,可以启用 metrics 组件。
修改完成后,在 harbor 目录下执行命令安装,这里使用 harbor 命名空间:
helm -n harbor install harbor .
安装完成后,如果修改了 values.yaml,可以执行以下命令更新:
helm -n harbor upgrade harbor .
部署完成后,在 ingressroute 中添加一个 Rule 暴露 harbor 命名空间下的 harbor 服务即可。
Harbor 的功能十分丰富,这里讲一下常用的几种。
镜像托管
Harbor 使用项目管理容器镜像与 Helm Chart,授权也是以项目维度执行的,我们可以创建一个机器人账户专用于拉取和推送镜像。
镜像代理
创建项目时如果勾选镜像代理,可以就可以提供类似 docker registry 的 pull through cache 功能,比如创建了一个 proxy 项目代理 DockerHub,假设当前 Harbor 域名为 image.wbuntu.com,如需拉取容器镜像 wbuntu/gost:v2.11.5,执行以下命令即可:
docker pull image.wbuntu.com/proxy/wbuntu/gost:v2.11.5
镜像复制
Harbor 支持从其他镜像仓库 Pull 镜像以及将本地镜像 Push 到其他镜像仓库,可以使用镜像名、Tag、标签、资源类型匹配,下面是从 DockerHub 同步 alpine:3.18 镜像的配置:
在按照 1.9.3 版本做完记录后,我尝试部署 1.15.0 版本,目前看区别如下:
- helm 版本要求大于 3.10.0
- 审查服务只保留 trivy,数据库只需创建一个 coreDatabase
这次保留了原始的 values.yaml,使用 diff 看一下修改部分,内容不多:
➜ harbor diff values.yaml values.yaml.backup
4c4
< type: clusterIP
---
> type: ingress
11c11
< enabled: false
---
> enabled: true
112c112
< externalURL: https://image.wbuntu.com
---
> externalURL: https://core.harbor.domain
194c194
< type: s3
---
> type: filesystem
218,222c218,222
< region: us-east-1
< bucket: harbor
< accesskey: xxxxxx
< secretkey: xxxxxx
< regionendpoint: https://xxxxxx
---
> region: us-west-1
> bucket: bucketname
> #accesskey: awsaccesskey
> #secretkey: awssecretkey
> #regionendpoint: http://myobjects.local
886c886
< type: external
---
> type: internal
936c936
< host: "postgres.storage"
---
> host: "192.168.0.1"
938,940c938,940
< username: "xxxxxx"
< password: "xxxxxx"
< coreDatabase: "xxxxxx"
---
> username: "user"
> password: "password"
> coreDatabase: "registry"