news 2026/10/22 8:25:20

生产环境Harbor部署实战:从选型到CI/CD接入避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
生产环境Harbor部署实战:从选型到CI/CD接入避坑指南

第一次把 Harbor 部署进生产环境,是给一套已经跑了三年的单体系统做 CI/CD 改造那会儿。团队里原来的做法是开发本地直接连公共镜像仓库,早上十点一过,镜像拉取慢到让人抓狂,更别提往公共仓库推送企业内部镜像时心里有多别扭。后来决定搭一套内网可用的私有镜像仓库,调研了一圈,最后落在了 Harbor 上。这篇文章想把当时的评估思路、部署过程、以及接下来几个月里踩过的坑完整地盘一遍,给刚准备上手私有仓库的团队一份能直接照着做的参考。

我的目标读者很明确:运维、DevOps 工程师,也包括被迫兼职运维的后端开发。你不需要懂 Harbor 内部实现,只要你用过 Docker、知道docker build和docker push大概是怎么回事,就能按这篇内容把 Harbor 装起来并接进 CI/CD 链路。文章不会只贴官方文档,而是会把每个关键配置为什么要这么写、装完以后怎么验证、后续怎么运维都讲清楚。

1. 前置认知:Harbor 在 CI/CD 链条里的位置

1.1 Harbor 到底是什么,它解决了什么问题

Harbor 是一个开源的企业级容器镜像仓库,定位很清晰:面向内网环境提供容器镜像的存储、分发、权限管理和安全扫描。它对外暴露 Docker Registry 协议,所以所有支持 Docker 的客户端都能直接对接;同时它又补上了原生 Registry 缺失的那一整套企业级能力:基于项目的 RBAC 权限模型、多租户隔离、镜像复制、漏洞扫描、垃圾回收、审计日志和 Webhook。

在很多团队里,镜像仓库被简单理解成"存镜像的地方",这其实低估了它。镜像一旦多起来、团队一旦大起来,仓库的核心价值就从"存"转移到了"管"和"控"。"谁能推这个项目?谁能拉这个镜像?这个镜像有没有高危漏洞?哪些节点在拉哪个版本?"这些问题的答案都在镜像仓库里,Harbor 给出的答案算是最完整的一档。

我个人的理解是:Harbor 本质上不是一个存储系统,而是一个以镜像为对象的权限与交付管理系统。它把原本散落在构建脚本里的账号密码、权限判断、版本校验集中到一个平台里,这是它跟裸的 Docker Registry 最本质的差别。

1.2 为什么私有仓库在 CI/CD 流程里是刚需

先看一条典型的 CI/CD 链路:开发提交代码,CI 工具拉代码、跑测试、用 Dockerfile 构建出不可变镜像并打上版本标签,然后把镜像推送到仓库;CD 环节再从仓库拉取指定版本的镜像,滚动部署到测试或生产环境。整条链路的交付物就是镜像,而镜像一旦被推送,理论上不应该再被修改,只能被替换。

这条链路里,仓库是唯一的"事实来源"。如果没有私有仓库,通常只能把镜像推到公共平台,然后在内网节点上拉取。很多团队实际体验是:公共平台访问速度不稳定、间歇性失败,镜像稍微大一点就让人血压升高。更麻烦的是策略合规问题——企业内的镜像可能包含业务代码、配置甚至算法,放到公共平台等于默认公开(虽然可以设私有,但数据毕竟离开了内网),审计上也说不清楚。

私有仓库补上了这些短板。镜像从构建到部署全流程都在内网闭环,速度只取决于内网带宽,权限可以由团队细分,推送与拉取都有日志可查。再叠加镜像签名和漏洞扫描,交付物的可信程度会明显提高。对于任何想认真做 CI/CD 的团队,私有仓库不是"加分项",而是基础设施级的刚需。

1.3 为什么选 Harbor 而不是其它方案

选型的时候我列过一张对比表,主要候选是 Docker Registry 官方镜像、Harbor、通用制品仓库和云厂商托管仓库。

