
Harbor 备份与恢复实战深入解析 contrib/backup-restore 脚本集【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harborHarbor 作为云原生制品仓库其数据PostgreSQL 数据库、镜像 Registry 存储、密钥与配置的可用性直接关系到生产环境的可靠性。本文以官方仓库中 contrib/backup-restore/ 目录下提供的harbor-backup与harbor-restore两个脚本为主体完整讲解它们的安装、参数、备份/恢复流程与底层实现原理并结合源码剖析其数据布局、rsync 增量策略与容错机制。读完本文你将能够独立完成 Harbor 实例的停机备份、灾难恢复以及向备用节点同步备份的完整操作。脚本概览备份范围与设计特点这两个脚本harbor-backup与harbor-restore位于仓库 contrib/backup-restore/ 目录用于对 Harbor 实例进行整体备份与恢复。根据 README.md 的说明备份覆盖以下六个组成部分Harbor 数据库PostgreSQL通过pg_dump导出所有非模板数据库为 SQL 文件容器镜像仓库数据Registry即/data/registry目录下的镜像存储Chart Museum 数据若启用即/data/chart_storage目录Redis 数据若启用即/data/redis目录密钥文件Secret Keys位于/data/secret目录Harbor 配置即/etc/harbor/harbor.yml配置文件。与 Harbor 项目早期仓库中附带的脚本相比这一套脚本在错误处理上更加健壮全程set -euo pipefail任意命令失败、未定义变量或管道失败都会立即终止并且提供了不打 tarball 包的选项--no-archive使备份保持为普通目录结构从而可以方便地用rsync将整个备份目录同步到备用/灾备节点并在其上恢复。脚本在多次备份之间保留备份目录中的既有文件利用rsync的增量特性显著缩短备份停机窗口代价是占用更多磁盘空间。此外脚本支持将状态日志直接写入syslogfacility 为local0便于与既有日志采集体系集成。需要特别说明的是这两个脚本位于contrib目录并非 Harbor 官方正式维护与支持README 明确警告按原样提供、自行承担风险在生产环境执行前务必充分理解其行为。前置条件在运行脚本前请确认以下条件Docker CLI 可用脚本完全依赖docker命令行与 Harbor 的容器交互如docker exec、docker run需确保机器上已安装 Docker 且docker命令在PATH中足够权限需要有执行 Docker 命令及文件系统操作的权限例如sudo或已加入docker用户组且能读写/data下的数据目录Harbor 实例必须处于停止状态无论是备份还是恢复都必须在 Harbor 完全停止后再运行脚本否则会产生数据不一致。脚本源码中也做了强制校验——launch_db()会先检查docker ps -q若存在任何运行中的容器将直接以CRITICAL级别报错退出。使用harbor-backup执行备份1. 获取脚本并赋予执行权限将 harbor-backup 放置到可从 Harbor 实例访问的位置仓库内通常位于contrib/backup-restore/然后赋予执行权限chmod x harbor-backup2. 停止 Harbor确保 Harbor 实例已完全停止例如docker-compose down或./install.sh对应的停止方式后再执行备份。3. 运行备份脚本./harbor-backup [OPTIONS]4. 参数说明harbor-backup支持以下命令行选项默认值与脚本源码 harbor-backup 中的变量定义一致选项作用默认值--docker-cmd command指定使用的 Docker 命令docker--db-image image指定用于临时备份容器的 Harbor 数据库镜像自动检测goharbor/harbor-db最新 tag--db-path pathHarbor 数据库数据路径/data/database--registry-path pathRegistry 数据路径/data/registry--chart-museum-path pathChart Museum 数据路径/data/chart_storage--redis-path pathRedis 数据路径/data/redis--secret-path path密钥数据路径/data/secret--config-path pathHarbor 配置文件路径/etc/harbor/harbor.yml--backup-dir path备份存放目录harbor_backup--no-archive不打包tar.gz备份保留为$BACKUP_DIR/harbor目录结构默认关闭即默认打包--use-syslog日志输出到 syslog默认关闭--log-level level日志级别INFO可选DEBUG、INFO、NOTICE、WARNING、ERROR、CRITICAL、ALERT、EMERGENCY--help显示帮助信息—关于数据库镜像脚本默认通过docker images goharbor/harbor-db --format {{.Repository}}:{{.Tag}} | head -1自动检测本机已拉取的 harbor-db 镜像README 建议在生产环境显式传入特定 tag如--db-image goharbor/harbor-db:v2.x.x以保证备份与恢复两端的一致性。5. 备份产物默认情况下备份会生成在当前工作目录的harbor_backup目录中若不使用--no-archive最终产物为harbor_backup/harbor_backup.tar.gz压缩包内部是harbor目录树若使用--no-archive备份保持为harbor_backup/harbor目录结构可直接对harbor_backup整体执行rsync同步到备用节点。6. 备份流程源码级解析从 harbor-backup 的main部分可以看出备份依次执行以下步骤创建备份目录结构create_backup_dirL311-L337在$BACKUP_DIR/harbor下创建db、registry、chart_storage、redis、secret子目录并设置正确属主与权限——其中db目录被chown为 PostgreSQL 用户999:999且chmod 700secret目录同样chmod 700其余目录chmod 755。若上次备份的db目录存在会先删除避免旧 SQL 残留混入新备份注册清理陷阱trap clean_db EXIT ERR INT TERM保证无论正常结束还是出错中断临时数据库容器都会被停止并删除启动临时数据库容器launch_dbL165-L173docker run -d --name harbor-db -v ${BACKUP_DIR}:/backup -v ${HARBOR_DB_PATH}:/var/lib/postgresql/data ${HARBOR_DB_IMAGE} postgres将备份目录挂载到容器内/backup将 Harbor 数据库数据目录挂载到/var/lib/postgresql/data等待数据库就绪wait_for_db_readyL176-L192循环执行pg_isready检查是否返回accepting connections最多等待 12 次 × 5 秒约 1 分钟超时则以CRITICAL退出导出全部数据库dump_databaseL195-L216通过psql -t -c SELECT datname FROM pg_database WHERE datistemplate false;列出所有非模板数据库逐个执行pg_dump -U postgres ${db}输出到$BACKUP_DIR/harbor/db/${db}.sql。脚本通过捕获Exit: N错误码判断 dump 是否失败失败即以ERROR级别退出备份各数据目录backup_registry、backup_chart_museum、backup_redis、backup_secret、backup_config依次执行。除配置为cp拷贝外其余全部采用rsync -a --delete增量同步--delete会删除目标端多余文件保证备份目录与源目录一致。Chart Museum 与 Redis 仅在对应源目录存在时才备份其中 Chart Museum 被脚本标注为 Deprecated feature已弃用功能密钥备份对 1.8 之前的老版本secretkey、defaultalias文件与 1.8 及以后版本目录整体 rsync做了兼容处理打包归档create_tarballL300-L309除非指定--no-archive否则执行tar -czvf --remove-files harbor_backup.tar.gz harbor生成压缩包并移除中间目录。使用harbor-restore执行恢复1. 获取脚本并赋予执行权限将 harbor-restore 放置到合适位置chmod x harbor-restore2. 停止 Harbor同样必须先完全停止 Harbor 实例。3. 运行恢复脚本./harbor-restore [OPTIONS]4. 参数说明恢复脚本的参数与备份脚本基本一致--docker-cmd、--db-image、--db-path、--registry-path、--chart-museum-path、--redis-path、--secret-path、--config-path、--use-syslog、--log-level重点差异在于以下两个参数--backup-dir path必须指向存放 Harbor 备份的目录——若是从 tarball 解压出来的指向包含harbor子目录的目录默认即harbor_backup若使用了--no-archive同样指向包含harbor子目录的harbor_backup目录--no-archive当备份已经解压为$BACKUP_DIR/harbor目录结构时使用如果备份是tar.gz文件则不要使用该选项脚本会自动解压。5. 恢复流程源码级解析从 harbor-restore 的main部分可以看出恢复依次执行以下步骤准备备份目录若$BACKUP_DIR不存在则自动创建以容纳解压出的备份注册清理陷阱与备份脚本相同trap clean_db EXIT ERR INT TERM启动临时数据库容器launch_dbL182-L190与备份不同这里将$BACKUP_DIR/harbor/db存放 SQL 备份的目录挂载到容器内/backup数据目录仍挂载到/var/lib/postgresql/data解压备份包extract_tarballL277-L294默认情况下若存在$BACKUP_DIR/harbor_backup.tar.gz则解压若已存在harbor目录先删除若指定--no-archive则跳过解压若既指定解压模式又找不到 tarball则报错退出恢复数据库restore_databaseL193-L206遍历$BACKUP_DIR/harbor/db/*.sql文件对每个数据库依次执行drop database、create database然后通过psql -d ${db} ${dump_file}导入 SQL——即先删除重建再灌入备份数据恢复各数据目录restore_registry、restore_chart_museum、restore_redis、restore_secret均以rsync -a --delete将备份目录反向同步回对应数据目录若对应备份子目录不存在则跳过并给出提示恢复配置文件restore_configL260-L267将备份中的harbor.yml拷贝回/etc/harbor/harbor.yml清理临时容器clean_db执行docker stop harbor-db docker rm harbor-db。6. 重启 Harbor恢复脚本成功完成后即可重新启动 Harbor 实例。从源码看实现要点日志系统syslog 兼容的分级日志两个脚本共用同一套日志实现harbor-backup 与 harbor-restore 几乎一致定义LOG_LEVELS关联数组将DEBUG~EMERGENCY映射为 syslog 兼容的 7~0 数值数值越小优先级越高log函数为每条消息加上[时间戳] [级别]前缀输出到 stderr若启用--use-syslog则通过logger -t harbor-backup -p local0.${level,,}将消息写入 syslogfacility 为local0tag 区分harbor-backup与harbor-restore消息级别低于阈值时直接丢弃实现按--log-level过滤。一致性保证与安全措施两个脚本都在顶部启用set -euo pipefail任何命令失败都会立即终止并触发trap清理避免残留容器污染后续运行launch_db前置校验不允许存在任何运行中的容器从机制上防止在 Harbor 运行期间误操作导致数据损坏权限处理上数据库备份目录强制为 PostgreSQL 属主999:999且700权限确保容器内 postgres 进程可读写secret 目录同样700其余数据目录755。与 Harbor 默认数据布局的对应关系脚本的默认路径与 Harbor 官方部署模板完全吻合。在 harbor.yml.tmpl 中默认数据卷为data_volume: /data由make prepare生成 docker-compose 时docker-compose.yml.jinja 将 registry 数据挂载为{{data_volume}}/registry:/storage、数据库挂载为{{data_volume}}/database:/var/lib/postgresql/data并在 core 容器中挂载{{data_volume}}/secret/core/private_key.pem与{{data_volume}}/secret/keys/secretkey等密钥文件——这正是脚本默认路径/data/database、/data/registry、/data/secret、/data/redis、/data/chart_storage的由来。如果你的部署自定义了data_volume或使用外部存储必须通过--db-path等参数显式指定实际路径README 的 Custom Deployments 一节亦强调这一点。密钥兼容性说明密钥备份逻辑harbor-backup区分了两个时代Harbor 1.8 之前版本使用secretkey/defaultalias文件脚本通过basename构造旧路径探测1.8 及以后版本密钥统一存放在$SECRET_PATH目录下整体 rsync。恢复端则统一从$BACKUP_DIR/harbor/secret同步回$SECRET_PATH因此跨版本恢复时需确认密钥布局兼容性。重要注意事项与最佳实践一致性优先为保证备份一致性建议备份期间停止 Harbor 实例或至少保证写入活动最小化README 明确要求完全停止锁定数据库镜像 tag生产环境务必为--db-image指定与当前 Harbor 版本匹配的具体 tag避免自动检测到不一致的镜像导致备份/恢复行为漂移自定义部署必须显式传参数据存放在非默认位置的定制化部署必须使用对应选项指定正确路径否则脚本会备份到错误位置或恢复失败先在测试环境演练将备份与恢复完整流程在非生产环境演练通过后再依赖它保护关键数据善用--no-archive做灾备同步不打包模式下可定期对harbor_backup目录执行rsync -a --delete增量同步到备用节点备用节点再以--no-archive执行恢复即可实现准实时的异机灾备留意已弃用功能Chart MuseumHelm Chart 存储已被脚本标注为 Deprecated若你的版本已迁移到 OCI 制品存储该目录可能不存在脚本会自动跳过属正常现象官方支持边界这两个脚本位于 contrib/backup-restore/README 声明其按原样提供、未被 Harbor 项目官方维护或支持使用风险自担。若发现问题或希望改进社区欢迎向contrib/backup-restore/目录提交 Pull Request见 README 的 Contributing 一节。总结harbor-backup与harbor-restore以简洁的 Bash 脚本封装了 Harbor 全部关键数据PostgreSQL、Registry、Chart Museum、Redis、密钥与配置的备份与恢复能力备份端基于临时数据库容器完成pg_dump逻辑导出数据目录采用rsync -a --delete增量同步恢复端按解压 → 重建数据库 → 灌入 SQL → 反向 rsync 数据目录 → 回填配置的顺序还原整站。借助--no-archive模式与增量 rsync你可以在较小停机窗口内持续维护一份可异地恢复的完整备份。理解其源码实现与 Harbor 默认数据布局的对应关系是安全使用这套脚本的前提。【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考