资讯详情

Harbor跨版本迁移实战:从1.x到2.10+的完整避坑指南

📅 2026/10/21 3:48:02 | 华诺云谱 👁 阅读
Harbor跨版本迁移实战:从1.x到2.10+的完整避坑指南
说实话Harbor版本迁移这活儿看着就是“把旧数据搬到新环境”这么一句话真上手做的人才知道里面坑有多密。尤其是从低版本往高版本迁比如直接从1.x跳到2.10以上中间隔着的不只是镜像仓库软件的版本号还有数据库结构、配置文件格式、密钥体系这几座大山。我这两年前后帮团队和几个朋友搞过好多次这类迁移有成功的也有做到一半卡住不得不回滚的。这篇就把实际踩过的坑、验证过没问题的步骤、以及为什么必须按这个顺序来的原因一次性讲透。不管你是刚接手公司Harbor的老运维还是准备把自建镜像仓库升级一把手的平台工程师这篇都按“能直接照着做”的标准来写。1. 动手之前先摸清两边的老底1.1 版本跨度直接决定迁移难度很多人一上来就想着“备份data目录拷过去启动”在小版本升级比如2.8升2.10里这招确实管用因为核心数据结构没变镜像blob也没有格式变化。但如果是跨大版本比如1.x升级2.x或者从2.3直接跳到2.11那情况就完全不一样了。先说最简单的分层Harbor运行时的数据大概分四块。元数据存在内置PostgreSQL里的项目、镜像tag、用户、机器人账号、配额、审计日志等这是数据库层面。镜像实体registry目录下的blob和manifest这是Docker Registry V2协议写出来的存储结构。密钥与证书/data/secret下的加密密钥/data/cert下的通信证书跟推送拉取的认证、内部服务TLS直接相关。配置文件旧版是harbor.cfg1.x时代新版是harbor.yml字段结构变化很大。跨大版本迁移时最难的不是镜像实体部分而是数据库和配置格式。PostgreSQL版本、库表结构、甚至加密方式都换过。比如1.x时代的数据库是PostgreSQL 9.6新版要求15/16这个差距靠直接覆盖数据文件是起不来的。1.2 迁移前必须刻进脑子的几个结论基于我做过的迁移案例先给你几个结论省得走弯路官方从1.7版本开始提供迁移工具harbor-migrator它的核心作用就是处理数据库和配置的版本适配但它不是万能的跨太多版本时仍然可能失败。配置迁移不能靠“抄配置”需要理解新版字段含义。旧版harbor.cfg里的某些项新版换了名称或直接移除硬填会导致服务起不来。数据库和registry存储必须是同一个时间点的快照。什么意思如果你先备份了数据库又过了一天才备份镜像目录期间有人往仓库里push了新镜像两边数据就对不上了迁移后可能出现“镜像明明存在但tag丢失”的诡异情况。replication规则、垃圾回收策略、LDAP/OIDC配置这些“带状态的配置”分散在数据库表和配置文件中迁移后一定要人工核对一遍不能假设它们完好。2. 数据结构和核心概念为什么不能直接copy完事2.1 PostgreQL版本差异怎么处理Harbor自己内置了一套PostgreSQL虽然生产环境有人会用外部数据库但绝大多数中小团队都是“一体机部署”。旧版本1.x到2.4左右用的PG版本比较老新版本要求PG 12以上甚至2.9之后默认就是PG 15。PostgreSQL跨大版本的数据文件不能直接让新版本程序去读。旧版本数据目录里的pg_type、pg_proc这些系统表的格式新版本不一定兼容。所以正规做法是用pg_dump把旧库逻辑导出成SQL文件在新环境里通过psql导回去或者直接用pg_upgrade工具处理数据目录但需要新旧binary同时在场操作复杂度高。官方迁移工具在内部就是帮你把这层逻辑做了但我实测下来手动做一遍更可控。尤其是当旧Harbor版本比较老、官方工具对新版本适配不够的时候手动导出导入反倒是最稳的。不过要注意Harbor的数据库里有多个库包括registry、clair、notary、chartmuseum等用pg_dump全量导出时建议按照角色分别导出或者直接把整个PG实例全库导出。我就遇到过只导了registry库结果notary的签名数据丢了的情况。2.2 registry镜像数据为什么意外地好迁镜像仓库的存储目录结构是Docker Registry V2标准规定的layout基本稳定。只要按blob的sha256组织文件存储路径多为/data/registry/docker/registry/v2/repositories/项目/仓库/_manifests/... /data/registry/docker/registry/v2/blobs/sha256/...这部分数据是内容寻址的直接把整个目录打包带走基本上不会出问题。真正麻烦的是manifest与tag的关系记录存在数据库里所以前面才强调数据库和存储必须同步备份。另外如果你用的是对象存储比如S3、MinIO、OSS作为registry的backend那迁移时不需要搬blob只需要改配置文件里的存储地址并确保新实例能访问同一个桶就行。这种情况下数据库的新旧一致性就更关键了。2.3 容易被忽视的“隐形数据”除了数据库和镜像目录还有两块数据容易被拷漏/data/secret这里面保存着Harbor内部服务portal、core、jobservice等通信用的加密密钥、以及一些密码派生用的salt。如果只拷数据库不拷secret新实例里面的数据完整性校验很可能失败尤其是remote replication远程复制配置里保存的仓库密码信息会无法解密。/data/certHTTPS证书及内部CA证书如果这里不一致客户端或用Harbor API做集成的系统会出现证书校验异常表现可能是“连接成功但怎么都推不上去”。我的习惯是直接对/data整个目录做快照或打包不要只打包其中几个子目录。代价不大但能避免一堆奇怪的“灵异问题”。3. 实操从备份到启动的完整迁移流程3.1 第一步停服并备份source端备份之前先做一次“优雅停服”。不要直接kill容器进程最好用docker compose或脚本把Harbor的栈停掉。原因很简单PostgreSQL还在写事务的时候你硬拉数据文件至少会得到一份非一致性快照轻则启动修复重则起不来。官方推荐的备份命令大概是这个套路cd /opt/harbor docker compose stop tar --exclude*.log -czf /backup/harbor_data_full.tar.gz /data docker compose start注意这里的组合拳先stop再打包再start。这样打包出来的数据是静止状态下的一致副本。如果想减少停机时间也可以用LVM快照或者文件系统级快照但对大多数场景来说离线打包已经足够了。打包完成后我还建议额外用pg_dump做一份数据库逻辑备份放在/data包之外单独保存docker exec harbor-database容器名 pg_dump -U postgres --clean --if-exists /backup/harbor_harbor_db.sql这一步属于“双保险”。万一.tar.gz里的数据库文件在新版本上不好直接恢复至少还有一份SQL可以导。3.2 第二步准备新环境新环境的选择有个重要原则如果你的源版本是1.x不要一次跳到最新的2.11而是先装一个2.2或2.5迁移数据验证没问题后再在这个基础上升级到目标版本。原因在于官方迁移工具和数据库升级脚本都是“分段”设计的跳代升级容易遇到SQL脚本执行报错。这不是说肯定不行而是不值得在生产上赌。新环境安装时可以沿用官方在线安装包或离线安装包确保环境里Docker和Compose版本符合要求。我遇到过好几次迁移后起不来的情况最后定位是新环境的docker-compose版本太老不认新版compose文件里的字段比如deploy.resources或cap_add的写法。一个稳妥的检查docker --version docker compose versionHarbor 2.7及之后版本已经明确要求使用docker compose插件v2.x老式docker-compose二进制v1可能会直接报错。3.3 配置迁移harbor.yml怎么填这一步信息量最大。新版harbor.yml的核心字段要逐个对hostname: registry.example.com http: port: 80 https: port: 443 certificate: /data/cert/server.crt private_key: /data/cert/server.key harbor_admin_password: 新设置的密码 database: password: 数据库密码 max_idle_conns: 50 max_open_conns: 100 data_volume: /data几个容易忽略的项external_url如果之前是通过反向代理对外暴露的新版配置里可能需要显式给出完整地址否则生成的推送拉取指令里的URL不对。harbor_admin_password旧版是通过harbor.cfg里的配置初始化新版在第一次初始化时才生效。你迁移完数据库后admin的密码哈希是旧库里的但web界面登录走的是数据库所以配置项里写什么并不重要。database.password新环境的数据库密码必须与旧环境一致或者你在导出SQL时用新的密码重新建库否则core服务连不上数据库所有接口都会502。3.4 数据导入与新实例启动在新环境的安装目录下三步走# 1. 先运行一次prepare生成docker-compose.yml相关配置 ./install.sh --without-clair --without-notary # 按你的实际需求加参数 # 2. 启动前把备份的data覆盖到新data_volume rm -rf /data tar -xzf /backup/harbor_data_full.tar.gz -C /这里有个细节不要在Harbor已经初始化并启动过的环境里覆盖/data。因为首次启动会写入初始化的数据库文件和secret目录你再覆盖新写入的数据库文件和旧文件混在一起容易炸。干净的做法是新环境安装完但没跑过install.sh先把/data恢复过去再跑install.sh或docker compose up -d。如果已经跑过一次了那就要把之前的容器彻底删除并清掉volume再进入恢复流程docker compose down -v rm -rf /data tar -xzf /backup/harbor_data_full.tar.gz -C / docker compose up -d3.5 启动后的验证动作启动只是开始最重要的一步是验证。我每次迁移完会做以下几件固定动作浏览器登录admin确认能进UI。查看项目列表、镜像仓库列表数量和旧环境对比。找个测试镜像分别使用docker pull和docker push各一次确认推送后tag列表正常。检查replication规则是否存在jobservice日志里有没有报错。检查垃圾回收策略、配额策略、机器人账号列表。用旧版客户端比如用旧版本docker引擎的机器尝试拉取一次镜像确认协议无兼容问题。只要前面几项有一项不对别急着对外切换流量先排查清楚再说。4. 常见报错和排查实录4.1 启动后core容器反复重启这个太常见了。最常见的原因就是数据库连接失败。先看日志docker compose logs core | tail -200如果日志里出现类似“failed to connect database”或“dial tcp ... connection refused”优先检查harbor.yml里的database.password是否与迁移后的库一致。我踩过一次新旧环境的数据库密码确实设置得一样但是prepare生成的环境变量文件/opt/harbor/common/config/core/env里数据库地址还写成了旧容器的内部名新环境里容器名不同导致连不上。解决方法是重新跑prepare而不是手动改env。4.2 镜像列表正常但docker push报权限错误迁移后UI里看项目都在tag也在但客户端一push老是401或403。这个大概率是新旧版本加密密钥不一致。Harbor保存机器人账号和拉取凭证时部分敏感数据会用/data/secret里的密钥做加密如果你只迁移了数据库secret目录是新的解密时就失败了。遇到这个直接把旧环境的/data/secret整个覆盖回去重新prepare并起容器。4.3 数据库迁移后出现“manifest digest mismatch”或者tag缺失这属于数据库和registry存储不一致的典型症状。最常见原因是备份时没停容器数据库备份时刻和registry目录备份时刻不一致。也有一种情况跨大版本时旧数据库里用digest方式记录的manifest新版本需要重新做垃圾回收或迁移脚本才能正确build出tag列表。遇到这种可以尝试先重新同步一次replication如果源仓库还能访问或者用本地工具将缺失的tag重新、打标签推送。如果源仓库已经不能访问只能接受损失手动从manifest数据里恢复tag。这也是为什么迁移前备份后不建议再让业务侧推送新镜像的另一个原因。4.4 prepare时报错“the secret key is too short”这个是在手动改过/data/secret目录后容易出现的。旧版本可能没生成过某个secret文件或者长度不满足新版要求。处理思路有两种一是补全缺失文件并重新生成随机密钥但这样会导致原有加密数据解不开二是把旧环境的/data/secret完整恢复不要只拷一部分。所以如果真的要把旧环境的secret带过来就整个目录覆盖别怕覆盖后配置丢失这个目录本身就是Harbor用来做持久化加密的。4.5 从1.x迁移后镜像仓库列表一直为空先区分是项目列表正常但仓库列表为空还是项目都看不到。如果是前者主要查数据库里registry的repository表是否有数据。有可能是迁移时只导了Harbor元数据库但registry的meta数据没同步。有个技巧旧版Harbor的registry数据库里repository相关的记录在表“registry.repositories”里新版已经把这部分纳入主库统一管理。如果结构不同手动导入时要把旧库里的repository、tag、manifest_blob关系全部导出。这也是为什么我更推荐用官方迁移工具处理1.x到2.x的跨越它内部会处理这些表结构的迁移。5. 一些实操心得和避坑建议5.1 迁移窗口怎么选这类迁移不是“想干就干”的事。尽量选业务低峰期而且至少预留一个完整的回滚方案。我的习惯是提前一周在测试环境做一次“排练迁移”数据用生产备份走全套流程量好总耗时。真正迁移时先在信封窗口前做最后一次增量备份至少包括数据库逻辑备份和/data整体快照。迁移完成后保留旧环境至少两周不要急着销毁。原因很简单等业务侧验证完所有外部集成CI/CD流水线、镜像扫描、复制规则都正常后再清理旧的才放心。5.2 官方迁移工具怎么用Harbor官方从1.7开始提供迁移工具放在官方二进制包中。使用上大概是这样./harbor-migrator --cfg旧版harbor.yml --from-version 1.10 --to-version 2.0它主要干两件事一是迁移配置文件二是升级数据库schema。实际用下来它在1.x到2.x这个场景里确实省事不少但有个前提——它要求旧环境容器是停止状态而且它迁移的是配置文件和新格式数据库。如果你在它运行后又手动改了数据库操作顺序上的小失误可能引起后续问题。我的建议把它当成“半自动”工具跑完以后一定要人工验证配置项不要盲目信任它生成的harbor.yml。5.3 关于升级后的配额和垃圾回收老版本里的配额可能应用在一些历史数据上跨版本升级后配额统计的维度和算法有调整可能出现“明明设置了项目配额但仓库已经超了”的情况。遇到这个去“项目→配置→配额”里重新编辑一次保存即可。垃圾回收策略同理旧策略迁移后有时候不会自动触发建议到“管理→垃圾回收”里看下策略和状态有需要就重建。5.4 一个小技巧迁移前先备份Notary和Chartmuseum的数据很多人以为Harbor就是镜像仓库忽略了如果有开启Notary镜像签名和ChartmuseumHelm Chart仓库它们是独立的数据组件。一旦漏迁最直观的影响是旧Helm Chart全没了但UI里还显示着Chart列表点进去却是空的。多花一分钟检查下/data目录下有没有notary、chartmuseum相关子目录打包备份时不要把它们排除掉。如果没有这些组件这步跳过就好。最后再分享一个我自己的小习惯每完成一次迁移我会把旧的/data目录打包后放在冷存储里并写一个文本记录里旧版本号、新版本号、迁移日期、以及迁移后做过的验证项。下次再迁移或者排查奇怪问题时这些记录比任何文档都好使。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