方案核心优势主要短板适合场景
Docker Registry部署极简、资源占用低没有 UI、没有权限模型、没有审计个人实验、极小规模临时使用
Harbor企业级功能齐全,权限/复制/扫描/审计开箱即用组件多,部署比裸 Registry 重,对服务器资源有要求内网持久化、团队协作、CI/CD 正式环境
通用制品仓库能同时管 Maven/npm/PyPI 等制品镜像相关能力支持晚,项目结构以仓库为主,多租户弱已有统一制品管理诉求的团队
云厂商托管仓库免运维、稳定性高与公有云绑定,内网打通依赖专线,策略审批路径长业务已上云、无自建要求的团队

我们当时的约束是:完全内网环境,不能依赖公网服务;需要按项目和团队隔离权限;后续要接漏洞扫描。这样的组合下,Harbor 几乎是唯一能一步到位的自建方案。裸 Registry 不满足权限审计,通用制品仓库在镜像这块不够专,云托管则因为合规直接排除。所以选 Harbor 不是因为它最火,而是它对"企业内网镜像仓库"这个场景的匹配度最高。

2. 动手前必须想清楚的部署方案

2.1 环境基线:硬件、系统、软件版本

Harbor 官方给出的最低要求是 2 核 CPU、4GB 内存,但那个配置只能跑 demo。生产环境的资源规划我倾向于按下面的基线来:

  • CPU:4 核及以上,如果启用了 Trivy 漏洞扫描,建议 8 核。
  • 内存:8GB 起步,实际占用会随着扫描任务和并发推送波动,16GB 会更从容。
  • 系统盘:装系统和 Docker,至少 50GB。
  • 数据盘:单独挂载给 Harbor 的数据目录,容量按镜像增长估算。

磁盘容量这个坑我见过不止一次,这里给一个可以抄作业的估算公式:日均新增镜像体积(去重后) × 留存天数 × 1.2(冗余系数)。比如团队每天构建 30 次,去掉相同层平均每次净增 500MB,保留 30 天,那就是 30 × 0.5GB × 30 × 1.2 = 540GB。这还只是保守场景,镜像一旦包含大数据模型或前端产物,体积会涨得很快。数据盘宁可一次性给大,也不要过三个月再扩容。

软件层面,操作系统用主流的 Linux 发行版即可,Harbor 对系统的依赖其实很弱;真正要留意的是 Docker 和 Docker Compose 的版本。Docker 至少 20.10 以上,Docker Compose 尽可能是 v2 版本。Harbor 安装脚本会检查这两个依赖,版本太老会直接报错,与其到时候排查,不如一开始就配齐。

2.2 在线安装包还是离线安装包

Harbor 官方提供两种安装包:在线版只包含安装脚本和配置模板,实际镜像从网络拉取;离线版把部署需要的所有 Docker 镜像都打进了 tgz 包,安装时不依赖公网。两者的差别只有在执行install.sh那一刻才会体现出来。

我的建议是:除非你能确定执行安装的机器有稳定的外网访问能力,否则一律用离线包。企业内网环境经常出现"代理偶尔能用、偶尔超时"的情况,在线安装卡在一个镜像拉取失败上非常被动。离线包体积大一些(2.x 版本通常是 1GB 上下),但传一次就能反复用,重装、迁移、升级都会用到,这 1GB 的投入很值。

下载完成后第一件事是校验文件完整性。官方页面会给出 sha256 校验值,下载后用sha256sum比对一次。这一步很多人跳过,但安装包在传输过程中损坏的情况真实存在,解压到一半报错再去排查,远比先花一分钟校验要痛苦。

2.3 单机部署还是高可用部署

Harbor 支持两种主流部署形态:单机用 Docker Compose 编排,生产高可用用 Helm Chart 部署到 Kubernetes 集群。两者不是二选一的路线,而是不同阶段的选择。

以我们当时的体量,单机部署完全够用。原因很朴素:镜像仓库对可用性的要求不像数据库那样是"零丢失",集群节点部署期间短暂不可用,影响范围是可控的;而单机部署的运维复杂度低一个量级,升级备份都能用脚本搞定。如果你现在的团队规模在几十人以内、日构建次数在几十到上百这个量级,单机 Compose 部署是最高性价比的起点。

