手里如果只跑着三五台机器,用 Docker Hub 或者阿里云镜像加速器就够了,但一旦服务器多起来、镜像有私有化要求,公共仓库的分发效率和安全性就有点绷不住。我自己的环境里,从最开始用 Docker Registry 裸跑,到后来换成 Harbor,中间踩了不少坑,也整理出一套相对顺畅的搭建流程。这篇文章就把这套流程完整写出来,从为什么选 Harbor、怎么部署、怎么配客户端,到日常运维里那些容易翻车的细节,一次性讲透。
1. 整体设计思路:为什么是 Docker + Harbor
1.1 私有镜像仓库到底解决了什么问题
先说个最简单的场景:你有一台 4 核 8G 的服务器,上面跑了 Nginx、MySQL、Redis、业务后端这些容器。假设每台新机器都要从 Docker Hub 拉镜像,网速好的时候还好,赶上 Docker Hub 抽风或者被限流,几百 MB 的镜像能拉半小时,服务器一多,时间全浪费在拉镜像上了。
再往下想一层:公司内部开发的镜像,带着业务代码和配置,直接丢到公共仓库显然不合适,先不说泄不泄露,光是在公网上拉取的速度和稳定性就没法保证。私有镜像仓库的核心作用,就是把这些镜像存到内网自己的服务器上,服务器之间通过内网拉取,速度快、不受外网影响,同时能控制访问权限,保证镜像内容可控。
Docker 官方有自己的私有仓库方案 Docker Registry,能用,但功能太过基础。没有 UI 界面、没有权限管理、没有镜像复制功能,多团队用起来全靠命令行和运维手工控制。Harbor 则是基于 Docker Registry 包装出来的完整企业级平台,UI、权限、复制、审计、回收这些能力都是开箱即用。对于大部分技术团队来说,Harbor 是比裸 Registry 更合适的选择。
1.2 Harbor 的核心组件与架构逻辑
Harbor 虽然是打包成一套 Docker 服务来运行的,但内部组件并不简单。梳理一下它的组成,对后面排查问题会有很大帮助:
- nginx:所有外部请求的统一入口,负责反向代理、TLS 终结、转发到对应服务。
- harbor-core:核心业务逻辑层,负责项目管理、用户权限、镜像复制、配额计算等。
- harbor-registry:真正存储镜像的 Docker Registry,负责 blob 和镜像层的存取。
- harbor-jobservice:异步任务处理服务,主要处理镜像复制、垃圾回收这些后台任务。
- harbor-portal:Web UI 前端页面。
- redis:缓存层,给 Core 和 JobService 提供缓存支持。
- harbor-db:PostgreSQL 数据库,存用户、项目、权限、镜像元数据等信息。
- harbor-log:集中日志收集,方便排查问题。
理解了这些组件的分工,你在排查故障时就能快速定位问题大概出在哪一层。比如 UI 能打开但登录异常,先怀疑 Core 和 DB;再比如推送镜像时报证书错误,十有八九是 nginx 层的 TLS 配置问题。
Harbor 对外提供服务时有两种部署方式:一种是单机 Docker Compose 模式,适合中小团队;一种是带高可用的 Kubernetes 部署模式,适合大规模生产环境。绝大多数团队的起步场景都是单机部署,这台机器既做存储也做服务,等规模大了再考虑把 registry 存储挂到 NFS 或者对象存储上,做多副本。
2. 环境准备与基础依赖安装
2.1 服务器硬件和系统要求
Harbor 对硬件的要求不算高,官方推荐最低 2 核 4G。但我实际使用的感受是,如果镜像量比较大,垃圾回收任务跑起来会比较吃 CPU,内存 4G 也只是刚好够跑。我建议至少 4 核 8G,磁盘空间按镜像增长速度预留,正常迭代频率的话,100GB 到 200GB 起步比较保险,而且建议数据目录单独挂一块数据盘,别跟系统盘放在一起。
系统方面,CentOS 7.9 和 Ubuntu 20.04/22.04 是网上使用量最大的两个环境。Harbor 官方提供了离线安装包,里面包含所有镜像文件,不需要在安装时再从外网拉取,这正是它在内网环境能顺利安装的关键。下面以 CentOS 7.9 为例,Ubuntu 操作逻辑基本一致,只是个别命令稍有差异。
2.2 Docker 安装与验证
Harbor 本身是容器化部署的,前提条件就是先把 Docker 装好。CentOS 7 上建议直接用阿里云镜像源安装:
# 卸载系统自带的旧版组件 sudo yum remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine # 安装必要依赖 sudo yum install -y yum-utils # 配置阿里云 docker-ce 源 sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装 docker-ce sudo yum install -y docker-ce docker-ce-cli containerd.io # 启动并设置开机自启 sudo systemctl start docker sudo systemctl enable docker # 验证 docker version装完之后有件事顺手做了:配置 Docker 的数据目录。Docker 默认数据目录在/var/lib/docker,如果系统盘空间不大,建议迁移到数据盘上。改/etc/docker/daemon.json:
{ "data-root": "/data/docker", "registry-mirrors": ["https://docker.m.daocloud.io"] }改完重启 Docker:
sudo systemctl restart docker这一步不做,等到镜像多起来再迁移就麻烦了,容器和数据迁移的成本比现在改一行配置高得多。
还有一点,如果你所在的网络环境拉取镜像非常慢,这里配置 registry-mirrors 用的公共镜像加速地址可能在后续某个时间失效,到时候重新换一个可用的地址即可。这个文件里面同时把>sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose docker-compose version
如果没有外网下载条件,可以提前在有网机器上下载好这个二进制文件传到服务器。接下来部署 Harbor。
3. Harbor 部署实操
3.1 下载安装包并解压
Harbor 官方在 GitHub 的 releases 页面提供两个类型的安装包:在线版(online)和离线版(offline),其实都有点误导,不是安装时是否联网的区分,而是离线包里预先打包好了全部 Harbor 组件的镜像文件,安装时不依赖外网。内网环境直接选 offline 版本最稳妥。
我这里用的版本是 v2.9.0,下载地址是 GitHub Releases 页面。下载命令大概是这样的:
cd /opt wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz tar -zxvf harbor-offline-installer-v2.9.0.tgz cd harbor解压之后,目录下会有一个harbor.yml.tmpl模板文件,真正干活之前要先把它复制成harbor.yml再修改。
3.2 修改 harbor.yml 配置文件
配置文件是 Harbor 安装的灵魂,里面很多参数一旦设错,后面踩的坑会非常深。先说最核心的几项:
hostname: 192.168.209.133 http: port: 80 https: port: 443 certificate: /data/cert/server.crt private_key: /data/cert/server.key harbor_admin_password: Harbor12345 database: password: root123 data_volume: /data/harbor log: level: info clair: updaters_interval: 0 trivy: ignore_unfixed: false skip_update: false offline_scan: false jobservice: max_job_workers: 10 chart: absolute_url: disabled注意事项:
hostname是访问地址,不能写成localhost或127.0.0.1,要填实际能被其他机器访问到的 IP 或域名。这里有个很容易忽略的问题,如果后面想用域名并配 Let's Encrypt 证书,这个字段就填域名。- 默认模板开启了 https,如果没有现成证书,建议先把 https 相关配置注释掉,使用 http 模式完成第一轮部署。后面需要 https 再补证书,不会影响已有数据。网上很多部署教程默认不注释 https,然后安装报错,就是因为没配证书文件。
harbor_admin_password是管理员初始密码,默认是 Harbor12345,首次登录后要立刻改掉。data_volume是 Harbor 的数据存储目录,建议单独放到数据盘,比如/data/harbor。database是 Harbor 内部 PostgreSQL 的密码,虽然不是外部访问的强需求,但设个复杂点的密码没坏处。
在首次安装之前,如果打算用 HTTPS,就要先准备证书。没有正式的域名证书时,可以自签自用,但客户端需要额外配置信任。我的建议是第一轮先用 HTTP 跑通流程,把推送拉取这些操作都调通之后,再根据需求上 HTTPS。
3.3 执行安装脚本
配置改好之后,运行安装脚本:
sudo ./install.sh安装脚本做的事情主要有三步:
- 检查 Docker 和 Docker Compose 是否可用。
- 加载离线包里的 Harbor 镜像。
- 根据
harbor.yml生成 docker-compose.yml 并启动所有服务。
看到终端输出类似这样的信息,说明安装成功:
[Step 4]: starting Harbor ... [Step 5]: Harbor started successfully.接着验证服务状态:
docker-compose ps正常会看到 nginx、harbor-core、harbor-registry、harbor-db 等一组容器都是 Up 状态。这时候在浏览器里访问http://192.168.209.133,用admin和配置的密码登录,就能看到 Harbor 的 Web 界面了。
3.4 Harbor UI 界面基础配置
首次登录后第一件事,建议先到“系统管理 → 用户管理”里建一个普通用户,日常操作别用 admin。然后“项目”里创建项目,项目是镜像分组和权限控制的基本单位。创建项目时有两个关键选项:
- 访问级别:选“私有”还是“公开”。私有项目需要登录且有对应权限才能拉取镜像;公开项目匿名也能拉取。内部环境看情况,通常选私有更稳妥。
- 存储配额:可以限制项目最大存储量,比如给一个项目限 50GB,防止某个团队把仓库磁盘塞爆。
这些配置逻辑非常直白,重点是在搭建完成后顺手做了,别等项目多起来再回头补。
4. 客户端 Docker 配置与镜像推送
4.1 配置 Docker 信任 HTTP 仓库地址
Harbor 刚装好的时候,如果你用的是 HTTP 模式,默认 Docker Daemon 是不允许往非 HTTPS 的 registry 推送镜像的,会直接报http: server gave HTTP response to HTTPS client的错误。解决方法是把目标地址加到 Docker 的insecure-registries里。
修改/etc/docker/daemon.json:
{ "insecure-registries": ["192.168.209.133"] }这里写的是 IP,如果用了域名,就填域名。如果有多个仓库地址,可以写成数组:
{ "insecure-registries": ["192.168.209.133", "registry.internal.example.com"] }改完重启 Docker:
sudo systemctl restart docker注意:重启 Docker 会重启所有容器。如果是生产机器,尽量挑业务低峰期操作,或者分批次处理。我在一次重启 Docker 后,大意了,业务容器因为重启策略是
always自动起来了,但没起来之前中断了一小段服务,这种细节在多人共用服务器时要格外重视。
4.2 登录 Harbor 并打标签推送
配置好信任之后,用 docker login 登录:
docker login 192.168.209.133输入用户名和密码,看到Login Succeeded即成功。接着给本地镜像打标签,标签格式是仓库地址/项目名/镜像名:标签:
docker tag nginx:latest 192.168.209.133/library/nginx:1.24推送:
docker push 192.168.209.133/library/nginx:1.24第一次推送因为是全量上传,速度取决于网络和内网带宽。之后同样的镜像层不会再传,增量推送非常快。
再验证一下拉取:
docker pull 192.168.209.133/library/nginx:1.24到这里,Docker + Harbor 的核心流程就走通了。从其他机器拉取镜像时,同样要先配置/etc/docker/daemon.json的insecure-registries并重启 Docker。
4.3 给镜像打标签时的常见错误
打标签时经常有人把格式搞错,比如写成了仓库地址:项目名/镜像名这种不存在的结构,或者漏掉端口号。Harbor 默认监听 80 端口时,HTTP 模式不需要写端口,但如果配置了其他端口,就必须写完整。例如:
docker tag myapp:latest 192.168.209.133:8080/project/myapp:latest这地方写错,push 的时候返回的报错信息可能让人一头雾水,比如显示 404 或者 project 不存在。提前理清地址格式能省很多事。
5. 常见问题与排查技巧实录
5.1 推送失败:dial tcp 192.168.209.133:443: connect: connection refused
网上这个报错出现的频率非常高,现象是docker push 192.168.209.133/project/image的时候报:
Get "https://192.168.209.133/v2/": dial tcp 192.168.209.133:443: connect: connection refused这里有个关键细节:报错信息里写的是https://,但你的 Harbor 只监听了 80 端口,没有监听 443。Docker 默认认为仓库地址是 HTTPS,因此先尝试 443 端口。解决方式就是把地址加入insecure-registries,让 Docker 放弃 HTTPS 而走 HTTP。
这个报错我在一开始搭 Harbor 时遇到最多,而且是新手最容易卡住的地方。本质原因就一句话:Docker 默认安全行为是只信任 HTTPS,你的仓库没有证书,所以额外声明允许 HTTP 访问。
类似的还有一个报错是连接超时dial tcp 192.168.209.133:443: i/o timeout,那就要检查网络通不通、防火墙有没有放行端口,或者 Harbor 容器本身是否还在运行。
5.2 登录失败:authorization failed或unauthorized
登录时报unauthorized: unauthorized to access repository,原因大多是用户名密码错误,或者这个用户没有目标项目的权限。注意 Harbor 里项目是独立的权限域,一个用户只登录了 Harbor 不代表能访问所有项目,还需要在项目的“成员”里把这个用户加进去,并赋予合适角色。
我实际开发中经常遇到的是:某同事自行注册了一个 Harbor 账号,但项目是私有的,他推镜像时收到 unauthorized,因为没人把它的账号加到项目成员里。只要在项目成员的界面里添加一下,问题立刻解决。
5.3 推送镜像时报413 Request Entity Too Large或连接中断
这种情况多见于镜像特别大、或者客户端和 Harbor 之间有 Nginx 反向代理时。如果客户端走的是公司网关或自己套了一层 Nginx,Nginx 默认的client_max_body_size 1m会直接拦截掉大镜像的推送请求。解决办法是在 Nginx 对应 location 配置里增加:
client_max_body_size 0;如果客户端直连 Harbor,没有经过额外代理,那就要检查 Harbor 所在服务器的磁盘空间,镜像推送过程中磁盘写满也会报类似错误,但报错信息通常不太明显,先排查磁盘是最快的。
5.4 垃圾回收不释放空间:镜像删了但存储没减少
这个和 Docker 的镜像分层机制有关,也是 Harbor 用户问得最多的运维问题之一。你在 UI 上删除了某个镜像,只是删除了镜像的元数据引用,底层 blob 仍然在磁盘上。要让磁盘空间真正释放,需要在 Harbor UI 的“系统管理 → 垃圾回收”里执行一次垃圾回收任务。
执行垃圾回收前,最好确认所有节点上没有容器引用这些镜像层,否则回收后容器启动会失败。实际操作中,如果某个镜像被正在运行的容器依赖,尽量不要并发去清理,先停掉相关容器再触发回收。
这里的经验是,垃圾回收任务频率不要太高,一般隔段时间手动执行一次,或者配合定时脚本调用 Harbor API 自动执行。Harbor 没有内置自动周期性回收,但它本身有 GC 排程设置,在 v2.x 版本里支持定时策略,默认是不开启的,建议在“系统管理 → 垃圾回收”里点击编排任务,设置每周跑一次。
5.5 客户端时间与服务器时间不一致导致认证异常
这是个冷门但真实踩过的坑。Harbor 登录和 JWT token 验证依赖时间窗口,客户端机器时间与 Harbor 服务器时间偏差过大时,登录可能正常,但推送时 token 校验失败,报authentication required或类似的 401/403 错误。
解决办法是把两边时间都用 NTP 同步到一致:
# 服务器端 sudo yum install -y ntpdate sudo ntpdate ntp.aliyun.com # 客户端类似操作,确保时间一致时间同步是基础环境问题,虽然不起眼,但真的遇到过几次,排查过程绕了一圈。写在这里给各位提个醒,部署环境阶段就把时间同步做掉,能避免很多莫名其妙的认证问题。
5.6 常见问题速查表
| 现象 | 大概率原因 | 解决动作 |
|---|---|---|
| push 时连接 443 被拒绝 | Docker 默认走 HTTPS,Harbor 没开 HTTPS | daemon.json 加 insecure-registries |
| login 成功但 push 报 unauthorized | 用户没有被加入项目成员 | 在项目成员里添加用户并授权 |
| 大镜像推送中断或超时 | 代理层限制了 body 大小 | Nginx location 设置 client_max_body_size 0 |
| 删了镜像但磁盘没变小 | 没执行垃圾回收 | UI 里执行 GC 任务 |
| pull 时证书过期或不受信任 | HTTPS 证书未被客户端信任 | 配置 insecure-registries 或用证书信任 |
| Harbor 容器起不来且报端口冲突 | 80/443 被占用 | 检查已占用进程,修改 harbor.yml 端口 |
6. 我这里推荐的 Harbor 日常运维与安全加固
6.1 数据备份策略
Harbor 的所有配置、用户信息、镜像元数据都存在 PostgreSQL 数据库里,镜像层本身在 data_volume 下。备份的思路分两块:
- 数据库备份:直接备份 Harbor 容器里的 PostgreSQL 数据,简单粗暴的方式是对 harbor-db 容器做卷备份,或者定期执行 pg_dump。
- 镜像数据备份:镜像数据量通常不小,直接用文件备份的方式复制 data_volume 通常成本较高,最简单的方案是 rsync 到另一台机器,或者用 Harbor 自带的“复制管理”功能把镜像复制到另一个仓库。
我的实践是:
- 每周对
/data/harbor/database做一次全量打包。 - 每天凌晨通过 rsync 把
/data/harbor下关键目录同步到备份服务器。 - 核心镜像的不可丢失性,优先放在另一个远端仓库做复制,单台机器坏掉也能从远端仓库恢复。
数据库和镜像数据要分开处理,数据库很轻,可以频繁备份;镜像数据很重,主要靠仓库复制来保障。
6.2 开启 HTTPS 并配置自签证书
如果公司没有内部 CA 或者正式域名证书,自签一个 HTTPS 证书给 Harbor 用也是常见做法:
mkdir -p /data/cert openssl req -newkey rsa:4096 -nodes -sha256 -x509 -days 365 \ -keyout /data/cert/server.key \ -out /data/cert/server.crt \ -subj "/CN=192.168.209.133"生成之后修改harbor.yml,把 https 部分的注释打开,填上证书路径,重新运行:
sudo ./install.shHarbor 安装脚本是幂等的,配置变了之后重新执行不会导致已有数据丢失。但客户端那边不能只是 restart docker,要把新证书加到系统信任列表里,或者继续依赖 insecure-registries。
说句实话,内网环境里 HTTPS 更多是为了防止链路劫持和误操作,真正大规模多团队使用时,HTTPS + 自建 CA 会让整个体验更规范顺手。但初期也可以先跑通 HTTP,等有正式证书了再平滑过渡。
6.3 镜像复制与多机房同步
Harbor 自带“复制管理”功能,可以把一个项目下的镜像自动复制到远端另一个 Harbor 或者标准的 Docker Registry。比如我在总部机房有一台 Harbor,分支机构机房有一台 Harbor,配置一个基于项目的复制规则,总部推送新镜像后,分支机构机器会自动从总部拉取。这个机制对分布式团队非常实用。
配置方式是在 UI 里的“系统管理 → 复制管理 → 新建规则”,填写目标仓库地址、访问凭证、复制模式(Push 或 Pull)、资源过滤器等。复制任务由 jobservice 负责,任务失败时有重试机制,也可以在界面上手动触发。
6.4 磁盘配额与清理策略
Harbor 2.x 支持配额管理,建议在项目创建时就设好限额。否则有些团队把几十 GB 的大镜像往仓库里塞,磁盘被写满之后所有镜像推送都失败,整个仓库不可用,这种事故我见过不止一次。设项目配额和容器启动时的资源限制是同一类习惯,越早做越好。
除了配额,镜像 tag 保留策略也很重要。Harbor 支持 tag 保留规则,比如只保留最近 30 天的 tag,或者保留最近 5 个版本。配置好之后配合垃圾回收定时执行,仓库体积就能控制在一个相对稳定的水平。
6.5 集成 LDAP / AD 统一认证
团队规模上来之后,每个成员单独注册账号并维护密码是很痛苦的事情,离职员工账号删除不及时还有安全隐患。Harbor 支持对接 LDAP/AD 服务器,在“配置管理 → 认证模式”里选择 LDAP,填写相关地址和参数。这样员工用公司统一账号就能登录 Harbour,权限还是按项目控制。
配置完成后需要重新登录,认证模式切换后原来的本地账号可能无法直接登录,这个要注意,最好在非高峰期切换,并且提前确认 LDAP 参数正确。
6.6 日志查看与常见问题定位
Harbor 容器里每天会产生大量日志,主要集中在 harbor-log 容器中。查看日志的方法:
# 查看某个容器的日志 docker-compose logs -f --tail=100 harbor-core # 如果所有服务都正常的,但某些镜像复制失败,去 jobservice 日志里找 docker-compose logs -f --tail=200 harbor-jobservice实际排查中,推送镜像失败时,先看harbor-core和nginx日志;垃圾回收异常时,看harbor-jobservice和harbor-registry日志。日志里包含具体的错误码和 HTTP 状态,能帮我们快速缩小范围。
我个人的习惯是固定一个“日志查验顺序”:用户报障时,先查 nginx 日志确认请求到没到 Harbor;再到 core 日志确认认证和权限环节;再往下才到 registry。这样一层层排查,很少出现抓瞎的情况。
7. 一些补充工具与进阶玩法
7.1 从裸 Docker Registry 平滑迁移到 Harbor
以前用 Docker Registry 的场景,想迁移到 Harbor 其实比较简单。因为 Harbor 底层就是 Docker Registry,镜像格式完全兼容。只需要在 Harbor 创建好对应项目,然后在客户端重新打标签推送即可。如果镜像量大,可以用 skopeo 这类工具做批量同步。
# 用 skopeo 示例(先登录源和目的) skopeo copy --src-creds=user:pass --dest-creds=user:pass \ docker://old.registry.com/library/nginx:1.24 \ docker://192.168.209.133/library/nginx:1.24skopeo 的好处是不需要把镜像拉到本地就能完成复制,对网络和磁盘的消耗都比较小。
7.2 配合 CI/CD 流水线使用
Harbor 和 Jenkins、GitLab CI 这些工具的配合场景太多见了。以 GitLab CI 为例,流水线里构建镜像后直接推送到 Harbor:
build: stage: build script: - docker login -u $HARBOR_USER -p $HARBOR_PASSWORD 192.168.209.133 - docker build -t 192.168.209.133/project/app:$CI_COMMIT_SHA . - docker push 192.168.209.133/project/app:$CI_COMMIT_SHAHarbor 中可以为该 CI 机器人建一个专门的账号,并只授予对应项目的推送权限。平时别把 admin 密码放到 CI 变量里,至少用个只读或只写账号,降低风险。
另外很多团队用 Harbor 做版本管理,镜像 tag 用 git commit hash,这样每次部署都能精确定位到代码版本。配合 Harbor UI 里 tag 保留规则,可以保留最近 N 个构建产物,既安全又不占太多空间。
7.3 镜像签名与漏洞扫描
Harbor 2.x 内置了漏洞扫描能力,基于 Trivy,可以在项目配置里开启“自动扫描”。这样每次推送新镜像后,Harbor 会自动扫描已知漏洞并通过 UI 展示。严重漏洞的镜像可以通过策略阻止拉取。
如果团队对供应链安全有更高要求,可以启用 Cosign 做镜像签名,Harbor 对 Cosign 签名有一定的集成支持。不过对于绝大多数内部使用场景来说,漏洞扫描已经属于加分项了,签名通常不是刚需,可以按团队规范逐步引入。
7.4 多 Harbor 实例负载均衡
单台 Harbor 做生产环境,最大的瓶颈在于并发推送量和大镜像存储。到了这个阶段,可以考虑用多台 Harbor 实例,前置负载均衡。Harbor 的 registry 后端如果共用同一个对象存储,理论上可以做到无状态横向扩展。
比较常见的模式是外部挂 S3 兼容存储,registry 数据不落本机磁盘,这样多台 Harbor 实例共享一份数据。docker-compose 部署模式对这种架构支持不算完美,一般建议单机模式或 K8s 模式配套对象存储。先把单机用明白,再考虑扩展。
8. 几点实操心得与收尾
整套流程走下来,我最想给后面动手搭建的朋友们强调的其实是下面三点:
第一,insecure-registries是新手遇到最多问题的根源,建议在安装 Harbor 之前就把客户端 Docker 环境统一规范好,别等推送失败才想起来配置。很多网上教程只写了 Harbor 本身的部署,没提客户端配置,导致很多人卡在执行这一端。
第二,Harbor 的配置改动成本很低,重新执行 install.sh 是幂等的,所以不要怕改配置,数据不会丢。改配置最需要注意的是端口冲突和数据目录,提前规划好这两项,后续迁移成本能大幅降低。
第三,日常运维中,垃圾回收和配额管理这两件事一定要舍得花时间配置。我在生产环境见过太多因为磁盘写满导致仓库瘫痪的案例,这些运维动作看似简单,但真正落地执行的团队并不多。把这两个动作做成定时任务,维护成本极低,带来的稳定性回报却很明显。
我目前这套 Harbor 环境已经稳定跑了一年多,从最初的单团队几台机器,发展到现在支撑研发、测试、生产三大环境的镜像分发。中间经历过磁盘告警、HTTPS 证书切换、跨机房复制这些大大小小的问题,但整体架构一直没有大改,说明当初选择 Docker + Harbor 的路线是走得通的。如果你也正在评估私有镜像仓库方案,照着这篇文章的路径先跑通一遍,能少踩不少坑。