
从零搭建Harbor私有仓库生产环境级安装配置全记录开发环境里随便 pull、随便 push 镜像的日子一进生产环境就结束了。我接手第一个正式项目时团队用的还是最朴素的方案一台服务器上跑了官方 registry 容器所有镜像按项目名堆在一起密码写在部署文档里谁都能 pull 也能 push。刚开始人少问题不明显。等后端、前端、算法三个组一起上线加上 CI 流水线开始频繁构建现场基本失控——镜像 tag 乱写、磁盘爆掉、版本回滚找不到老镜像甚至有同事不小心 push 了一个同名 tag 把生产版本覆盖了。那之后我做的第一件事就是找一套真正能落地的私有镜像仓库方案。当时对比过几个选项最终选了 Harbor。原因很直接它不只解决“存镜像”的问题而是把权限、审计、复制、漏洞扫描这些企业级需求一次性打包而且部署成本远低于自己拿 registry 自研管理后台去拼。这篇文章不聊概念直接按我在生产环境的完整实施过程来讲从选型到安装、配置、日常使用、问题排查、升级维护全部覆盖。先说清楚这篇内容的定位如果你是刚接触容器生态、想给团队搭一个稳定镜像仓库的运维或开发可以完整读一遍如果你只是临时搭个环境写 Demo重点看安装选型和快速部署部分如果你已经跑过 Harbor、但被证书、存储、升级这些细节折腾过直接跳到“常见问题与排查实录”和“升级与备份”两章应该能找到对应答案。1. 内容整体设计与思路拆解1.1 为什么是Harbor而不是裸 registry裸的 Docker Registry 我用了大概三个月感受非常明确它能存镜像但管不住人也管不住镜像的使用方式。团队里每个人都能 push、都能 pulltag 可以随意命名旧镜像没人清磁盘空间一次一次告警。更难受的是一旦多个项目共用镜像目录层级完全靠自觉根本没法做权限隔离。Harbor 带来的核心变化在于它把一个单纯的存储服务变成了完整的管理系统。权限层面它支持基于项目的用户或用户组隔离每个项目可以单独设置谁来拉取、谁来推送镜像层面tag 可以设置不可变immutable防止生产 tag 被覆盖运维层面有操作日志审计谁在什么时间做了哪个操作都留有记录。另外它还内置了漏洞扫描和镜像复制能力这些对于安全要求高的业务场景几乎是刚需。说句实话如果你的团队规模只有两三个人而且部署环境完全可信那裸 registry 确实够用。但凡是团队超过五个人、有独立测试环境和生产环境、或者需要对接 CI/CD 系统我建议直接上 Harbor。它在生产环境中多出来的这点资源开销换来的是管理成本和事故概率的大幅下降。1.2 Harbor 的核心组件构成很多第一次接触 Harbor 的人会被它的部署方式吓到——docker-compose 拉起来一串容器。其实它的容器数量看着多逻辑上完全可以拆成几个部分来理解。入口层是 nginx负责统一接收外部请求终结 TLS 证书并把请求按路径转发给后面的服务组件。核心业务层是 core 和 portalportal 是 Web 界面core 是 API 和业务逻辑的载体。镜像存储层是 registry也就是 Docker 官方的 registry 镜像Harbor 只是给它套了一层管理和鉴权的外壳。此外还有数据库PostgreSQL、缓存Redis和负责漏洞扫描的任务组件。这几个容器协同工作组成了完整的 Harbor 服务。理解了架构安装的时候就不会慌。你会看到 docker-compose 里有一长串服务定义但这些服务大多不需要你直接操作只要把配置文件和环境变量准备对Harbor 自己会处理容器编排。关键是不要把精力花在细枝末节上而是把它当成一个整体黑盒来部署把前置条件准备好比纠结某个容器内部逻辑重要得多。1.3 安装方式的选型思考Harbor 官方提供两种主流安装方式在线安装online installer和离线安装offline installer。两者的区别非常直白在线安装器体积很小安装过程中动态拉取镜像离线安装器把需要的镜像全部打包在压缩包里安装时直接加载。我在生产环境一律用离线安装。原因很朴素安装 Harbor 的服务器通常在内网环境外网访问受限在线安装很可能卡在拉镜像这一步就算是能访问外网的机器安装过程也不应该依赖外部网络的稳定性。离线包多下载几百兆换来的是全程可控、可预测的安装过程。另外一个重要的选型维度是 Harbor 的版本。我个人的经验是不要贪图最新版本生产环境优先选择已经发布过一段时间、社区反馈充分的版本。新版本刚出来时可能会有一些边缘问题而仓库系统作为基础设施稳定性高于一切。具体版本号我建议你在官方 release 页面查看选一个发布时间超过两个月的稳定版本。2. 环境准备与前置条件这些坑先排干净2.1 服务器资源规划CPU、内存、磁盘一个都不能少Harbor 官方给出的最低配置是 2 核 CPU、4GB 内存但这个数字在真实生产环境里只能算勉强能跑。我自己第一次部署时就在一台 2 核 4GB 的机器上跑结果是 Web 界面响应很慢并发推送镜像时 CPU 直接被打满docker compose 里的容器频繁出现健康检查失败。如果条件允许生产环境建议 4 核 8GB 起步。镜像仓库属于 IO 密集型服务磁盘性能比 CPU 更关键有条件上 SSD 就上 SSD尤其是多团队高频推送镜像的场景机械盘的延迟会直接影响推送速度和稳定性。磁盘规划是最容易被忽略的地方。Harbor 的镜像数据默认保存在宿主机/data目录下数据库、证书、日志也都集中在数据目录里。这个目录必须单独规划不要跟系统盘混在一起。我见过最惨的一次事故就是把 Harbor 装在了根分区只有 30GB 的机器上镜像推了没几天整个根分区满了容器全部异常退出。所以装之前一定要搞清楚数据目录要放在独立分区或者独立数据盘上预留的容量至少要按未来一年镜像增长量来估。2.2 操作系统与依赖软件版本要求Harbor 对操作系统的要求其实很宽松主流的 CentOS、Ubuntu、Debian 都在支持范围内。但我建议优先选择你团队最熟悉的发行版不要为了 Harbor 特意换系统。依赖方面最核心的就是 Docker 和 Docker Compose。这里有一个容易出问题的点Harbor 不同版本对 Docker 版本有各自的要求安装前务必去官方文档确认。特别要留意的是 Docker Compose 的版本Harbor 的安装脚本依赖 docker-compose 命令如果系统里用的是新版 Docker 内置的docker compose没有横杠安装脚本可能识别不到。我的做法是在安装 Harbor 之前单独安装完 docker-compose-plugin确认docker-compose --version能正常输出版本号再继续下一步。域名规划也要提前想清楚。Harbor 的仓库地址会被写进 docker 客户端的配置和 CI/CD 流水线里一旦部署后再换域名几乎所有客户端都要重新配置。最好在一开始就用一个正式的、规划内长期有效的域名比如harbor.internal.example.com。没有域名的情况下用 IP 地址也可以但 HTTPS 证书的签发和客户端配置会更麻烦一些后面在证书部分会详细说。2.3 提前创建好目录结构与配置备份目录安装 Harbor 之前我习惯先把目录规划好避免安装过程中临时乱放文件。我的标准目录规划是这样的数据目录用一个独立挂载点比如/data/harbor下面再细分几个子目录后续好维护。配置文件放在单独的目录离线包解压后的harbor.yml是核心配置文件我会在正式修改前先拷贝一份原始版本用来对比和回滚。证书文件放在/data/harbor/certs目录下私钥权限必须严格设置为 600这个后面细说。其实这一步本质上是为后面的可维护性做铺垫尤其是涉及证书更新、存储迁移的场景目录结构清晰会节省大量排查时间。3. 核心细节解析与实操要点3.1 离线包下载与完整性校验下载离线安装包最靠谱的渠道是 Harbor 官方 GitHub Releases 页面。注意认准harbor-offline-installer-版本号.tgz这个文件名不要下载成在线安装包。下载完成后我建议先做 SHA256 校验。官方页面通常会同时提供对应的.asc签名文件或者 SHA256 校验值把下载的压缩包 hash 一下比对。这一步看似多花十几秒但能避免下到损坏或不完整的包带来的莫名奇妙的安装问题。我早期有一次跳过校验安装时 registry 容器反复重启查了很久才发现是安装包本身不完整导致的。# 下载离线安装包后强烈建议先做 sha256 校验 wget https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-offline-installer-v2.11.1.tgz sha256sum harbor-offline-installer-v2.11.1.tgz解压之后你会得到一个harbor目录里面最核心的文件就是harbor.yml和install.sh。先修改配置文件再执行安装脚本这个顺序千万别反。3.2 harbor.yml 配置逐项解析看似简单其实全是细节harbor.yml是 Harbor 安装的全部开关几乎所有关键配置都集中在这个文件里。我第一次配置时没怎么在意结果 HTTPS 段配错导致客户端全部连不上后来才逐项研究明白。先看hostname字段这个值决定了访问 Harbor 的地址。如果用了域名就填完整的域名如果直接用 IP就填 IP。要注意的是即使你打算用 HTTP 访问这里的 hostname 也必须和客户端后续访问的实际地址保持一致否则生成的配置信息会不一致。然后是http和https段落。很多初次安装的人会直接把https段注释掉、只开http图省事。我理解这个选择但必须提醒Docker 客户端默认对非本地地址的 HTTP 仓库是拒绝 push 的必须额外在/etc/docker/daemon.json里配置insecure-registries才能用。虽然测试环境这么干没问题但生产环境我强烈建议用 HTTPS后面专门用一节讲证书问题。data_volume指定镜像存储目录默认是/data我建议改到独立数据盘上。这里要注意的是如果数据盘挂载点和默认路径不一致一定要在配置里明确改掉不然 install 脚本创建的在/data下的文件如果落在系统盘上后续扩容会很痛苦。harbor_admin_password是管理员初始密码。安装完成后 Harbor 不会让你重新设置管理员密码而默认密码是公开的所以这个字段必须在安装前改成你自己的强密码。强烈建议用至少 12 位、包含大小写字母和数字的复杂密码避免用团队名、生日这类可猜测的内容。如果密码里有特殊符号注意有些版本在自动生成配置时会处理不当我为了保险起见遇到的这种情况会避免用特殊字符。数据库密码database_password也在配置文件中设置。这里有个细节安装脚本会通过环境变量把数据库密码传给 Harbor 的 db 容器如果密码里有$等特殊字符可能会在 shell 解析时出问题。建议使用不包含特殊字符的长随机字符串。写完了配置文件我还会再做两件事检查 YAML 缩进是否正确以及确认harbor.yml的权限是 644 或更低。YAML 解析失败会在安装脚本里报很奇怪的错误多检查一遍能省掉后面的排查时间。3.3 证书配置HTTPS 是生产环境的底线证书是 Harbor 安装中第一个真正让新手抓狂的点。这里我先给出两种常见场景的完整操作。如果是公网或内网有正规域名最好申请权威 CA 签发的证书。域名为harbor.example.com的场景你得在 Harbor 服务器上先准备好server.crt和server.key两个文件。如果是纯内网环境很多人会用自签名证书。此时我建议在服务器上自己建一个内部 CA而不是直接用openssl req -x509生成一个简单的自签名证书。原因很简单如果直接用自签名证书集群内每台 Docker 客户端都得去配置它后续换了证书还得重新配置而用一个内部 CA把 CA 证书统一分发到各台机器上以后服务器证书更新客户端根本不用动。这个细节在客户端配置这一节里我会再展开讲。在 Harbor 服务器上生成内部 CA 和服务器证书的操作大致如下简化起见只列出核心命令实际使用时可根据域名调整参数。我见过很多人把私钥权限配成了 644这会带来安全问题务必记得chmod 600。生成证书之后回到harbor.yml在https段里将certificate和private_key指定到刚才生成的文件路径把http段注释掉即可。这里要说一个常见误区证书的域名或 IP 必须与客户端实际访问 Harbor 的地址完全匹配。如果你用harbor.example.com访问但证书里只写了 IP客户端会报证书校验失败反过来如果我配置了域名但后来一直用 IP 访问同样会失败。所以证书生成时的 CN 和 SAN 字段要和最终客户端使用的地址保持一致。自签名证书场景下还有一个小细节Harbor 默认在浏览器打开时会提示不安全这对 Docker 客户端不影响但如果你希望浏览器也不报警可以把内部 CA 证书导入到操作系统的受信任根证书列表里办公环境的机器可以做这一步开发者体验会好很多。4. 实操过程与核心环节实现从配置文件到跑起来4.1 修改配置文件前的备份准备解压离线包之后官方会提供一个harbor.yml.tmpl模板文件需要你复制为harbor.yml再做修改。我建议把模板文件保留一份不要直接覆盖后续如果配置改乱了至少能对比初始状态。执行cp harbor.yml.tmpl harbor.yml之后打开文件逐项修改。这个过程我用过三遍每次大概十分钟主要是细心核对每一项不着急保存。4.2 执行安装脚本每一个输出都值得看配置完成后执行安装脚本sudo ./install.sh安装过程会做几件事检查 docker 和 docker-compose 是否可用、加载离线镜像包、根据 harbor.yml 生成 docker-compose.yml、创建数据目录、最后拉起来所有容器。我这里建议安装脚本跑完后不要急着高兴先看输出结尾有没有报错信息。执行完如果出现类似✔ ----Harbor has been installed and started successfully----的提示才说明整体安装成功。然后检查容器状态sudo docker-compose ls sudo docker ps正常状态下会有至少 8 到 9 个容器在运行状态其中nginx容器是入口harbor-core是核心逻辑registry是镜像仓库本体harbor-db是数据库harbor-redis是缓存还有harbor-portal提供 Web 界面。看到这些容器都是 Up 状态基本就成功了一大半。安装完成后如果修改了配置比如改了端口或域名可以用sudo ./install.sh重新执行Harbor 会检测已有配置并提示。日常维护不要直接手动docker-compose stop/start这个后面会提到。4.3 首次登录Web 界面快速验证安装成功后用浏览器打开https://你的地址。首次访问如果是自签名证书浏览器会有安全警告点继续访问即可。默认管理员账号是admin密码就是你刚才在harbor.yml里设置的harbor_admin_password。登录成功后会进入项目列表页。此时我建议做的第一件事不是马上建项目而是先检查一下管理菜单里的配置项尤其是 认证模式、仓库地址显示这些确认它们跟你的规划一致。4.4 创建项目并配置访问权限团队协作的关键一步Harbor 的项目是权限管理的最小单元。点击“新建项目”填写项目名称比如backend、frontend、algorithm。这里有一个选择“访问级别”的设置如果勾选了公开那么所有能访问 Harbor 的用户都能拉取这个项目里的镜像不勾选则只有被授权的用户才能拉取。我的建议是默认全部私有需要公开的单独设置这样可以避免内部镜像被误拉取。紧接着要做的是为团队创建用户。在“系统管理 → 用户管理”中逐个添加成员然后回到项目页面选择“成员”把用户添加到项目并分配角色。Harbor 的角色有项目管理员、开发人员、维护人员、访客等几种按实际情况选择即可。我最常用的分配方式是项目管理员给小组负责人开发人员给需要推送和拉取镜像的研发访客角色给只需要拉取镜像的测试或部署账号。权限配置完成后还有 Docker 客户端的登录验证。在一台能访问 Harbor 的机器上执行docker login https://你的地址输入用户名和密码提示Login Succeeded就说明客户端认证没问题。如果这一步失败九成是证书信任或地址配置的问题可以跳到后面的排查章节查看。4.5 镜像推送与拉取验证完整链路创建好项目和用户后拿一个本地镜像走一遍完整的 push 和 pull 流程确认整条链路是通的。# 给本地镜像打上 Harbor 仓库的完整 tag docker tag nginx:latest 你的地址/backend/nginx:v1.0 # 推送镜像到 Harbor docker push 你的地址/backend/nginx:v1.0 # 拉取镜像 docker pull 你的地址/backend/nginx:v1.0这里要注意一个端口细节Harbor 默认的 HTTPS 端口是 443HTTP 默认是 80。如果你在harbor.yml里改了默认端口所有docker tag和docker login里的地址都要带上对应的端口很多人在这上面卡了很久。推送成功后在 Harbor Web 界面的“镜像仓库”里就能看到backend/nginx这个仓库和对应的 tag。整个流程走通之后Harbor 的骨架就算完全落地了后面就是日常的策略配置和运维细节。5. 客户端接入细节Docker、Kubernetes 与 CI/CD 的适配5.1 Docker 客户端的 insecure-registries 与证书信任配置客户端接入是 Harbor 部署完成后面临的第一个“最后一公里”问题。如果 Harbor 用的是 HTTP必须在每台客户端机器的/etc/docker/daemon.json中配置{ insecure-registries: [harbor.example.com] }然后执行sudo systemctl restart docker重启 Docker 守护进程。这里有个优先级的问题daemon.json 里如果已经存在其他配置比如registry-mirrors修改时不要把原配置删掉要合并保留。重启 Docker 对正在运行的容器有影响客户端机器建议选择合适的维护窗口执行。如果是自签名证书但用了 HTTPS我不推荐直接走 insecure 配置更正规的做法是把内部 CA 证书拷贝到客户端机器的/etc/docker/certs.d/你的地址/目录下并命名为ca.crt。这个目录方式比修改 daemon.json 更精确而且只针对特定仓库生效。在 Kubernetes 节点上也可以使用同样的方式配置 containerd 或 docker 的证书信任。我的经验是如果你有超过三台客户端机器需要配置一定要脚本化处理不要手动一台一台配。写个简单的 shell 脚本把证书分发和 docker 重启串起来既能保证一致性也方便后续证书更新时批量操作。5.2 Kubernetes 集群如何拉取 Harbor 私有镜像Kubernetes 集群使用 Harbor 镜像核心问题有两个节点信任证书和拉取凭证。第一个问题每个节点都需要信任 Harbor 的 CA 证书。第二个问题Kubernetes 拉取私有仓库镜像需要先创建一个docker-registry类型的 Secret然后用这个 Secret 在 Deployment 里指定imagePullSecrets。创建 Secret 的命令kubectl create secret docker-registry harbor-registry-secret \ --docker-server你的地址 \ --docker-username用户名 \ --docker-password密码 \ --docker-email任意邮箱 \ --namespace你的命名空间然后在工作负载的 YAML 里引用spec: template: spec: imagePullSecrets: - name: harbor-registry-secret这里要特别提醒不要把所有命名空间共用同一个 Secret因为 Harbor 里的项目权限是按账号隔开的如果 A 项目的账号被 B 命名空间拿去用可能有权限越界的风险。在命名空间维度管理 Secret配合 Harbor 的项目权限是很关键的规范问题。另外还有一个细节在 Kubernetes 里拉取镜像时镜像地址中的项目名和镜像名大小写要严格匹配 Harbor 的规则。Harbor 项目名不支持大写字母如果团队习惯用大写命名在迁移到 Harbor 过程中可能会遇到找不到镜像的诡异问题。5.3 CI/CD 流水线里的最佳实践如果你在用 GitLab CI、Jenkins 或 GitHub ActionsHarbor 完全可以在流水线里无缝对接。基础用法是在流水线的构建阶段直接docker login然后构建镜像推送到 Harbor。但生产环境中我建议更进一步把镜像版本和代码提交信息关联起来。比如用 Git 短提交 SHA 作为镜像 tag 的一部分或者用流水线生成的构建号做 tag这样每个镜像都能溯源到对应的代码版本。我习惯的模式是分成两个阶段。第一个阶段是流水线构建后推一个带唯一标记的镜像比如backend/nginx:build-20250112-1830。第二个阶段是人工确认无误后再把这个 tag 重新打为稳定的 release 版本比如backend/nginx:v1.2.0。这种方式既保留了不可变版本又能在版本号上做有效管理。如果担心流水线频繁推送导致磁盘增长过快还可以在 Harbor 里配置镜像清理策略。Harbor 的“清理策略”功能可以按规则自动清理旧镜像比如保留最近 N 个 tag清理超过 N 天的 tag。这个功能在生产环境非常实用能有效控制存储占用但配置时要小心不要把正在使用的镜像删掉建议先在测试项目里观察一段时间。6. 日常使用与团队协作规范6.1 镜像命名与 Tag 规范从根源上减少混乱Harbor 安装完成后团队协作的关键往往就不再是技术问题了而是规范和约定。镜像命名上我建议统一使用仓库地址/项目名/应用名:版本号的格式。项目名对应 Harbor 里的项目应用名对应服务名版本号对应可追溯的 tag。其中版本号部分最好区分环境比如v1.2.0表示正式版本dev-20250112表示开发快照rc-xxx表示候选版本。这套命名规范的收益要等团队达到一定规模才能体现出来但前期定好后面就少很多争吵。Harbor 有一个非常重要的功能tag 不可变。在项目的 “Configuration” 里可以把某个前缀的 tag 设置为 immutable这样一来任何人包括管理员都不能覆盖已有的 tag。这个功能我强烈建议在正式版本项目上开启它是我前面提到的“生产镜像被意外覆盖”问题的官方解法。6.2 用户、角色与回收机制Harbor 提供多级角色模型系统管理员Admin、项目管理员Project Admin、开发人员Developer、维护人员Maintainer、访客Guest。不同角色能做的事差别很大比如开发人员可以 push 和 pull 镜像但不能删除镜像或修改项目设置维护人员在开发人员基础上还能读取日志等。我最常用的模式是管理员账号只留给平台运维团队负责人拿项目管理员研发给开发人员角色测试和部署账号给访客即可。权限最小化可以避免很多安全事故即使内部团队也是如此。用户回收也要建立机制。人员离职或调动时管理员应及时禁用账号而不用急着删除。Harbor 的账号禁用和删除都支持禁用更安全因为不会影响已创建的镜像及审计记录。6.3 审计日志与镜像漏洞扫描的实际用途Harbor 自带的日志系统记录用户登录、项目创建、镜像推送、镜像删除等关键操作。出了事故时通过日志可以定位是谁、做了什么、什么时间做的。建议配置进程每天由负责人快速浏览一遍管理日志长周期归档必要时配合外部日志收集系统留存。漏洞扫描方面Harbor 通过内置的漏洞扫描器基于数据库比对镜像中依赖组件和软件包的安全漏洞。生产环境建议开启自动扫描在每次推送新镜像后触发扫描扫描结果直接在 Web 界面显示漏洞数量和等级。如果某个镜像存在高危漏洞项目管理员就应该及时处理要么让研发升级依赖重新构建要么临时下架该 tag阻断使用方继续拉取高危镜像。7. 常见问题与排查技巧实录Harbor 安装和日常运维最大的挑战永远不在安装本身而在那些奇怪的问题上。下面是我在真实环境里踩过的坑和排查思路直接整理成速查表。7.1 安装或启动失败容器频繁重启怎么办容器启动失败排查第一步永远是看日志。比如harbor-core容器反复重启需要执行docker logs harbor-core查看输出数据库相关的问题看harbor-db容器的日志。常见的坑有以下几类端口占用。我见过多次因为宿主机 80 或 443 端口被其他 Web 服务占用的场景Harbor 的 nginx 容器起不来。排查方式很直接netstat -tlnp | grep 80看端口谁占着然后调整 Harbor 端口或解决冲突。这种问题最容易误判成 Harbor 自身故障。目录权限。Harbor 在启动时需要创建数据目录如果数据目录父级权限不足容器可能启动后立即退出。解决方式是将数据目录的所有权交给当前执行安装的用户或直接交给 root生产环境我建议用专门用户管理。内存不足。数据库容器或 core 容器启动时如果 OOM容器也会反复重启。低配机器上尤其常见。如果已经发生了查看dmesg | grep -i oom或journalctl -k确认。磁盘空间不足。这个看似简单但非常容易被忽略。df -h看一下数据盘的使用率超过 85% 时就要着手清理了。Harbor 不会因为磁盘满自动停止服务但写入镜像时会报错表现得很奇怪。7.2 客户端登录失败证书与地址问题的排查顺序docker login报错是一个非常高频的问题。按下面顺序排查通常能在几分钟内定位先确认地址有没有写对端口有没有带。如果输错地址或端口错误信息大概率是连接超时或被拒。再确认证书是否可信。如果客户端没配 CA 证书而仓库是自签名 HTTPS会报证书校验错误。如果是 HTTP 但客户端没配置 insecure-registriesDocker 会拒绝非安全连接。最后确认网络是否真的通curl -k https://你的地址/v2/能返回 JSON 响应说明服务本身没问题问题多半在客户端配置。7.3 镜像推送失败413、500、超时分别是什么问题推送大镜像时犯的错误和网络有关常见的是 nginx 上传大小限制。确认harbor.yml里是否启用了client_max_body_size或者在 nginx 容器里检查配置。如果推送时报 413 Request Entity Too Large基本就是这个问题。另外有些网络环境上传不稳定建议 Docker 客户端配置较低的并发重试机制但更稳的做法是 CI 机器和 Harbor 之间保持内网直连跨公网推大镜像很容易不稳定。还有一个隐蔽问题是镜像推送到一半出现连接被重置。这种多发生在 Harbor 前面有负载均衡器而负载均衡器设置的上传超时时间太短或 TLS 握手超时。排查时可以绕开负载均衡直接连 Harbor 后端节点试试如果正常重点检查负载均衡配置。7.4 存储占用不断增长的应对策略镜像仓库的存储增长是必然的但失控增长是可以避免的。一个常见问题是开发/测试环境反复推送相同代码的镜像tag 一直在变旧镜像从未清理。应对方式是项目里配置“清理策略”保留最近 N 个 tag删除超过 N 天的镜像。定期执行或手动触发能明显回收空间。清理前注意确认没有 Pod 还在使用将被删除的 tag不然删除瞬间可能会导致拉取失败的偶发情况。Harbor 的垃圾回收机制也需要了解。删除镜像之后底层存储文件不会立刻释放要执行垃圾回收才能真正释放磁盘。这个操作可以在 Harbor 界面里触发也可以在维护窗口在服务器上执行脚本进行。GC 执行期间会影响镜像推送建议放在低峰期或维护窗口进行。7.5 自签名证书有效期一年后突然全部客户端失效这是最容易被忽略的定时炸弹。自签名内部 CA 证书默认有效期一年到期后所有配置了旧 CA 的 Docker 客户端都会开始报证书错误。更麻烦的是如果 Harbor 的服务器证书绑定的是上一个 CA那么光在 Harbor 侧换证书是不够的客户端也要同步信任新 CA。我的建议是创建内部 CA 时直接指定足够长的有效期比如 10 年服务器证书可以短一些比如 2 年更新流程要提前演练一遍。证书更新这种事不能在过期当天才想起来最好在日历上加一个提前 60 天的提醒。对于有这个需求的生产环境还可以考虑使用自动证书管理方案但要确保网络和架构支持否则会引入新的复杂度。8. 升级与备份Harbor 运维绕不开的必修课8.1 备份策略数据目录与数据库缺一不可Harbor 的数据可以分成两部分镜像文件和数据库数据。镜像文件在数据目录下数据库在harbor-db容器里。只备份镜像不备份数据库恢复后你会发现项目、用户、权限信息全部丢失镜像也变成没有归属的孤儿。备份数据库的推荐方式是在宿主机上执行docker exec命令调用 PostgreSQL 的 pg_dump 工具导出数据到文件然后连同数据目录一起做增量或全量备份。如果数据量很大可以考虑先对文件系统做快照再配合数据库备份这样能保证一致性。我第一次给 Harbor 做备份时只拷了数据目录没备份数据库。后来一次服务器重装恢复完发现项目列表是空的登录用户也没了那一刻才真正明白数据库的重要性。从那以后我的备份脚本永远是把两样绑定在一起。8.2 升级流程先看官方升级指南Harbor 的版本升级不能像普通应用那样直接覆盖安装包特别是跨大版本升级官方都会提供专门的升级指南有的版本之间需要先升级到中间版本。升级前如果没有读文档很容易把环境搞挂。我的标准升级流程是先完整备份包括数据库和数据目录再下载对应版本离线包仔细阅读官方的升级说明确认当前版本和目标版本之间有没有特殊注意事项然后按照指南执行 Migration Tool。升级完成后验证 Web 界面、docker login、push/pull 全链路正常。升级操作放在维护窗口不要在业务高峰期操作。如果升级失败备份就是你的救命稻草回滚时恢复数据和旧版本即可。8.3 Helm 部署与其他部署方式最后提一句Harbor 也可以由 Helm Chart 部署到 Kubernetes 集群里。如果你的基础设施已经在 Kubernetes 上用 Helm 管理的优点是配置变更可以通过 values.yaml 声明式管理升级回滚也更方便。但 Kubernetes 方式对存储、网络、证书的要求更高排障链路也更长。我个人的建议是如果你团队已经有成熟的 Kubernetes 平台和存储方案可以考虑 Helm 方式如果只是三五台 Linux 服务器跑业务用官方 docker-compose 方式反而简单直接运维心智负担更小。两种方式我都试过最终选择了 docker-compose 方式没有迁移到 Helm核心原因是单机运维简单可控。当然这也基于团队规模不大需要你根据自己团队的情况做决定。9. 写在最后几个让我少踩半年坑的经验之谈关于 Harbor 的安装配置如果只让我总结几条个人体会我会说第一步的证书和域名规划比后面任何一步都重要生产环境永远走离线安装数据目录一定要独立管理员密码在安装前就要改掉升级前必须备份数据库日常文件结构和配置都要留下记录最好写进团队文档。还有一个很多人会忽略的习惯Harbor 服务器上的操作尽量通过脚本或 Makefile 固化下来不要每次手工敲命令。我会把证书生成、备份、清理策略执行这些频繁操作都写成脚本这样换人接手也不会出太大偏差。看到这里如果你也觉得基础设施就该这样“一次搭建长期稳定”那这篇内容的目的大概就达到了。如果你在安装过程中遇到了什么特别的问题欢迎在评论区留言我看到了都会回复。