但单机部署必须提前想清楚几个边界:Harbor 自身的数据(数据库、镜像存储、密钥)都在本机,机器宕机期间镜像拉取会中断;磁盘写满会导致推送失败;升级操作需要停机窗口。这些不是缺陷,而是单机的固有特征。接受这些边界,然后靠备份策略兜底,这是务实的做法。等体量真的大到单机扛不住时,再考虑迁移到 Kubernetes 高可用形态也不迟。

3. 安装部署完整实操:从解压到初始化

3.1 解压安装包与目录结构

离线包下载回来后,放到规划好的部署目录(比如/opt/harbor),直接解压:

mkdir -p /opt/harbor && cd /opt/harbor tar -xzf harbor-offline-installer-v2.x.tgz cd harbor

解压后的目录结构很清晰,核心文件就几个:harbor.yml.tmpl是配置模板,install.sh是安装入口,common.sh是公共函数库,还有一整个harbor镜像目录,里面是所有组件镜像的 tar 文件。目录里没有太多多余的装饰,这个结构本身也说明 Harbor 的部署逻辑很直接:加载镜像,生成配置,启动容器。

正式执行前有个容易忽略的动作——打开harbor.yml.tmpl看一下注释,模板里几乎每个字段都有说明,先粗读一遍能避免后面不少低级错误。配置是从这个模板复制出来的,不要直接改模板,正确做法是复制一份再改:

cp harbor.yml.tmpl harbor.yml

3.2 harbor.yml 核心配置逐段拆解

Harbor 安装成败的关键全在harbor.yml里,这里逐个讲清楚必须动的配置项。

hostname

hostname: registry.corp.internal

这是整个配置里最重要的字段,它决定了 Harbor 对外暴露的访问地址,会写进内部生成的证书和各个组件之间的通信 URL 里。这里优先使用规划好的内网域名,而不是 IP。如果暂时没有域名,可以用 IP 先初始化,但后面补域名会涉及证书重建和配置重置,比较折腾。我的建议是:哪怕先用一条/etc/hosts记录把域名解析到本机,也比直接用 IP 干净。

http 与 https

http: port: 80 https: port: 443 certificate: /data/cert/tls.crt private_key: /data/cert/tls.key

生产环境必须启用 HTTPS。pipeline 里推送镜像默认走 TLS,明文传输在公网不可接受,在内网也容易导致客户端配置问题。证书有两个来源:正规 CA 签发的证书,或者内部 CA 签发的证书。如果暂时没有证书,可以先只开 HTTP 并在客户端的 Docker 守护进程配置对应地址为 insecure-registry,但务必把它列为"上线前必须解决"的事项。

初始管理员密码与数据库密码

harbor_admin_password: Harbor12345 database: password: root123

默认的Harbor12345是官方默认值,首次登录后立即改掉是基本操作,但更稳的做法是在配置文件里直接设一个强密码。database.password是 Harbor 内部数据库的密码,默认值属于公开信息,必须改。这里有个经验:把这两个密码记录到团队的密码管理工具里,而不是只存在部署者的本地文件,否则人员变动后想改密码会很痛苦。

数据目录

data_volume: /data/harbor

数据目录建议单独用一块数据盘挂载,而不是放在系统盘。前面估算过容量,这里把路径指到大分区,后续所有镜像、数据库、日志都会落到这个目录。特别注意目录属主和权限,Harbor 容器以特定用户运行,目录权限不对会导致启动时写不进去。保险起见,先建好目录并授权:

mkdir -p /data/harbor chown -R 10000:10000 /data/harbor

这个 10000 是 Harbor 容器内部使用的 UID,不提前授权的话,启动阶段大概率会报卷权限错误。

3.3 执行 install.sh 与底层组件

配置改完就可以安装了。安装命令支持按需启用附加组件,最常用的是漏洞扫描和 Chart 仓库(Helm Chart 支持):

./install.sh --with-trivy --with-chartmuseum

--with-trivy启用了镜像漏洞扫描能力,--with-chartmuseum启用了 Helm Chart 存储。如果团队暂时不用 Helm,可以先不加 chartmuseum;但 Trivy 建议加上,镜像安全扫描在 CI/CD 里越早介入成本越低。

