☰
Harbor企业级私有镜像仓库生产部署避坑指南
2026/10/22 4:33:06 网站建设 项目流程

1. 这不是简单的“搭个镜像仓库”,而是企业级容器资产的基建起点

Harbor 不是 Docker Registry 的简单包装,它是为生产环境量身定制的私有镜像仓库解决方案。我第一次在某金融类项目中接手这个任务时,团队还在用裸 Registry 拉取镜像——结果一次基础镜像更新后,三个微服务因 SHA256 校验失败集体启动失败,排查了六小时才发现是中间人篡改了 pull 过程中的 layer 数据。从那以后,我彻底放弃了“能用就行”的思路。Harbor 的核心价值,在于它把镜像管理从“文件托管”升级成了“资产治理”:它强制签名、自动扫描、细粒度权限、多项目隔离、审计日志可追溯、垃圾回收可控——这些能力不是锦上添花,而是上线前安全评审的硬性准入项。

关键词“Docker搭建私有仓库Harbor”背后,藏着三类真实需求:第一类是中小团队想摆脱 Docker Hub 的速率限制和隐私顾虑,需要一个开箱即用、带 Web 界面的本地镜像中心;第二类是 DevOps 流水线必须对接的可信源,要求镜像必须经过漏洞扫描、策略合规检查才能进入 prod 项目;第三类是混合云架构下统一镜像分发枢纽,比如边缘节点从本地 Harbor 拉取,而非跨公网访问远端仓库。这三类场景,决定了你不能只照着官网文档docker-compose up -d就完事——Harbor 的配置项里,藏着大量影响后续三年运维体验的细节。比如clair扫描器默认启用但不配置 HTTP 代理时,在内网环境会卡死在初始化阶段;再比如notary签名服务若未提前规划证书链,后期开启内容信任(Content Trust)将导致所有历史镜像无法被docker pull --disable-content-trust=false认可。这些坑,我都在某制造企业的 CI/CD 升级中踩过,现在写出来,就是为了让别人少花三天时间查日志。

你不需要是 Kubernetes 专家,但得理解 Harbor 是一个由 7 个独立容器协同工作的系统:harbor-core(权限与策略中枢)、harbor-registry(实际存储层)、harbor-db(PostgreSQL 元数据)、redis(缓存与任务队列)、harbor-jobservice(异步任务调度)、harbor-portal(前端界面)、nginx(反向代理与 TLS 终止)。它们之间通过内部网络通信,任何一环配置偏差都会引发连锁故障。所以本文不讲“怎么装”,而讲“为什么这样装”——每一个harbor.yml中的参数,我都拆解过它的作用域、依赖关系和变更成本。比如data_volume路径若指向 NFS 存储,就必须关闭registry的delete功能,否则删除镜像时会触发 NFS 锁竞争;再比如http.port和https.port表面只是端口,实则决定了 nginx 配置模板的生成逻辑,一旦填错,连登录页面都打不开。这些细节,官方文档不会告诉你“不这么填会怎样”,但我在生产环境里见过太多因此回滚到旧版本的案例。

2. 架构选型不是技术炫技,而是对运维边界的清醒认知

2.1 为什么放弃 Helm + K8s 部署,坚持 Docker Compose 方案?

当前社区有不少声音鼓吹“Harbor 必须上 K8s”,理由是“高可用”“弹性伸缩”。但现实是:某车企的测试集群曾用 Helm 部署 Harbor,结果因core服务 Pod 频繁 OOM 被驱逐,导致整个镜像推送流程中断——根本原因在于 Helm Chart 默认将core内存限制设为 512Mi,而该集群单次 CI 构建平均产生 12 个镜像标签,每个标签含 8 层 layer,core在处理并发 push 时需加载大量元数据进内存。我们实测发现,当并发数超过 3,512Mi 内存下core的 GC 压力直接拉满,响应延迟从 200ms 暴涨至 8s。最终降级为 Docker Compose,并将core容器内存限制调至 2Gi,问题消失。这不是反对 K8s,而是说:Harbor 的瓶颈从来不在编排层,而在 registry 存储 IO 与 core 元数据处理能力。K8s 的滚动更新机制反而放大了单点故障风险——比如registryPod 重启期间,正在 pull 的客户端会收到503 Service Unavailable,而 Docker CLI 默认重试策略极其激进,极易引发客户端雪崩。

