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-trustfalse认可。这些坑我都在某制造企业的 CI/CD 升级中踩过现在写出来就是为了让别人少花三天时间查日志。你不需要是 Kubernetes 专家但得理解 Harbor 是一个由 7 个独立容器协同工作的系统harbor-core权限与策略中枢、harbor-registry实际存储层、harbor-dbPostgreSQL 元数据、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 层 layercore在处理并发 push 时需加载大量元数据进内存。我们实测发现当并发数超过 3512Mi 内存下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 而非内置 SQLiteHarbor 官方文档明确标注“SQLite 仅用于开发和测试”。但很多团队仍选择它理由是“省事”。这个“省事”代价极高。SQLite 的锁机制是全库级的——当core服务执行用户权限同步如 LDAP 组映射更新时会持有写锁此时若jobservice正在写入扫描报告或registry正在记录 blob 引用全部阻塞。我们在某教育平台压测中发现当并发用户数达 80SQLite 下平均 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 对小 layer5MB效率极低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,rsize1048576,wsize1048576,vers4.1参数优化挂载性能。某电商大促前我们曾用fio对比测试NFS4.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 强制要求 HTTPSHTTP 仅允许开发模式但很多人卡在证书环节。常见错误是直接用自签名证书然后在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.crtMac 的钥匙串Windows 的受信任根证书颁发机构。这在百台服务器规模下运维成本极高。正确做法是使用Lets Encrypt或企业内网 CA 签发的证书。以 Lets 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必须与证书的 CNCommon Name或 SANSubject 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 --iphttp://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 是CNDevTeam,OUGroups,DCcorp,DClocal而 Harbor 默认解析器期望CNDevTeam导致组同步为空。解决方法是在harbor.yml中添加ldap: group_search_filter: (member{0}) group_search_base: OUGroups,DCcorp,DClocal 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:CNadmin,OUUsers,DCcorp,DClocal,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间的通信默认启用sslmoderequire若 PostgreSQL 未配置 SSL则连接拒绝。解决方案分两步首先确认 PostgreSQL 已启用 SSL。编辑/var/lib/pgsql/data/postgresql.confssl 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 /CCN/STBeijing/LBeijing/OHarbor/CNlocalhost 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.0Compose 是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.cgroupdriversystemd] }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-compose4.3 获取与解压 Harbor 安装包别跳过校验环节Harbor 安装包必须从 goharbor.io 官网下载严禁使用第三方镜像站。原因在于Harbor 的离线安装包harbor-offline-installer-v2.8.2.tgz包含预编译的二进制和 Docker 镜像 tarball若被篡改可能导致install.sh执行恶意代码。我们要求所有团队在下载后必须校验 SHA256wget 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.yml4.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:10000harbor 用户 ID # --- Clair 扫描 --- clair: updaters_interval: 12 http_proxy: http://proxy.internal:3128 https_proxy: http://proxy.internal:3128 skip_update: true # skip_updatetrue 时必须手动运行 clairctl update # --- LDAP 配置 --- ldap: url: ldaps://ad.corp.local basedn: dccorp,dclocal admin_dn: cnadmin,ouusers,dccorp,dclocal admin_password: xxx email_attribute: mail group_search_base: ougroups,dccorp,dclocal group_search_filter: (member{0}) group_search_scope: 2 # group_search_scope2 是关键否则无法搜索子 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-coredocker start harbor-core4.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 completedharbor-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 使用 Lets 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 docker4.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 和 CLIRedis 队列积压harbor_jobservice_redis_queue_length{queuejobs} 100jobservice 任务堆积扫描/复制延迟存储空间使用率100 - (node_filesystem_avail_bytes{mountpoint/data,fstype~nfs.*} / node_filesystem_size_bytes{mountpoint/data,fstype~nfs.*} * 100) 85%NFS 存储即将写满需清理或扩容数据库连接数postgres_connections{datnameregistry} 900连接池接近上限需调大max_open_conns这些指标一旦越界Grafana 会自动发送企业微信告警。某次Redis 队列积压持续 10 分钟 200我们登录harbor-jobservice容器发现clair扫描器因网络问题卡死手动 kill 了相关进程后队列迅速清空。4.11 故障排查从日志定位问题的标准化流程当 Harbor 出现异常我们遵循四步日志分析法第一步确认服务状态