安装脚本整体流程是:先加载离线包里的镜像到本地 Docker,再根据harbor.yml生成 docker-compose 配置并启动容器。整个过程会持续 5 到 10 分钟,主要耗时在镜像加载上。启动完成后用docker ps验证,正常情况下会看到一组容器:nginx 负责反向代理和 TLS,harbor-core 是核心 API 服务,harbor-db 是 PostgreSQL 数据库,harbor-registry 是实际存储镜像的 Registry,harbor-jobservice 处理复制和扫描任务,harbor-portal 是 Web 前端页面,redis 做缓存。

看到这些容器都处于 healthy 状态,说明部署这一关已经过了。如果有容器反复重启,不要着急,绝大多数情况是配置问题,查看具体容器日志就好:

docker-compose -f harbor/docker-compose.yml logs -f harbor-core

依赖目录需要在 harbor 目录下执行 docker-compose 命令,其中 docker-compose.yml 是安装脚本生成的,不要手工去改它,配置修改应该回改 harbor.yml 然后重新执行安装或更新逻辑。

3.4 基础验证与初始化项目

容器起来后,浏览器访问配置的 hostname,能出现登录页面就基本成了。用admin加配置里设置的密码登录,进去后先做三件事。

第一,修改 admin 密码。在用户设置里改成一个随机强密码,并记录到密码管理工具。

第二,创建项目。Harbor 的项目是权限隔离的最小单元,一个项目通常对应一个业务线或一个应用。创建时设置项目名称,选择私有还是公开。私有项目意味着只有被授权的用户或机器人账号才能拉取镜像;公开项目所有人都能拉取,一般不建议开,除非是基础镜像这种全公司共享的资源。

第三,创建机器人账号。在项目的机器人账号页面新建一个 robot 账号,指定它对项目具有推送或拉取权限。这个账号是给 CI 流水线用的,它不绑定具体人员,权限范围可以精确到"只能推这个项目",泄露后可以独立吊销,不会影响真实用户账号。

4. 接入 CI/CD 管道:让镜像在流水线里跑起来

4.1 客户端认证与 docker login

镜像要推送到 Harbor,客户端的 Docker 守护进程必须先认证。最直接的方式:

docker login registry.corp.internal

如果是 HTTPS 且证书是内部 CA 签发的,每台构建机都需要把 CA 证书加入系统信任链;如果退而求其次用了 HTTP,则需要在每台机器的 Docker 守护进程配置里加上:

{ "insecure-registries": ["registry.corp.internal"] }

两种方式我都实际用过,结论很明确:把 CA 证书装进系统信任链才是最省心的做法。insecure-registry 配置会让所有客户端跳过 TLS 校验,一次两次没问题,时间久了会被遗忘,某天上生产环境排查"为什么镜像拉取是明文"时才发现到处是裸奔的节点。有个小技巧:证书的 SAN(Subject Alternative Name)必须包含 hostname 里用的那个域名或 IP,否则就算证书装了信任链,Docker 客户端也会报证书校验错误,还不好定位。

4.2 在流水线里推送镜像的完整编排

CI 流水线里接入 Harbor 的核心就三步:登录、打标签、推送。以某个通用的流水线工具为例,构建阶段的核心逻辑大致是:

docker login -u robot$ci-push -p <token> registry.corp.internal docker build -t registry.corp.internal/order-service/order-api:${BUILD_NUMBER} . docker push registry.corp.internal/order-service/order-api:${BUILD_NUMBER}

几个细节很容易被忽视:

机器人账号的用户名格式。Harbor 的 robot 账号实际登录名是类似robot$ci-push这样的形式,前面带着固定前缀,手动输入时容易漏掉。在流水线变量里配置时,直接复制 Harbor 页面显示的完整用户名,避免手输。

标签策略。生产环境部署要求镜像可追溯,标签要能对应到一次确定的构建。用构建号或 Git 短提交哈希都是好方案,比如order-api:20250411-1205或者order-api:3f2a9c0。不要用latest作为部署标签,否则部署时根本不知道线上跑的是哪次构建,回滚也无从谈起。