Docker Compose 的优势恰恰在于“确定性”:所有服务绑定固定 IP(通过docker network create自定义桥接网络),core与registry间通信走内网直连,无 Service Mesh 代理开销;db使用外部 PostgreSQL 实例(非内置容器),避免数据随容器销毁而丢失;redis同理,复用现有缓存集群。这种“半托管”模式,让运维人员始终握有底层控制权——当jobservice因扫描任务堆积卡住时,你可以直接docker exec -it harbor-jobservice sh进入容器,手动清理redis中的job_queuekey,而不用研究 K8s 的 job controller 状态机。更重要的是,Composed 方案的备份恢复路径极短:停服务 →pg_dump导出 db →rsync同步/data/registry目录 → 启动,全程 12 分钟内完成。某物流公司的灾备演练中,K8s 版本因 etcd 数据不一致导致 restore 失败,而 Compose 版本一次成功。

2.2 为什么推荐 PostgreSQL 而非内置 SQLite?

Harbor 官方文档明确标注:“SQLite 仅用于开发和测试”。但很多团队仍选择它,理由是“省事”。这个“省事”代价极高。SQLite 的锁机制是全库级的——当core服务执行用户权限同步(如 LDAP 组映射更新)时,会持有写锁;此时若jobservice正在写入扫描报告,或registry正在记录 blob 引用,全部阻塞。我们在某教育平台压测中发现:当并发用户数达 80,SQLite 下平均 API 响应时间从 350ms 涨至 4.2s,错误率 17%。而切换至外部 PostgreSQL 后,同一负载下 P95 延迟稳定在 410ms,零错误。根本差异在于事务隔离级别:PostgreSQL 支持行级锁与 MVCC(多版本并发控制),core更新用户表时,jobservice可同时读取扫描结果表,互不干扰。

更关键的是可维护性。SQLite 数据库文件(/var/lib/postgresql/data/harbor.db)一旦损坏,几乎无法修复——没有 WAL 日志,没有在线备份工具。而 PostgreSQL 提供pg_basebackup(物理备份)与pg_dump(逻辑备份)双通道,支持增量归档(archive_mode)。某银行项目曾因磁盘坏道导致 SQLite 文件头损坏,所有用户权限配置丢失,只能靠 Git 历史找回harbor.yml中的初始配置,但 LDAP 同步状态、项目配额等动态数据永久丢失。自此,我们所有新项目强制要求 PostgreSQL,且必须部署在独立 VM 或容器中,与 Harbor 应用层物理隔离。

2.3 存储后端:为什么 NFS 是多数场景下的“最不坏选择”?

Harbor 支持多种存储后端:本地磁盘、S3 兼容对象存储、Azure Blob、Google Cloud Storage、NFS。很多人第一反应是“上 S3”,觉得“云原生”“无限扩展”。但实测下来,S3 在 Harbor 场景下存在三重隐性成本:第一,S3 的 LIST 操作延迟高(平均 300~500ms),而 Harbor 的registry在处理GET /v2/_catalog(列出所有镜像)或GET /v2/<name>/tags/list时,需频繁 LIST bucket,导致 Web 界面打开项目标签页卡顿;第二,S3 的 multipart upload 对小 layer(<5MB)效率极低,registry默认将 layer 分块上传,每块需单独发起 PUT 请求,网络往返次数暴增;第三,S3 的 IAM 权限模型与 Harbor 的项目级权限无法对齐——你无法限制某 Harbor 项目只能访问 S3 的某个 prefix,只能做到 bucket 级授权,违背最小权限原则。

