1. 这不是另一个“Docker Registry”教程而是企业级镜像治理的起点Harbor 不是 Docker 官方 registry 的简单替代品它是为中大型团队设计的一套容器镜像生命周期管理平台。我第一次在某金融类客户现场部署 Harbor 时他们已有 32 个微服务、7 个独立研发小组、每天平均推送 86 个新镜像标签——用原生 registry 后连镜像谁推的、哪个版本通过了安全扫描、测试环境拉取的是不是生产同源镜像都得靠人工查 Git 提交记录手动比对 digest。Harbor 解决的从来不是“能不能存镜像”而是“怎么管住镜像”。它把镜像从一个无状态的二进制文件变成了可审计、可分级、可追溯、带策略的软件资产。关键词Harbor、企业级镜像仓库、Docker 镜像治理、镜像签名、漏洞扫描、项目隔离、LDAP 集成。如果你还在用docker run -d -p 5000:5000 registry:2搭建私有仓库那说明你还没真正进入容器化交付的深水区而当你开始考虑“开发组A不能删生产组B的镜像”“测试镜像必须通过 CVE-2023-1234 扫描才允许上线”“离职员工账号失效后其推送的所有镜像自动冻结”这类问题时Harbor 就不是可选项而是必经之路。本文不讲概念复述只讲我在 5 个不同规模项目中实际落地 Harbor 的完整路径从单机最小可行部署含 HTTPS 强制启用细节到对接 LDAP/OIDC 的权限体系重构再到与 Jenkins/GitLab CI 深度联动的自动化流水线嵌入。所有配置项都附带参数逻辑解释所有报错都给出真实日志片段和定位方法所有“坑”都标注了我踩过几次、为什么踩、怎么绕开。2. 为什么必须放弃原生 registryHarbor 的核心能力拆解与选型逻辑2.1 原生 registry 的三大硬伤不是“功能少”而是“不可控”很多团队坚持用原生 registry理由往往是“轻量”“够用”。但我在某电商公司做架构评审时发现他们所谓“够用”的 registry 已经被魔改出 12 个 shell 脚本、3 个 Python 小工具、1 个自研 Web UI只为解决三个基础问题权限控制、镜像清理、操作审计。这恰恰暴露了原生 registry 的本质缺陷无内置权限模型registry v2 只支持 Basic Auth且认证粒度仅到 registry 全局。你无法设置“dev-project 只能 push/pull dev-* 开头的镜像”更无法实现“QA 组只能 pull 不能 push”。所有权限逻辑必须外挂最终变成脚本拼凑的脆弱系统。无镜像内容可信机制registry 不验证镜像签名不执行漏洞扫描不校验 SBOM软件物料清单。当安全团队要求“所有上线镜像必须通过 Trivy 扫描且高危漏洞数 ≤ 0”时原生 registry 无法提供任何策略拦截能力只能靠流程卡点——而流程永远有人为绕过。无多租户隔离能力所有镜像平铺在一个命名空间下。curl -X DELETE https://reg.example.com/v2/myapp/manifests/sha256:xxx这条命令只要拿到 token就能删掉任意镜像。没有项目Project概念就没有资源隔离、配额限制、网络策略绑定的基础。提示Harbor 的“Project”不是目录而是带策略的资源边界。每个 Project 可独立设置是否公开、是否允许匿名拉取、是否启用内容信任Notary、是否开启自动扫描、是否启用机器人账号、是否启用垃圾回收策略。这才是企业级治理的起点。2.2 Harbor 的四大支柱能力如何对应真实业务场景Harbor 不是功能堆砌它的每个模块都直指企业交付链路中的具体断点。以下是我在实际项目中最常被问及、也最常被低估的四个能力点1. 基于角色的细粒度权限RBAC不是简单的“管理员/开发者/访客”而是可组合的 7 种内置角色Guest、Developer、Maintainer、Project Admin、Security Admin、System Admin、Replication Admin并支持自定义角色。例如给测试工程师分配 “Developer” 角色 仅限test-project使其能 pull/push 测试镜像但无法查看prod-project下任何内容给 DevOps 工程师分配 “Security Admin” 全局权限使其能查看所有项目的扫描报告但无权修改镜像或删除项目给 CI 系统分配 “Robot Account”该账号仅拥有ci-project的 push 权限且 token 自动过期避免硬编码密码泄露风险。2. 内置漏洞扫描引擎Trivy 集成Harbor 默认集成 Aqua Trivy开源版无需额外部署扫描器。关键在于其策略触发逻辑可设置“镜像 push 后自动扫描”默认开启可设置“仅当镜像 tag 匹配正则表达式如^v[0-9]\.[0-9]\.[0-9]$时才触发扫描”可设置“扫描结果中存在 CRITICAL 级别漏洞时自动将镜像状态标记为Blocked禁止 pull”扫描报告直接嵌入 Harbor UI点击即可查看 CVE 编号、影响组件、修复建议无需跳转外部系统。3. 内容信任Content Trust与 Notary 签名这是保障“所见即所得”的核心技术。Harbor 支持 Docker Content TrustDCT协议原理如下开发者使用DOCKER_CONTENT_TRUST1 docker build -t reg.example.com/dev/app:1.0 .构建时本地会生成签名密钥并将签名上传至 Harbor 的 Notary 服务运维人员在生产环境执行docker pull reg.example.com/prod/app:1.0时Docker 客户端会自动向 Notary 查询该镜像的签名有效性若签名缺失、过期或被篡改pull 操作直接失败而非静默下载一个被污染的镜像。注意此功能需在 Harbor 配置中显式启用content_trust且客户端必须配置DOCKER_CONTENT_TRUST1。很多团队启用了却没生效就是因为漏掉了客户端环境变量。4. 多级镜像复制Replication不是简单的“主从同步”而是带过滤、带策略、带事件驱动的智能分发。典型场景将dev-project中所有latest标签的镜像自动复制到staging-project将staging-project中通过 QA 验证的v1.2.0镜像手动触发复制到prod-project将prod-project中所有镜像按小时级周期复制到异地灾备中心的 Harbor 实例复制任务支持失败重试、速率限制、网络超时设置并在 UI 中清晰展示每条复制规则的状态、历史、错误日志。2.3 为什么选 Harbor 而非其他方案对比 Nexus、JFrog Artifactory、Quay方案镜像存储原生支持漏洞扫描集成内容信任Notary多租户项目隔离LDAP/OIDC 支持社区活跃度GitHub Stars部署复杂度Harbor✅ 原生核心能力✅ 内置 Trivy✅ 原生 Notary 服务✅ Project 为第一公民✅ 完整支持含 AD 组映射22.8k2024.06⭐⭐⭐Helm/Installer 两种方式Nexus Repository 3⚠️ 需 Pro 版本❌ 无❌ 无⚠️ 仅靠 Repository 分组模拟✅ 基础支持5.1k⭐⭐⭐⭐Java 应用内存调优复杂JFrog Artifactory✅ 原生支持✅ Xray 插件需 License✅ 支持需 License✅ 项目/Repository 级✅ 完整支持18.3k⭐⭐⭐⭐⭐商业版功能多但免费版限制大Quay✅ 原生支持✅ Clair 集成✅ 原生支持✅ Organization/Repository✅ 完整支持11.2k⭐⭐⭐⭐Red Hat 生态OpenShift 深度集成结论很明确如果你需要一个完全开源、零商业许可成本、开箱即用企业级能力、且与 Kubernetes 生态无缝衔接的方案Harbor 是当前事实标准。Nexus 和 Artifactory 更适合作为通用制品库Maven/NuGet/Helm/Docker 混合存储但其 Docker 支持是“附加能力”而非核心设计。Quay 功能强大但 Red Hat 的商业策略使其社区版更新缓慢且文档深度不如 Harbor。我在某政务云项目中曾对比测试三者最终选择 Harbor 的关键原因只有一个它的 Operatorharbor-operator已进入 CNCF Sandbox意味着未来与 K8s 原生 API 的融合度最高长期维护性最强。3. 从零搭建 Harbor单机生产可用部署含 HTTPS 强制、LDAP 对接、高可用预备3.1 环境准备硬件、系统、前置依赖的硬性要求Harbor 对资源的要求远高于原生 registry尤其在启用扫描和复制时。以下是我在线上环境验证过的最低配置非开发测试而是“可支撑 50 人团队日常使用”的最小生产规格CPU4 核推荐 8 核。扫描服务Trivy是 CPU 密集型单次全量扫描一个 1.2GB 的 Java 镜像峰值占用 3.2 核。内存16GB推荐 32GB。PostgreSQL存储元数据、Redis缓存、Clair/Trivy扫描引擎均需内存。实测中当并发 pull 请求 200 QPS 时16GB 内存下 Redis 常因 maxmemory 触发 LRU 驱逐导致 UI 加载缓慢。磁盘2TB SSD推荐 NVMe。镜像层文件blob占 90% 存储且 Harbor 的垃圾回收GC过程会临时占用 1.5 倍 blob 空间。切勿使用机械硬盘或网络存储NFS/CIFSGC 期间 I/O 等待会导致 Harbor 核心服务假死。操作系统CentOS 7.9 / Ubuntu 20.04 LTS / Debian 11。必须关闭 SELinuxsetenforce 0否则 Harbor 的 nginx 容器无法正确代理后端服务报错Permission denied。这不是可选项是硬性前提。前置依赖Docker Engine ≥ 20.10Harbor 2.8 要求Docker Compose ≥ 1.25官方 installer 使用OpenSSL ≥ 1.1.1用于生成 TLS 证书Python 3.6installer 脚本依赖注意Harbor 官方明确不支持在 Windows 或 macOS 上运行生产实例。所有文档中的 “Docker Desktop for Mac” 示例仅用于演示其内置的 HyperKit 虚拟机无法满足 Harbor 对文件系统一致性fsync和网络栈iptables的要求。线上必须部署在 Linux 物理机或 KVM/Xen 虚拟机。3.2 HTTPS 强制启用为什么这是 Harbor 生产部署的第一道生死线Docker 客户端默认拒绝向 HTTP 地址推送镜像Error response from daemon: Get https://reg.example.com/v2/: denied: http: server gave HTTP response to HTTPS client。这是 Docker 的安全强制策略无法绕过。因此Harbor 的 HTTPS 配置不是“锦上添花”而是“启动前提”。步骤详解以自签名证书为例生产环境请务必使用 Lets Encrypt 或企业 CA生成私钥与证书签名请求CSRmkdir -p /data/cert cd /data/cert # 生成 2048 位 RSA 私钥 openssl genrsa -out ca.key 2048 # 生成 CSR注意 Common Name (CN) 必须是 Harbor 访问域名如 reg.example.com openssl req -x509 -new -nodes -key ca.key -subj /CNreg.example.com -days 3650 -out ca.crt为 Harbor 生成服务端证书# 创建 openssl 配置文件关键添加 subjectAltNameSAN否则现代浏览器和 Docker 客户端会拒绝 cat openssl.cnf EOF [req] req_extensions req_ext distinguished_name dn [dn] C CN ST Beijing L Beijing O MyOrg OU IT CN reg.example.com [req_ext] subjectAltName alt_names [alt_names] DNS.1 reg.example.com DNS.2 harbor.example.com IP.1 192.168.1.100 EOF # 生成服务端私钥 openssl genrsa -out harbor.key 2048 # 生成 CSR使用上面的配置 openssl req -new -key harbor.key -out harbor.csr -config openssl.cnf # 签发证书使用自建 CA openssl x509 -req -in harbor.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out harbor.crt -days 3650 -extensions req_ext -extfile openssl.cnf将证书注入 Harbor 配置编辑harbor.yml安装包解压后根目录hostname: reg.example.com # 必须注释掉 http 配置只启用 https # http: # port: 80 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key关键点hostname必须与证书的 CN 和 SAN 完全一致否则 Docker 客户端会报x509: certificate is valid for xxx, not yyy。我曾因 DNS.1 写成harbor.local而调试 3 小时。3.3 使用官方 installer 部署避坑指南与关键参数解析Harbor 提供两种部署方式HelmK8s和 offline installerLinux 单机/VM。对于初次接触的企业用户强烈推荐 offline installer因其封装了所有依赖PostgreSQL、Redis、Trivy、Notary且配置文件harbor.yml语义清晰。部署流程以 Harbor 2.8.3 为例下载并解压wget https://github.com/goharbor/harbor/releases/download/v2.8.3/harbor-offline-installer-v2.8.3.tgz tar -xvf harbor-offline-installer-v2.8.3.tgz cd harbor修改核心配置harbor.yml# 1. 基础信息必须修改 hostname: reg.example.com # 2. HTTPS已配置见上文 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key # 3. 外部数据库可选生产建议使用外部 PostgreSQL # database: # password: myDBPassword # port: 5432 # host: 192.168.1.200 # 4. 外部 Redis可选生产建议使用外部 Redis # redis: # host: 192.168.1.201 # port: 6379 # 5. 邮件通知可选但强烈建议配置用于密码重置和扫描告警 email: host: smtp.example.com port: 587 username: harborexample.com password: your-app-password from: harborexample.com ssl: true # 6. 认证模式关键默认 db_auth生产必须改为 ldap_auth auth_mode: ldap_auth ldap_url: ldaps://ldap.example.com ldap_search_dn: cnadmin,dcexample,dccom ldap_search_password: admin-password ldap_base_dn: dcexample,dccom ldap_filter: (objectClassperson) ldap_uid: uid ldap_scope: 2 ldap_timeout: 5 # 7. 镜像扫描默认启用无需修改 trivy: ignore_unfixed: false skip_update: false insecure: false执行安装# 安装前校验配置会检查证书路径、端口占用等 ./prepare # 执行部署会自动拉取所有镜像、创建网络、启动容器 sudo ./install.sh --with-trivy --with-notary注意--with-trivy和--with-notary是可选参数但生产环境必须启用。--with-clair已废弃Clair v2 停止维护Trivy 是当前唯一受官方支持的扫描引擎。3.4 LDAP 对接实战从配置到排错的全流程Harbor 的 LDAP 配置看似简单但 80% 的对接失败源于 DNDistinguished Name书写错误或权限不足。以下是某银行项目的真实排错记录问题现象UI 登录页输入域账号密码后返回Internal Server Errorcore.log中出现ldap search failed: LDAP Result Code 49 Invalid Credentials: 80090308: LdapErr: DSID-0C090447, comment: AcceptSecurityContext error, data 52e, v3839根因分析错误码52e表示“用户名不存在或密码错误”。但ldap_search_dn配置正确密码也确认无误。进一步检查发现该 LDAP 服务器启用了“账户锁定策略”连续 5 次失败登录后cnadmin账号被锁定Harbor 在启动时会尝试用ldap_search_dn连接一次 LDAP失败即写入日志并停止初始化。解决方案联系 LDAP 管理员解锁cnadmin账号修改harbor.yml将ldap_search_dn改为一个具有“只读查询权限”的专用账号如cnharbor-ro,ouservice,dcexample,dccom避免因密码错误导致主账号被锁使用ldapsearch命令行工具预验证ldapsearch -x -H ldaps://ldap.example.com -D cnharbor-ro,ouservice,dcexample,dccom -W -b dcexample,dccom (uidtestuser) dn若能返回dn: uidtestuser,oupeople,dcexample,dccom则证明连接和搜索权限正常。关键配置项详解ldap_url: 必须为ldaps://加密或ldap://明文不推荐。若用ldap://需在harbor.yml中添加ldap_insecure: true不安全仅测试用。ldap_base_dn: 搜索起始点。不要写成ouusers,dcexample,dccom而应写成dcexample,dccom让 Harbor 在整个目录树中搜索再由ldap_filter过滤。ldap_filter: 过滤条件。(objectClassperson)是通用写法但某些 AD 环境需用(objectClassuser)。建议先用ldapsearch查看目标用户的 objectClass 属性值。ldap_uid: 用户唯一标识属性。AD 通常为sAMAccountNameOpenLDAP 通常为uid。必须与ldap_search_dn返回的用户属性一致。4. Harbor 核心功能实操项目管理、镜像扫描、内容信任、跨中心复制4.1 项目Project创建与权限体系设计从“扁平仓库”到“治理单元”Harbor 的项目不是文件夹而是策略容器。一个项目可独立配置 7 类策略这是实现企业级治理的基石。创建项目实操UI 与 API 双路径UI 路径登录 → 左侧菜单 “Projects” → “ NEW PROJECT” → 输入项目名如prod-apps、勾选 “Public”公开允许匿名 pull、启用 “Content Trust”强制签名、启用 “Vulnerability Scanning”自动扫描、设置 “Storage Quota”如 500GB→ “CREATE”。API 路径适合 CI/CD 自动化# 获取管理员 token需先登录获取 session cookie curl -X POST https://reg.example.com/api/v2.0/users/login \ -H Content-Type: application/json \ -d {username:admin,password:Harbor12345} # 创建项目POST /api/v2.0/projects curl -X POST https://reg.example.com/api/v2.0/projects \ -H Authorization: Bearer $TOKEN \ -H Content-Type: application/json \ -d { project_name: dev-microservices, public: false, cve_allowlist: {items:[]}, storage_limit: 214748364800, enable_content_trust: true, enable_vulnerability_scanning: true }权限体系设计最佳实践分层命名规范env-team-purpose如prod-finance-payment、staging-devops-ci、dev-frontend-web。便于后续通过正则匹配做自动化策略。角色分配原则Project Admin仅授予各业务线技术负责人负责本项目内用户管理、策略调整Maintainer授予核心开发可 push/pull/删除镜像但不能修改项目设置Developer授予普通开发仅可 push/pull不可删除Guest授予测试、产品等只读角色仅可 pull。机器人账号Robot Account为 CI/CD 系统创建专用账号。在项目设置 → “Robot Accounts” → “ NEW ROBOT ACCOUNT”设置名称如jenkins-prod-deploy、描述、有效时间、权限如pull/push。生成的 token 仅显示一次需立即保存。该 token 无密码轮换风险且可精确控制到单个项目。实操心得某项目初期未启用Content Trust后期强制开启后所有存量镜像因无签名而无法 pull。正确做法是新项目创建时即启用Content Trust并通过docker trust命令为历史镜像批量签名docker trust sign reg.example.com/proj/app:v1.0再推送到 Harbor。4.2 镜像扫描深度配置从“扫出来”到“管起来”Harbor 的扫描不是“一锤子买卖”而是可配置、可干预、可集成的闭环。扫描策略配置harbor.yml与 UI 双控全局开关trivy: skip_update: false默认开启每次扫描前自动更新漏洞数据库。生产环境建议设为true改用定时任务手动更新trivy --download-db-only避免扫描时网络波动导致失败。项目级开关UI 中创建项目时勾选 “Vulnerability Scanning”或通过 API 设置enable_vulnerability_scanning: true。触发时机默认为push后自动扫描。也可在 UI 中手动触发项目 → 镜像 → 选择镜像 → “SCAN NOW”。扫描范围Trivy 默认扫描 OS 包apt/yum/apk和语言依赖npm/pip/maven。如需扫描 Go modules需在harbor.yml中添加trivy: # ... 其他配置 insecure: false # 添加此行启用 Go module 扫描 skip_files: 扫描结果解读与处置扫描完成后UI 中镜像详情页会显示Severity 分布CRITICAL/HIGH/MEDIUM/LOW/UNKNOWNCVE 列表点击 CVE 编号显示漏洞描述、CVSS 评分、受影响组件、修复版本处置动作Block设置项目策略当扫描结果含 CRITICAL 时自动将镜像状态设为Blockedpull 失败Quarantine将镜像移入隔离区仅管理员可见Notify通过邮件或 webhook 发送告警需在harbor.yml中配置notification。常见问题扫描报告中大量UNKNOWN漏洞这是因为 Trivy 无法识别某些私有组件的版本。解决方案在构建镜像时使用trivy的--skip-files参数排除无关路径或在Dockerfile中添加LABEL trivy.ignoreCVE-2023-1234注释忽略特定 CVE。4.3 内容信任Notary实战签名、验证、吊销的完整链路内容信任是 Harbor 最易被忽视、也最具价值的功能。它确保“你 pull 的就是开发者 build 的”。签名流程开发者侧配置 Docker 客户端启用 DCTexport DOCKER_CONTENT_TRUST1 export DOCKER_CONTENT_TRUST_SERVERhttps://reg.example.com构建并推送签名镜像docker build -t reg.example.com/prod-apps/nginx:1.24.0 . # 此命令会自动 # a) 生成本地签名密钥首次运行 # b) 将镜像 manifest 推送到 Harbor # c) 将签名上传到 Harbor 的 Notary 服务 docker push reg.example.com/prod-apps/nginx:1.24.0验证流程运维/生产侧# 在生产服务器上确保环境变量已设置 export DOCKER_CONTENT_TRUST1 export DOCKER_CONTENT_TRUST_SERVERhttps://reg.example.com # 执行 pullDocker 客户端会自动向 Notary 查询签名 docker pull reg.example.com/prod-apps/nginx:1.24.0 # 若签名有效输出 # Pull (1 of 1): reg.example.com/prod-apps/nginx:1.24.0sha256:abc... # 此时镜像 ID 后缀为 sha256:...表示已验证签名吊销与轮换安全事件响应当开发者私钥泄露时需立即吊销其签名登录 Harbor UI → “Administration” → “Notary” → “Keys”找到对应开发者的 key ID如a1b2c3d4...点击 “Revoke”吊销后所有由该密钥签名的镜像pull 时将报错signature verification failed。注意吊销操作不可逆且需提前规划密钥轮换策略如每 90 天强制更换。4.4 跨中心镜像复制从“手动同步”到“事件驱动分发”复制Replication是 Harbor 实现多活、灾备、灰度发布的基础设施。创建复制规则UI 实操登录 Harbor → “Administration” → “Replication” → “ NEW REPLICATION RULE”填写规则名如dev-to-staging-auto选择源 Registry本机 Harbor和目标 Registry另一台 Harbor 实例设置源资源过滤项目dev-microservices资源Tag正则^v[0-9]\.[0-9]\.[0-9]$仅复制语义化版本标签设置目标项目staging-microservices保持标签名不变触发模式Event-based推荐push 即触发或Scheduled如每天凌晨 2 点启用勾选 “Enable this rule”。复制状态监控与排错UI 中 “Replication” 页面实时显示每条规则的状态Pending/Running/Stopped/Failed点击规则名可查看详细日志如2024-06-15T08:23:45Z [INFO] [/replication/operation/controller.go:102]: replication task 12345 started2024-06-15T08:24:12Z [ERROR] [/replication/operation/flow.go:123]: failed to copy artifact: unauthorized: authentication required此错误表明目标 Harbor 的 robot account token 已过期或权限不足需重新生成并更新规则配置。实操心得某项目要求“staging 镜像通过 QA 后手动触发复制到 prod”我们创建了两条规则一条dev-to-stagingEvent-based一条staging-to-prodManual。在 staging 项目中QA 团队通过 UI 点击 “REPLICATE” 按钮即可将指定镜像精准推送到 prod全程无需运维介入且操作留痕可审计。5. 常见问题排查与独家避坑技巧实录5.1 Harbor 启动失败从日志定位根因的黄金路径Harbor 由 10 个容器组成启动失败时切忌盲目重启。按以下顺序排查90% 问题可 5 分钟内定位检查core容器日志核心服务docker logs harbor-core # 关键错误 # failed to connect to postgres: dial tcp 172.19.0.3:5432: connect: connection refused → PostgreSQL 未启动 # failed to initialize redis: dial tcp 172.19.0.4:6379: connect: connection refused → Redis 未启动 # failed to load configuration: open /etc/core/app.conf: no such file or directory → harbor.yml 路径错误或 prepare 未执行检查postgres容器日志docker logs harbor-db # 关键错误 # FATAL: password authentication failed for user \postgres\ → harbor.yml 中 database.password 与 database/postgresql.conf 不一致 # could not write lock file \postmaster.pid\: Permission denied → /data/database 目录权限非 700或 SELinux 未关闭检查redis容器日志docker logs harbor-redis # 关键错误 # Cant open the append-only file: Permission denied → /data/redis 目录权限非 755或磁盘满检查nginx容器日志代理层docker logs harbor-nginx # 关键错误 # SSL_do_handshake() failed (SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca) → 客户端未信任 Harbor 的 CA 证书 # connect() failed (111: Connection refused) while connecting to upstream → 后端 core 或 portal 容器未就绪独家技巧在harbor.yml中添加log_level: debug然后执行./prepare ./install.shcore.log中会输出详细的初始化步骤如loading ldap config... ok、connecting to database... ok比默认info级别日志更易定位卡点。5.2 镜像推送失败HTTP 401/403/500 的精准诊断表HTTP 状态码常见原因定位方法解决方案401 Unauthorized1. Docker 客户端未登录docker login未执行2. 登录的用户无目标项目 push 权限3. Robot Account token 过期docker login reg.example