推送凭据的存储。robot 账号的 token 是敏感信息,在 CI 系统里应该存成密钥变量,而不是明文写在流水线文件里。即使流水线文件放在私有仓库里,随着协作者增多,泄露面也会变大,凭据独立管理是应该养成的习惯。

4.3 Webhook、镜像复制与持续交付场景

Harbor 与 CD 系统的对接,有两个能力值得认真用起来。

第一个是Webhook。在项目配置里可以创建 Webhook,当镜像推送成功或删除时,Harbor 会向配置的 URL 发送 JSON 通知。这样 CD 系统就不必反复轮询"镜像推送好了没",而是等通知到了再触发部署。实际用起来的流程是:CI 推送镜像,Harbor 发 Webhook,CD 系统收到通知后开始拉取指定标签并滚动发布。这个链路比 CI 工具同时负责构建和部署要干净得多,构建失败和部署失败被清晰地分隔开。

第二个是镜像复制。Harbor 支持把某个项目的镜像自动复制到另一个 Harbor 实例。典型场景是做多环境隔离:开发环境一个 Harbor,生产环境一个 Harbor,两边内网隔离,镜像从开发环境复制到生产环境仓库。复制可以基于标签过滤,可以定时触发,也可以实时同步。这个能力还能顺便解决跨机房拉取慢的问题,让每个机房各存一份副本。

还有个容易被忽略的日常操作是垃圾回收(GC)。镜像删除了,但底层存储空间不会自动释放,因为镜像层之间存在共享。需要定期在 Harbor 的管理界面里执行垃圾回收来清理无引用的层数据。我见过有团队镜像删了一堆,磁盘却越用越满,最后发现是 GC 从没跑过。GC 可以在低峰期手动触发,也可以接受删除后体积不立即下降的特性,把 GC 纳入定期运维动作清单。

4.4 一条参考的完整交付链路

抽象地讲完流程,最终还是落到一条完整的链路上。假设有一个订单服务:

  1. 开发推送代码到内网代码仓库,触发 CI 任务。
  2. CI 任务执行单测、静态检查,然后docker build构建镜像,标签用 Git 短哈希。
  3. 流水线使用项目下的 robot 推送账号登录 Harbor,推送镜像到order-service/order-api项目。
  4. Harbor 触发 Trivy 扫描,发现高危漏洞会阻止镜像转为"已扫描且干净"状态。
  5. Harbor 向 CD 服务发送 Webhook,CD 服务拉取指定标签镜像,在测试环境完成部署。
  6. 测试环境验证通过后,手动(或半自动)触发生产环境部署,CD 服务从同一个 Harbor 拉取同一个标签的镜像完成滚动更新。

这条链路里,Harbor 处在承上启下的位置:向上接收 CI 的产出,向下为 CD 供给交付物。镜像在一个受控、可审计的仓库里流转,任何一步出现问题,都有日志和 tag 可以回溯。

5. 日常运维与升级避坑实录

5.1 磁盘空间、数据备份与恢复演练

Harbor 的数据全部在data_volume目录下,里面主要分成几块:database存元数据、registry存镜像层、secret存密钥、log存日志。备份策略要分层设计,我的经验是:

**镜像层数据(registry 目录)**体积大、变化相对规律,适合用定期快照或同步工具备份。文件级备份时要注意一致性,最稳的方式是停止 Harbor 相关容器后备份,或使用支持应用一致性的存储快照机制。**数据库(database 目录)**是另一条线,Harbor 的配置、项目、用户、审计记录都存在这里。数据库备份建议频率更高,因为镜像只是文件,丢了还能从归档找回,而元数据一旦损坏,整个仓库的索引和权限关系就乱了。

备份做完必须定期演练恢复。我说得直白一点:只做备份不演练等于没有备份。某次试过一次演练,从恢复数据目录到重新启动 Harbor 访问,前后花了不到一小时,但过程中发现数据库备份缺少一致性处理,恢复后需要人工修复用户数据。这个教训让团队把"恢复演练"和"备份"绑定在一起。恢复步骤很简单:停容器、用备份覆盖data_volume目录、重新启动。