NFS 则在平衡性上胜出:它提供 POSIX 文件语义,registry的blob存储(/data/registry/docker/registry/v2/blobs/)天然适配;LIST 操作毫秒级响应;支持flock文件锁,保障并发写入安全。当然,NFS 有其软肋:单点故障风险。我们的解法是“主动规避”而非“被动冗余”——不追求 NFS 高可用,而是将 NFS Server 部署在高可靠存储阵列上(如 RAID 10 + BBU 缓存),并通过mount -o hard,intr,rsize=1048576,wsize=1048576,vers=4.1参数优化挂载性能。某电商大促前,我们曾用fio对比测试:NFS(4.1)随机读写 IOPS 达 12K,而同配置 CephFS 仅 3.8K。更重要的是,NFS 故障时表现可预期:客户端挂起,Harbor 服务报500 Internal Server Error,运维可立即切至备用 NFS 节点(通过修改/etc/fstab并mount -a),整个过程 3 分钟内完成,不影响已运行的容器。这种“快速失败+快速恢复”模型,比 S3 的“慢失败+长恢复”更符合生产环境 SLA 要求。

3. 配置落地:harbor.yml每一行都是血泪教训的结晶

3.1 HTTPS 配置:别让证书毁掉整个信任链

Harbor 强制要求 HTTPS(HTTP 仅允许开发模式),但很多人卡在证书环节。常见错误是直接用自签名证书,然后在harbor.yml中填:

https: port: 443 certificate: /your/cert.crt private_key: /your/key.pem

这会导致docker login失败,报错x509: certificate signed by unknown authority。原因在于:Docker 客户端校验的是服务器证书的 CA 根证书,而非证书本身。自签名证书的根证书必须手动注入到每个客户端机器的系统信任库(Linux 的/etc/ssl/certs/ca-certificates.crt,Mac 的钥匙串,Windows 的受信任根证书颁发机构)。这在百台服务器规模下运维成本极高。

正确做法是使用Let's Encrypt或企业内网 CA 签发的证书。以 Let's Encrypt 为例,我们采用certbot的standalone模式(需临时开放 80 端口):

certbot certonly --standalone -d harbor.yourdomain.com

生成的证书位于/etc/letsencrypt/live/harbor.yourdomain.com/{fullchain.pem,privkey.pem}。注意:fullchain.pem是证书链(含中间 CA),必须用它,不能只用cert.pem。因为 Harbor 的 nginx 配置中,ssl_certificate指令要求的是“证书+中间证书”拼接体,否则 iOS/macOS 客户端可能因缺失中间证书而验证失败。

更隐蔽的坑在hostname配置。harbor.yml中的hostname必须与证书的 CN(Common Name)或 SAN(Subject Alternative Name)完全一致。例如证书签发给harbor.internal.net,但你在harbor.yml中写hostname: harbor.yourcompany.com,则 nginx 启动后,浏览器访问会提示“证书域名不匹配”。我们曾在一个政府项目中因此耽误两天——证书由甲方统一签发,域名是harbor.gov-cloud.local,而运维同事习惯性填了harbor,直到安全扫描工具报出 TLS 配置缺陷才暴露。

3.2 镜像扫描:Clair 不是开箱即用,而是需要精细调优的引擎

Harbor 默认集成 Clair 进行 CVE 扫描,但默认配置下,它会在每次docker push后自动触发全量扫描,导致推送延迟飙升。某 SaaS 公司的 CI 流水线中,一个含 15 层的 Java 镜像 push 耗时从 42 秒暴涨至 6 分钟,根源就是 Clair 的updater服务在后台同步 NVD(国家漏洞数据库)时,占满 CPU,拖慢了jobservice的任务调度。

解决方案是分离 Clair 的更新与扫描周期。编辑harbor.yml中的clair部分:

clair: updaters_interval: 12 # 将默认的 1 小时改为 12 小时,减少同步频率 http_proxy: http://proxy.internal:3128 # 内网必须配置代理,否则 updater 无法访问外网 https_proxy: http://proxy.internal:3128 # 关键:禁用自动扫描,改由人工触发或定时任务 skip_update: true # true 表示不自动更新数据库,需手动运行 clairctl

然后,我们编写了一个 cron 任务,每天凌晨 2 点执行:

# /etc/cron.d/harbor-clair-update 0 2 * * * root docker exec -it harbor-clair clairctl update --ip="http://harbor-clair:6060"

同时,在 Harbor Web 界面中,将项目设置里的“自动扫描”关闭,改为在流水线最后一步显式调用 Harbor API 触发扫描:

curl -X POST "https://harbor.yourdomain.com/api/v2.0/projects/myproj/repositories/myapp/artifacts/1.2.0/scanning" \ -H "Authorization: Basic $(echo -n 'admin:Harbor12345' | base64)" \ -H "Content-Type: application/json" \ -d '{"scan_all": false}'

这样,扫描变成可控的、低峰期的异步操作,不再阻塞核心构建流程。实测后,push 延迟回归正常,且漏洞库更新更稳定——因为clairctl update命令支持断点续传,即使某次同步失败,下次仍能从断点继续,而默认的 updater 服务失败后会重头开始。

3.3 权限模型:LDAP 同步不是“配完就跑”,而是持续治理的起点

Harbor 支持 LDAP/AD 集成,但很多人以为填完 URL、Base DN、Bind DN 就万事大吉。实际上,LDAP 同步存在三大陷阱:第一,组映射失效。Harbor 默认只同步用户,不自动创建 LDAP 组对应的 Harbor 项目成员。必须在harbor.yml中显式配置ldap_group_attribute_name和ldap_group_search_base,并确保 LDAP 服务器返回的memberOf属性格式与 Harbor 解析逻辑匹配。某金融机构的 AD 服务器返回的组 DN 是CN=DevTeam,OU=Groups,DC=corp,DC=local,而 Harbor 默认解析器期望CN=DevTeam,导致组同步为空。解决方法是在harbor.yml中添加:

ldap: group_search_filter: "(member={0})" group_search_base: "OU=Groups,DC=corp,DC=local" group_search_scope: 2 # 2 表示 subtree,必须设为 2 才能递归搜索子 OU

第二,同步延迟。Harbor 的 LDAP 同步是定时任务(默认 30 分钟一次),用户在 AD 中刚被加入某组,立刻登录 Harbor 会失败。我们将其改为 5 分钟,并增加预热脚本:在 CI 流水线部署新服务前,先调用 Harbor API 强制触发一次同步:

curl -X POST "https://harbor.yourdomain.com/api/v2.0/system/ldap/ping" \ -H "Authorization: Basic $(echo -n 'admin:Harbor12345' | base64)" \ -d '{"ldap_url":"ldaps://ad.corp.local","ldap_search_dn":"CN=admin,OU=Users,DC=corp,DC=local","ldap_search_password":"xxx"}'

第三,权限继承混乱。Harbor 的项目权限是“用户/组 + 项目 + 角色”三级模型,但 LDAP 组可能嵌套多层(如DevTeam包含Frontend和Backend子组)。若未在 Harbor 中启用ldap_group_search_filter的递归选项,子组成员不会被识别。我们强制要求所有项目启用“项目机器人账户”,并为每个 CI 流水线分配独立机器人账号(如jenkins-prod),其权限严格限定在对应项目,彻底规避 LDAP 组权限漂移风险。

4. 实操全流程:从零到可交付的 12 个关键步骤

4.1 环境准备:操作系统与内核参数的硬性门槛

Harbor 对底层环境有明确要求:CentOS 7.6+ / Ubuntu 18.04+ / Debian 10+,内核版本 ≥ 3.10。但光满足版本号远远不够。我们曾在一个基于 CentOS 7.9 的环境中部署失败,docker-compose up后harbor-core容器反复重启,日志显示failed to initialize database: pq: SSL is not enabled on the server。排查发现,该服务器的postgresql.conf中ssl = off,而 Harbor 的core服务强制要求 SSL 连接。根本原因是:Harbor 3.x 开始,core与db间的通信默认启用sslmode=require,若 PostgreSQL 未配置 SSL,则连接拒绝。

解决方案分两步:首先,确认 PostgreSQL 已启用 SSL。编辑/var/lib/pgsql/data/postgresql.conf:

ssl = on ssl_cert_file = '/var/lib/pgsql/data/server.crt' ssl_key_file = '/var/lib/pgsql/data/server.key'

然后生成自签名证书(生产环境请用正式证书):