5.2 版本升级路径与兼容性

Harbor 升级是个需要按部就班的事。官方提供upgrade.sh脚本,逻辑是:先备份当前数据,然后加载新版本镜像,最后启动迁移容器把数据库和配置迁移到新版本。整个流程设计得很自动化,但有几个我必须特别提醒的点。

第一,版本不能无限制跳级。Harbor 官方只保证相邻主要版本之间的升级路径是经过验证的。如果当前是 2.7,想升到 2.10,官方文档很可能要求先升到 2.9 再升 2.10。跳过中间版本很容易碰到数据库迁移不兼容的问题。升级前先读目标版本的发版说明和升级指南,这一点偷不得懒。

第二,永远先在一台临时环境做升级演练。生产环境直接升级不是不行,但一旦迁移脚本出问题,会面临"旧版本已经被覆盖、回退只能靠完整备份"的局面。我们当时的流程是:复制一份数据目录到测试机,在测试机上跑一遍升级脚本,验证全部功能后再上生产。多花两小时,换来生产不炸的确定性,这笔账非常划算。

第三,升级前必须完整备份 database 目录。升级迁移会直接操作 PostgreSQL 的数据结构,一旦迁移失败需要回退,一个干净完整的数据库备份就是唯一的救命稻草。数据目录备份后,不要在确认升级成功前删除备份。

5.3 常用运维命令速查

Harbor 的日常运维命令集中在 docker-compose 上,整理成速查表方便直接取用:

操作命令
查看所有组件状态docker-compose -f harbor/docker-compose.yml ps
停止 Harbordocker-compose -f harbor/docker-compose.yml stop
启动 Harbordocker-compose -f harbor/docker-compose.yml start
查看某个组件日志docker-compose -f harbor/docker-compose.yml logs -f harbor-core
修改配置后重建修改harbor.yml后执行./install.sh或docker-compose -f docker-compose.yml up -d
查看数据目录占用du -sh /data/harbor/*

有个操作细节值得强调:修改 harbor.yml 后不能重启容器就完事,某些配置(比如 hostname)是通过安装脚本重新生成配置和证书的,需要重新执行安装逻辑,而不仅是docker-compose restart。判断方法是看配置改动是否涉及端口、域名、证书、数据目录这类拓扑级参数,是的话就整套重新执行。

5.4 运维中常见的问题信号

Harbor 的故障不是突然爆炸那种,更多是有规律的前兆信号:

容器反复重启。先看是不是权限问题,特别是data_volume目录的属主不正确时,数据库容器和 core 容器会启动即退出。这类问题用ls -ld查目录属主就能定位。

镜像推送成功但页面看不到。这种情况大多是推送时用的镜像 tag 没有带完整项目路径。Harbor 的镜像组织方式是"项目名/镜像名",推送时必须写明项目名,否则默认推到了 library 项目或直接报错。

页面能打开但 API 超时。常见原因是并发扫描任务占满资源,或者磁盘写入遇到瓶颈。先看系统负载和磁盘 IO,不要一头扎进容器日志里。

访问地址和实际网络不通。很多"服务没起来"的误判,其实是 hostname 配置成了容器内部才认得的名称,客户端没法解析。从一开始就确认 hostname 能被所有需要访问 Harbor 的环境正确解析到服务器 IP,能省掉大量排查时间。

6. 高频问题排查表与长期经验

6.1 遇到的问题和解决思路

把实际操作中最常遇到的现象、原因和解决办法整理成一张表,它比任何单独一段文字都更贴近实战:

问题现象常见原因处理思路
登录页面打不开端口未放行、nginx 容器未启动先确认容器状态,再检查防火墙和监听端口
docker login 报 x509 证书错误客户端不信任该 CA,或证书 SAN 不匹配安装 CA 到系统信任链,并换用包含正确域名的证书
推送镜像报 unauthorized机器人账号权限不足或用户名格式错检查机器人账号权限,确认使用robot$前缀的完整用户名
镜像删了但磁盘没释放垃圾回收未执行在 Harbor 管理界面执行垃圾回收,低峰期操作
磁盘写满后无法推送数据盘容量规划不足清理无用镜像并 GC,扩容数据盘,优化镜像体积
升级后某个功能异常跳版本升级或未按文档走完整流程回退备份,按版本路径重新升级,不要跳级
拉镜像慢跨机房跨网络传输使用 Harbor 复制功能,每个机房部署场景或就近仓库
页面显示"项目不可用"底层存储异常或数据库连接问题查看 jobservice 和 database 容器日志,确认存储可写

这张表看起来简单,但每条背后都有一线排错的影子。特别是"证书 SAN 不匹配"这条,客户端报错信息有时会误导你以为是 CA 不受信任,实际上翻看完整报错才能看到IP SAN缺失的描述。

6.2 部署和长期使用中值得养成的习惯

经历了几次故障之后,我总结了几条固定动作,现在每次部署 Harbor 都会照做:

先规划 hostname 再安装。这个话题前面反复提,因为它是回改成本最高的配置。至少提前在规划文档里确定域名、IP、证书归属,然后一次性配置到位。

机器人账号和人类账号严格分开。人在页面上登录用个人账号,机器在流水线里用 robot 账号。这不仅是权限最小化的问题,审计日志里能清楚看到"哪个操作是哪个主体发起的",排障的时候价值非常大。

磁盘容量做成告警而非事后补救。给数据盘容量设置监控告警阈值(比如 70% 预警、85% 告警),并定期执行 GC。等到写满再处理,意味着正在跑的业务流水线会直接失败,连带下游部署全部阻塞。

保留升级演练的记录。每次升级前把当前版本号、目标版本号、备份路径、演练步骤记到运维文档里。这类信息半年后回头看,能避免很多重复踩坑。

6.3 从单机迈向高可用的演进信号

单机部署用得好好的团队,可能会遇到这几种情况,它们往往是你需要认真考虑高可用的信号:

  • 镜像仓库出现单次故障,直接导致整个发布流程停摆,业务方开始抱怨。
  • 日构建和拉取量明显增长,单机 CPU 和磁盘 IO 经常打满。
  • 团队对镜像版本的安全性要求提升,开始有严格的审计和合规要求。
  • 希望做异地多活或应急演练,单一节点从架构上就无法支持。

真要迈过去,主线方案是 Harbor 官方在 Kubernetes 上部署,使用其 Helm Chart 和外部数据库、对象存储与共享文件存储,配合多副本组件和负载均衡器对外提供统一地址。这套架构的运维复杂度比单机高一个量级,涉及 Kubernetes、持久化存储选型、网络策略等,所以更有价值的前置动作是:在单机阶段就把数据目录设计成可迁移的独立卷,把数据库和镜像存储从容器中剥离为外部服务的可行性预留好评估,这样将来演进时能少一些数据迁移的痛苦。

关于版本和数据的管理,最后想补充一点个人体会。我最初也以为镜像仓库只是 CI/CD 流水线里的一个中转站,部署完就完事了。直到有一次线上发布要回滚,需要确认某个旧镜像当时是谁构建、包含哪些提交、是否有漏洞扫描记录,我才真正意识到 Harbor 的长期价值很大程度在于它积累的元数据。镜像本身只是一个压缩包,而"哪个版本部署在哪里、由谁通过什么流程发布、有没有通过安全扫描",这些信息才决定了回滚是否安全、事故复盘是否有据可查。所以从第一天开始,认真维护镜像 tag 规范、项目权限划分和 robot 账号管理,比任何花哨的自动化都能更持久地保护你的交付链路。这也是我为什么建议不要在最开始只图省事,把镜像往一个公共项目里一推了事——等到镜像数量多起来再回头治理权限和规范,成本会高很多。希望这篇内容能帮你少走一些弯路,把第一套 Harbor 稳稳落地。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 5:22:51

Node.js fs模块深度解析:从API设计到生产环境避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 19:41:24

Matplotlib图例(legend)参数详解与实战调优技巧

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 8:24:52

RTC毫秒级Alarm实现原理与硬件精度控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/18 11:07:01

STM32F103C8T6模拟PS2手柄:裸机时序控制实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/21 11:21:17

8x8 RGB LED点阵控制器布局文件配置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华