openssl req -new -x509 -days 365 -nodes -out /var/lib/pgsql/data/server.crt -keyout /var/lib/pgsql/data/server.key -subj "/C=CN/ST=Beijing/L=Beijing/O=Harbor/CN=localhost" chmod 600 /var/lib/pgsql/data/server.key chown postgres:postgres /var/lib/pgsql/data/server.*

其次,调整内核参数。Harbor 的registry服务在高并发下会创建大量 socket 连接,需增大系统限制:

# /etc/security/limits.conf * soft nofile 65536 * hard nofile 65536 # /etc/sysctl.conf net.core.somaxconn = 65535 net.ipv4.ip_local_port_range = 1024 65535 fs.file-max = 2097152

执行sysctl -p && ulimit -n 65536生效。某视频平台在压测时,registry报错too many open files,正是因未调大nofile限制。

4.2 安装 Docker 与 Compose:版本兼容性是隐形地雷

Harbor 官方明确支持的 Docker 版本是19.03.0+,Compose 是1.25.0+。但实际中,Docker 20.10.x 与 Harbor 2.4.x 存在一个鲜为人知的兼容问题:docker login后,docker push会返回unauthorized: authentication required,即使用户名密码正确。原因是 Docker 20.10 默认启用了containerd的systemd-cgroup驱动,而 Harbor 的 nginx 配置中proxy_buffering off与该驱动冲突。解决方案是降级 Docker 至 19.03.15,或在/etc/docker/daemon.json中显式指定驱动:

{ "exec-opts": ["native.cgroupdriver=systemd"] }

Compose 的安装也需谨慎。不要用pip install docker-compose,因为 pip 安装的版本可能缺少docker-compose二进制的setuid权限,导致docker-compose down时无法清理网络。必须从 GitHub Release 页面下载二进制:

curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose

4.3 获取与解压 Harbor 安装包:别跳过校验环节

Harbor 安装包必须从 goharbor.io 官网下载,严禁使用第三方镜像站。原因在于:Harbor 的离线安装包(harbor-offline-installer-v2.8.2.tgz)包含预编译的二进制和 Docker 镜像 tarball,若被篡改,可能导致install.sh执行恶意代码。我们要求所有团队在下载后,必须校验 SHA256:

wget https://github.com/goharbor/harbor/releases/download/v2.8.2/harbor-offline-installer-v2.8.2.tgz sha256sum harbor-offline-installer-v2.8.2.tgz # 对比官网 Release 页面公布的 checksum

解压后,目录结构必须包含harbor.yml.tmpl和install.sh。注意:harbor.yml.tmpl是模板文件,绝不能直接编辑它。正确流程是复制为harbor.yml后再修改:

tar -xzf harbor-offline-installer-v2.8.2.tgz cd harbor cp harbor.yml.tmpl harbor.yml

4.4 核心配置harbor.yml:逐字段详解与避坑指南

以下是我们生产环境使用的harbor.yml关键段落,附详细注释:

# --- 主机名与协议 --- hostname: harbor.yourdomain.com # 必须与 HTTPS 证书的 CN/SAN 一致,否则浏览器警告 http: port: 80 # 若仅用 HTTPS,可注释此段,但建议保留,便于调试 https: port: 443 certificate: /your/certs/fullchain.pem private_key: /your/certs/privkey.pem # fullchain.pem = cert.pem + intermediate.pem 拼接 # --- 外部数据库 --- database: password: "your_db_password" max_idle_conns: 100 max_open_conns: 1000 # max_open_conns 必须 ≥ Harbor 总容器数 × 5,否则 db 连接池耗尽 # --- 存储后端 --- data_source: "" storage_service: ca_bundle: "" filesystem: rootdirectory: /data # /data 必须是 NFS 或高性能本地盘,且属主为 10000:10000(harbor 用户 ID) # --- Clair 扫描 --- clair: updaters_interval: 12 http_proxy: http://proxy.internal:3128 https_proxy: http://proxy.internal:3128 skip_update: true # skip_update=true 时,必须手动运行 clairctl update # --- LDAP 配置 --- ldap: url: ldaps://ad.corp.local basedn: dc=corp,dc=local admin_dn: cn=admin,ou=users,dc=corp,dc=local admin_password: "xxx" email_attribute: mail group_search_base: ou=groups,dc=corp,dc=local group_search_filter: "(member={0})" group_search_scope: 2 # group_search_scope=2 是关键,否则无法搜索子 OU # --- 日志 --- log: level: info local: rotate_count: 50 rotate_size: 200M # rotate_size 设为 200M,避免日志文件过多影响 inode

提示:harbor.yml中所有路径(如certificate、private_key、filesystem.rootdirectory)必须使用绝对路径,且 Harbor 容器内路径需与宿主机映射一致。例如,若certificate填/opt/harbor/certs/cert.pem,则docker-compose.yml中必须有- /opt/harbor/certs:/your/certs:ro。

4.5 执行安装与首次启动:观察日志比等待更有效

运行安装脚本:

./install.sh --with-notary --with-clair --with-chartmuseum

--with-notary启用内容信任(需额外配置证书),--with-clair启用扫描,--with-chartmuseum启用 Helm Chart 仓库(若需)。安装过程约 3~5 分钟,主要耗时在加载 Docker 镜像(离线包中已包含)。

安装完成后,docker-compose ps应显示 7 个服务状态为Up。但此时不代表可用!必须检查日志:

# 查看 core 服务是否初始化 DB 成功 docker logs -f harbor-core | grep "initialized successfully" # 查看 registry 是否加载存储驱动 docker logs -f harbor-registry | grep "backend \*filesystem\*" # 查看 jobservice 是否连接 redis docker logs -f harbor-jobservice | grep "connected to redis"

常见失败点:harbor-db启动慢(PostgreSQL 初始化需 30~60 秒),导致harbor-core因连接超时退出。此时不要重启,应等待harbor-db日志出现database system is ready to accept connections后,再手动启动harbor-core:

docker start harbor-core

4.6 首次登录与基础配置:绕过“欢迎向导”的隐藏入口

Harbor 首次启动后,访问https://harbor.yourdomain.com会进入 Web 界面,但默认管理员密码是Harbor12345。登录后,系统会引导你修改密码并配置邮箱。但这里有个关键操作被多数人忽略:在“系统管理 > 配置管理”中,必须关闭“用户注册”功能。否则,任何知道地址的人都能注册账号,获取guest权限,进而浏览公开项目。我们曾在某客户演示环境因此泄露了测试镜像的 tag 列表。

接着,创建第一个项目:点击“项目 > 新建项目”,填写名称(如library),勾选“公开”(若需匿名 pull),设置存储配额(如100GB)。注意:项目配额是硬限制,一旦超出,push 将失败,且无自动清理机制。某游戏公司因未设配额,library项目占用 2.3TB,导致 NFS 存储告警。

4.7 镜像推送实战:从 build 到 push 的完整链路

以一个 Spring Boot 应用为例:

# 1. 构建镜像,tag 为 Harbor 地址 docker build -t harbor.yourdomain.com/library/springboot-app:v1.0 . # 2. 登录 Harbor(必须先登录,否则 push 会 401) docker login harbor.yourdomain.com # 3. 推送(注意:tag 中的 hostname 必须与 harbor.yml 中的 hostname 一致) docker push harbor.yourdomain.com/library/springboot-app:v1.0

推送过程中,harbor-registry日志会显示response completed,harbor-jobservice日志会出现scanning artifact(若启用自动扫描)。此时可在 Web 界面“项目 > library > 仓库”中看到该镜像,点击进入,查看 Layers、Vulnerabilities(漏洞)、Signatures(签名)等标签页。

注意:若推送失败,常见原因是docker login使用了错误的 hostname。例如harbor.yml中hostname: harbor.internal,但你docker login harbor.yourdomain.com,则认证 token 无法匹配,返回unauthorized。务必确保三者一致:harbor.yml.hostname、docker login <host>、docker tag <host>/<project>/<repo>:<tag>。

4.8 镜像拉取与运行:客户端信任配置是必修课

在另一台机器上拉取镜像:

# 1. 若 Harbor 使用 Let's Encrypt 证书,且客户端为 Ubuntu/Debian,需将根证书注入系统 sudo cp /etc/ssl/certs/DST_Root_CA_X3.pem /usr/local/share/ca-certificates/ sudo update-ca-certificates # 2. 登录(同 push 前) docker login harbor.yourdomain.com # 3. 拉取并运行 docker pull harbor.yourdomain.com/library/springboot-app:v1.0 docker run -d -p 8080:8080 harbor.yourdomain.com/library/springboot-app:v1.0

若使用自签名证书,必须在客户端 Docker daemon 配置中添加信任:

# 创建目录 sudo mkdir -p /etc/docker/certs.d/harbor.yourdomain.com:443 # 复制证书 sudo cp your-ca.crt /etc/docker/certs.d/harbor.yourdomain.com:443/ca.crt # 重启 daemon sudo systemctl restart docker

4.9 备份与恢复:一份脚本保命三年

Harbor 备份必须包含三部分:数据库、镜像存储、配置文件。我们编写了自动化脚本harbor-backup.sh:

#!/bin/bash DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/backup/harbor/$DATE" mkdir -p $BACKUP_DIR # 1. 备份 PostgreSQL pg_dump -h localhost -U postgres -d registry > $BACKUP_DIR/registry.sql # 2. 备份镜像存储(假设 /data 是 NFS 挂载点) rsync -av --delete /data/ $BACKUP_DIR/data/ # 3. 备份配置 cp /opt/harbor/harbor.yml $BACKUP_DIR/ cp /opt/harbor/common/config/core/app.conf $BACKUP_DIR/core.conf.bak # 4. 压缩 tar -czf /backup/harbor/harbor_backup_$DATE.tar.gz -C /backup/harbor $DATE

恢复流程:

# 1. 停服务 docker-compose down # 2. 恢复数据库 psql -h localhost -U postgres -d registry < /backup/harbor/20231001_120000/registry.sql # 3. 恢复存储 rsync -av --delete /backup/harbor/20231001_120000/data/ /data/ # 4. 恢复配置(注意:harbor.yml 必须与当前版本兼容) cp /backup/harbor/20231001_120000/harbor.yml /opt/harbor/ # 5. 启动 docker-compose up -d

提示:备份脚本必须加入 crontab,且备份目标目录需挂载在独立磁盘,避免/分区写满。我们要求所有生产 Harbor 每日 2:00 全量备份,每 4 小时增量备份(使用rsync --link-dest)。

4.10 日常运维:5 个必须监控的核心指标

Harbor 自带 Prometheus metrics 接口(https://harbor.yourdomain.com/metrics),我们通过 Grafana 监控以下 5 个黄金指标:

指标Prometheus 查询语句告警阈值说明
Registry 请求成功率rate(harbor_registry_http_request_total{code=~"2.."}[5m]) / rate(harbor_registry_http_request_total[5m])< 0.95持续低于 95% 表示 registry 异常
Core 服务延迟 P95histogram_quantile(0.95, rate(harbor_core_http_request_duration_seconds_bucket[5m]))> 2s核心 API 响应过慢,影响 UI 和 CLI
Redis 队列积压harbor_jobservice_redis_queue_length{queue="jobs"}> 100jobservice 任务堆积,扫描/复制延迟
存储空间使用率100 - (node_filesystem_avail_bytes{mountpoint="/data",fstype=~"nfs.*"} / node_filesystem_size_bytes{mountpoint="/data",fstype=~"nfs.*"} * 100)> 85%NFS 存储即将写满,需清理或扩容
数据库连接数postgres_connections{datname="registry"}> 900连接池接近上限,需调大max_open_conns

这些指标一旦越界,Grafana 会自动发送企业微信告警。某次,Redis 队列积压持续 10 分钟 > 200,我们登录harbor-jobservice容器,发现clair扫描器因网络问题卡死,手动 kill 了相关进程后,队列迅速清空。

4.11 故障排查:从日志定位问题的标准化流程

当 Harbor 出现异常,我们遵循四步日志分析法:

第一步:确认服务状态

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询