国内网络环境下Harness CI/CD流水线实战:GitLab+Harbor一键跑通
1. 项目概述为什么国内团队需要一条“能跑通”的 Harness CI/CD 流水线你刚在公司内部技术分享会上听到同事说“我们准备把 Jenkins 换成 Harness听说更智能、更省事。”你点点头心里却在想GitLab 仓库连得上吗Harbor 镜像仓库证书报错怎么解本地开发机是 Windows流水线里执行 shell 脚本会不会直接挂CI 触发后构建失败日志里全是login failed. check api token or gitlab version这种提示到底该去 GitLab 哪个页面找 Token——这些不是理论问题是今天下午三点前你必须让第一条流水线成功打出一个 Docker 镜像的现实压力。这就是“Harness 教程 02国内网络环境下创建第一个 CI/CD 流水线”要解决的真实场景。它不讲抽象概念不堆架构图只聚焦一件事在你当前所处的典型国内企业开发环境里GitLab 社区版或自建实例 Harbor 私有镜像仓库 Windows/Mac/Linux 混合开发机 无公网 GitHub 访问权限用最短路径、最少配置、最稳参数跑通从代码提交 → 自动构建 → 推送镜像 → 生成可部署制品的完整闭环。核心关键词Harness、CI/CD、流水线、GitLab、Harbor不是标签而是你每天要打交道的五个具体系统组件。其中“国内网络环境”四个字是全部前提——它意味着你要绕开默认依赖的 SaaS 服务地址、处理自签名证书、适配国产化中间件的 TLS 版本、接受 GitLab API 的兼容性降级、容忍 Harbor 的 HTTP 重定向陷阱。我带过的 7 个客户团队里有 5 个卡在第一步“连接 GitLab”超 2 小时不是因为不会配 Token而是因为没意识到 GitLab 12.6.4 的/api/v4/projects接口在开启双因素认证2FA后会静默返回 403而 Harness UI 的错误提示根本没提这茬。这篇教程就是把这些“文档里没写、报错里不显、搜不到答案”的坑用实操步骤原理说明截图逻辑全给你摊开。适合刚接触 Harness 的 DevOps 工程师、被临时拉来搭流水线的后端开发、或是正在评估替代 Jenkins 方案的技术负责人——只要你手头有一台能连内网 GitLab 和 Harbor 的机器就能跟着做不需要翻墙、不需要改 DNS、不需要申请额外云账号。2. 整体设计思路与方案选型解析2.1 为什么选 GitLab Harbor 组合而不是 GitHub Docker Hub先说结论这不是技术偏好是合规与落地成本的硬约束。国内中大型企业几乎 100% 使用自建 GitLab社区版或企业版原因很实在——代码资产不出内网、审计日志可追溯、分支保护策略可定制。而 Docker Hub 在 2023 年底起对未登录用户限流且其免费层不支持私有镜像自动扫描这对金融、政企类项目是红线。Harbor 成为事实标准不仅因它是 CNCF 毕业项目更因它原生支持国密 SM2/SM4 算法证书、可对接 LDAP/AD 域控、提供细粒度的项目级镜像扫描策略比如要求所有推送到prod项目的镜像必须通过 Trivy CVE-2023-XXXX 扫描。我在某省级政务云项目里实测过同样推送一个 800MB 的 Spring Boot 镜像走 Docker Hub 公网链路平均耗时 6 分 23 秒受运营商 DNS 解析和跨境带宽影响而走内网 Harbor10G 光纤直连仅需 48 秒。这个差距在每日数百次构建中会放大成数小时的人力等待。所以本教程所有配置都基于 GitLab 12.6.4 和 Harbor v2.8.3当前国内政企交付最稳版本不假设你有 GitHub 账号不依赖任何境外 CDN 或镜像源。2.2 为什么跳过 Harness Cloud坚持用 Self-Managed Harness PlatformHarness 官方提供两种部署模式SaaSHarness Cloud和自托管Self-Managed。国内项目必须选后者理由有三第一数据主权。所有流水线定义、密钥凭证、构建日志、部署记录都存储在你自己的 Kubernetes 集群中符合《网络安全法》第 37 条关于关键信息基础设施运营者境内存储的要求第二网络可控。Harness Cloud 默认通过app.harness.io域名通信而国内防火墙对这类 SaaS 域名存在间歇性拦截曾有客户反馈流水线触发后 15 分钟无响应抓包发现是 DNS 请求被丢弃第三集成深度。自托管版可直接挂载企业 NFS 存储做构建缓存可复用现有 K8s RBAC 权限体系还能通过harness-delegate的--labels参数给 Delegate 打标实现“测试环境 Delegate 只能访问测试 GitLab 项目生产环境 Delegate 只能调用生产 Harbor 仓库”的强隔离。我建议用 Helm 部署 Harness Platform而非 Docker Compose因为 Helm 的values.yaml可以精确控制每个组件的资源限制、TLS 证书挂载路径、数据库连接池大小——这些在金融类客户压测中都是救命参数。比如当并发流水线超过 50 条时若不调大harness-manager的 JVM 堆内存默认 2G就会出现OutOfMemoryError: Metaspace导致整个平台不可用而 Helm 部署只需改一行manager.jvmOptions: -Xms4g -Xmx4g即可。2.3 为什么流水线设计采用“单阶段三步法”而非多环境分阶段很多教程喜欢画一张“Dev → Staging → Prod”三级流水线图但真实国内项目往往卡在第一步就动不了。原因在于多阶段需要提前配置至少 3 套环境凭证GitLab Token、Harbor Credential、K8s Config而新团队通常只有测试环境可用其次GitLab 的分支保护策略如main分支需 2 人 approve在多阶段中会引发权限冲突最后Harness 的 Stage 间 Artifact 传递依赖Harness Artifact功能而该功能在自托管版需额外启用 Feature Flag且国内客户常因 NTP 时间不同步导致 Artifact 签名验证失败。所以本教程采用极简主义设计一个 Pipeline一个 Stage三个 Sequential Steps——Step 1从 GitLab 拉代码含 submoduleStep 2用 Maven 构建并打 Docker 镜像使用 BuildKit 加速Step 3推送到 Harbor 并打 TagTag 名为git commit short hash timestamp。这样做的好处是所有操作都在同一命名空间下完成凭证复用率 100%失败时日志上下文完整排查时不用跨 Stage 切换上下文。等这条流水线稳定运行一周后再按需拆分出 QA Stage 或 Prod Stage这才是符合国内团队渐进式落地节奏的做法。2.4 为什么强调“Windows 开发机适配”而不是默认 Linux因为国内开发桌面环境仍是 Windows 主导。据我统计过去一年接手的 12 个客户中9 个团队的主力开发机是 Windows 10/11装有 WSL2 或直接用 Git Bash只有 3 个是 Mac。这意味着你的流水线脚本不能默认用#!/bin/bash也不能假设sed -i命令存在Windows Git Bash 的 sed 不支持-i参数。更关键的是Harness Delegate 在 Windows 上运行时其工作目录路径含空格如C:\Program Files\harness-delegate会导致 Docker 构建上下文路径解析失败。解决方案是强制 Delegate 启动参数加--work-dir D:\harness-work并在流水线 YAML 中所有run步骤的shell字段明确指定sh而非默认bash同时用$(pwd)替代反引号执行 pwd 命令。这些细节看似琐碎但正是导致“教程能跑通我的环境跑不通”的根源。本教程所有命令示例均经过 Windows Git Bash、WSL2 Ubuntu 22.04、macOS Ventura 三端实测确保你复制粘贴就能用。3. 核心细节解析与实操要点3.1 GitLab 连接配置Token 权限、API 版本、分支保护绕过技巧连接 GitLab 是 Harness 流水线的第一道关卡也是失败率最高的环节。核心问题不在 Harness 配置而在 GitLab 侧的权限收敛与接口兼容性。我们分三步解决第一步创建专用 GitLab Personal Access Token不要用管理员账号的 Token也不要复用已有开发 Token。进入 GitLab → Settings → Access Tokens填写Token nameharness-ci-token命名规范便于审计Scopes仅勾选api和read_repositorywrite_repository权限在 CI 场景中完全不需要属于安全冗余Expires at设为 1 年避免 Token 过期导致流水线静默失败提示如果 GitLab 启用了双因素认证2FA此 Token 创建后会立即生效无需二次验证但若用户账户被管理员设置为“pending approval”则 Token 创建会失败此时需联系 GitLab Admin 在 Admin Area → Overview → Users 页面手动批准该账户。第二步确认 GitLab API 兼容性Harness 默认调用 GitLab/api/v4/接口但 GitLab 12.6.4 存在一个隐藏 Bug当项目启用了 Merge Request Approvals合并请求审批且审批组为空时GET /api/v4/projects/:id接口会返回 500 错误导致 Harness 无法获取项目元数据。验证方法用 curl 直接调用curl -H PRIVATE-TOKEN: your-token https://gitlab.your-company.com/api/v4/projects?searchyour-project-name若返回{message:500 Internal Server Error}说明存在该 Bug。临时解法是在 GitLab 项目设置 → Merge Requests → Merge Request Approvals 中为该项目添加一个空的 Approval Rule即不指定任何成员保存后即可恢复 API 正常。第三步处理分支保护策略的“静默拦截”国内团队常对main分支设置“Push rules”推送规则例如禁止直接 push、仅允许 merge request。这会导致 Harness 在执行git push如自动打 Tag时被拒绝但 Harness 日志只显示Command failed with exit code 128不提示具体原因。破解方法是在 Harness Pipeline 的Git CloneStep 中将Connection Type设为SSH而非 HTTPS并在 GitLab 用户 Settings → SSH Keys 中添加 Harness Delegate 服务器的公钥id_rsa.pub。这样所有 Git 操作走 SSH 协议绕过 HTTP 层的 Push Rules 检查。实测下来SSH 方式比 HTTPS 快 40%且不受 GitLab Web UI 的分支保护策略影响。3.2 Harbor 凭证配置HTTP vs HTTPS、证书信任、项目权限映射Harbor 连接失败的第二大原因是证书与权限。国内自建 Harbor 普遍使用自签名证书或内网 CA 签发证书而 Harness Delegate 默认只信任系统根证书库/etc/ssl/certs/ca-certificates.crt不会自动加载 Harbor 的.crt文件。我们分场景处理场景一Harbor 使用 HTTP测试环境常见这是最快捷的入门方式但仅限非生产环境。在 Harness 中创建 Connector 时Connection Type选择Docker RegistryURL填http://harbor.your-company.com注意是http不是httpsAuthentication选择Username and Password输入 Harbor 普通用户账号非 admin关键操作在Advanced展开项中勾选Allow HTTP此选项默认关闭不勾选则连接必败场景二Harbor 使用 HTTPS 自签名证书生产环境标准必须让 Delegate 信任该证书。操作分两步将 Harbor 的 CA 证书通常是ca.crt拷贝到 Delegate 服务器的/opt/harness-delegate/certs/目录下修改 Delegate 启动脚本在java命令后添加 JVM 参数-Djavax.net.ssl.trustStore/opt/harness-delegate/certs/cacerts \ -Djavax.net.ssl.trustStorePasswordchangeit注意cacerts是 Java 默认信任库需用keytool命令将ca.crt导入keytool -import -trustcacerts -file /opt/harness-delegate/certs/ca.crt -alias harbor-ca -keystore /opt/harness-delegate/certs/cacerts密码默认为changeit。场景三Harbor 项目级权限隔离金融类刚需很多团队希望team-a的流水线只能推镜像到harbor.your-company.com/team-a项目不能碰team-b。这需要在 Harbor 侧创建 Robot Account机器人账号进入 Harbor → Projects → 选择目标项目如team-a→ Robots → New Robot AccountNameharness-team-aPermissions勾选Pull / Push仅限本项目生成后复制Robot Account的用户名格式为harbor-robot$team-a和密码一串长字符串在 Harness Connector 中Authentication 选择Username and Password填入上述 Robot Account 凭据这样即使 Harness 平台被攻破攻击者也只能操作team-a项目下的镜像无法横向移动。3.3 流水线 YAML 关键字段详解从模板到可运行的最小集Harness 流水线本质是 YAML 文件但官方文档常堆砌 50 字段新手根本不知哪些是必填。我们提炼出“国内环境可运行的最小 YAML 集”共 12 个核心字段其余均可删减# pipeline.yaml pipeline: identifier: first-cicd-pipeline name: First CI/CD Pipeline tags: {} stages: - stage: name: Build and Push identifier: build-and-push type: CI spec: cloneCodebase: true # 必须为 true否则不拉代码 infrastructure: type: KubernetesDirect spec: connectorRef: YOUR_K8S_CONNECTOR_ID # 指向你已配好的 K8s 集群 namespace: harness-build-ns # 建议新建独立命名空间避免资源冲突 execution: steps: - step: name: Checkout Code identifier: checkout type: Plugin spec: image: plugins/git:1.14.0 # 固定版本避免镜像更新导致行为变化 settings: depth: 1 # 只拉最新 commit提速 70% fetchSubmodules: true # 若项目含 submodule必须设为 true - step: name: Build Docker Image identifier: build-docker type: ShellScript spec: shell: sh # 强制用 sh兼容 Windows Git Bash script: |- #!/usr/bin/env sh echo Building image with commit $(git rev-parse --short HEAD) docker build --platform linux/amd64 \ --build-arg BUILD_NUMBER${HARNESS_PIPELINE_EXECUTION_ID} \ -t harbor.your-company.com/team-a/app:${HARNESS_GIT_COMMIT_SHORT_SHA}-$(date %Y%m%d-%H%M%S) \ -f ./Dockerfile . # 关键设置 timeout 为 15m避免大项目构建超时中断 timeout: 15m - step: name: Push to Harbor identifier: push-harbor type: Plugin spec: image: plugins/docker:22.04.0 settings: registry: harbor.your-company.com repo: team-a/app tags: ${HARNESS_GIT_COMMIT_SHORT_SHA}-$(date %Y%m%d-%H%M%S) username: ${HARNESS_SECRET_USERNAME} # 从 Harness Secret 读取 password: ${HARNESS_SECRET_PASSWORD} # 从 Harness Secret 读取字段解析与避坑点cloneCodebase: true这是开关设为 false 则整个流水线不拉代码日志里还找不到提示depth: 1GitLab 默认拉全量历史对 5 年老项目可能耗时 8 分钟设为 1 后秒级完成shell: shHarness 默认用 bash但在 Windows Git Bash 下会报bash: line 1: syntax error near unexpected token必须显式声明timeout: 15mDocker 构建超时默认是 10m而国内网络下docker build拉基础镜像常卡在 9m59s设为 15m 可覆盖 95% 场景tags字段中的${HARNESS_GIT_COMMIT_SHORT_SHA}这是 Harness 内置变量值为 7 位 commit hash比用$(git rev-parse --short HEAD)更可靠后者在某些 Delegate 版本中会因工作目录问题失效username/password用${HARNESS_SECRET_USERNAME}绝不要明文写密码必须先在 Harness UI → Account Resources → Secrets 中创建 Text 类型 Secret再在此处引用。3.4 Windows 开发机专属适配Delegate 安装、路径处理、Shell 兼容性如果你的 Harness Delegate 装在 Windows 机器上比如开发笔记本以下四点必须手动修正否则 100% 失败第一Delegate 安装路径不能含空格官方安装脚本默认将 Delegate 装在C:\Program Files\harness-delegate但Program Files中的空格会导致 Docker 构建时--context参数解析失败。正确做法下载 Delegate ZIP 包非 MSI解压到D:\harness-delegate纯英文、无空格、盘符非 C编辑D:\harness-delegate\delegate.shGit Bash 环境或delegate.batCMD 环境在java命令行末尾添加-Dharness.delegate.workDirD:\harness-work并确保D:\harness-work目录已手动创建。第二流水线中所有路径用正斜杠/Windows 习惯用反斜杠\但 Harness YAML 解析器只认/。例如❌ 错误script: cd C:\project mvn clean package✅ 正确script: cd /c/project mvn clean packageGit Bash 下 C 盘映射为/c第三禁用 Windows Defender 实时扫描Delegate 运行时会高频读写D:\harness-work目录Defender 默认将其标记为“可疑行为”并阻断。需在 Windows 安全中心 → 病毒和威胁防护 → 管理设置 → 添加或删除排除项 → 添加文件夹D:\harness-work。第四Shell 脚本必须声明#!/usr/bin/env shHarness 在 Windows 上默认调用cmd.exe而cmd不支持$()语法。在ShellScriptStep 的script字段开头必须写#!/usr/bin/env sh echo Current dir: $(pwd)这样 Delegate 会强制用 Git Bash 的sh解释器执行而非cmd。4. 实操过程与核心环节实现4.1 环境准备清单5 分钟内完成所有前置依赖别跳过这一步。我见过太多人花 3 小时排错结果发现是少装了一个jq工具。以下是经 12 个客户环境验证的最小依赖清单全部命令在 Windows Git Bash、WSL2、macOS 终端通用组件检查命令正确输出示例不通过时操作Java 11java -version 21 | head -1openjdk version 11.0.22下载 Adoptium JDK 11 配置JAVA_HOMEDocker CLIdocker --versionDocker version 24.0.7Windows 用 Docker Desktop WSL2 用sudo apt install docker.iokubectlkubectl version --clientClient Version: v1.27.7curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl chmod x kubectl sudo mv kubectl /usr/local/bin/Helm 3helm version --shortv3.12.3g39452e5curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3jqjq --versionjq-1.6sudo apt install jqUbuntu或brew install jqMac或choco install jqWindows提示所有命令执行后若返回command not found请立即安装不要尝试“跳过”。特别是jqHarness Delegate 启动时会用它解析 JSON 配置缺失会导致 Delegate 卡在Starting...状态。4.2 Harness Platform 自托管部署Helm 安装全流程我们用 Helm 3 部署 Harness Platform 到现有 Kubernetes 集群版本 ≥ 1.22。全程无需修改官方 Chart只调整values.yaml中 4 个关键参数步骤 1添加 Harness Helm 仓库helm repo add harness https://helm.harness.io helm repo update步骤 2创建自定义 values.yaml新建harness-values.yaml内容如下已针对国内网络优化global: # 关键禁用所有外网依赖 disableTelemetry: true disableAnalytics: true # 指向国内镜像源 image: repository: registry.cn-hangzhou.aliyuncs.com/harness tag: 1.22.0 manager: # 内存调大防 OOM jvmOptions: -Xms4g -Xmx4g # 数据库连接池适配高并发 database: maxActive: 100 maxIdle: 50 redis: # 使用企业 Redis非内置 enabled: false host: redis.your-company.com port: 6379 mongo: # 使用企业 MongoDB非内置 enabled: false uri: mongodb://mongo.your-company.com:27017/harness?replicaSetrs0步骤 3执行 Helm 安装# 创建命名空间 kubectl create namespace harness-platform # 安装替换 YOUR_RELEASE_NAME 为实际名称 helm install YOUR_RELEASE_NAME harness/harness-platform \ --namespace harness-platform \ --values harness-values.yaml \ --set global.ingress.enabledtrue \ --set global.ingress.hosts[0].hostharness.your-company.com \ --set global.ingress.tls[0].hosts[0]harness.your-company.com \ --set global.ingress.tls[0].secretNameharness-tls-secret验证是否成功kubectl get pods -n harness-platform # 应看到 manager-xxx, redis-xxx, mongo-xxx 等 Pod 状态为 Running kubectl get ingress -n harness-platform # 应看到 harness-ingress 的 ADDRESS 字段为你的 Ingress Controller IP注意若集群无 Ingress Controller可改用 NodePort 模式只需将--set global.ingress.enabledtrue改为--set global.service.typeNodePort然后用kubectl get svc -n harness-platform查看harness-manager的 NodePort 端口通常是 30000。4.3 Delegate 部署与注册Windows/Linux/macOS 三端统一方案Delegate 是 Harness 的“手脚”所有流水线操作都由它执行。国内环境推荐用Kubernetes Delegate而非 Docker 或 VM因为1资源隔离好2可水平扩展3天然支持多集群。但首次部署建议用Shell Script Delegate即传统脚本方式因为它启动快、调试直观、不依赖 K8s。Windows Git Bash 部署流程登录 Harness Platform UI → Account Settings → Delegates → Add Delegate → Shell Script复制生成的delegate.sh脚本在 Windows 上打开 Git Bash执行# 创建工作目录 mkdir -p /d/harness-work # 进入目录并下载脚本 cd /d/harness-work curl -O https://app.harness.io/storage/.../delegate.sh # 粘贴你复制的完整 URL chmod x delegate.sh # 修改脚本找到 JAVA_CMD 行改为 JAVA_CMDjava -Dharness.delegate.workDir/d/harness-work -jar # 启动 ./delegate.sh启动后UI 上 Delegate 状态变为Connected即成功。Linux/macOS 部署流程更简单# 创建目录 mkdir -p /opt/harness-work # 下载并启动URL 同上 curl -O https://app.harness.io/storage/.../delegate.sh chmod x delegate.sh ./delegate.sh关键验证点Delegate 日志中出现Delegate registered successfully with account [YOUR_ACCOUNT_ID]UI 上 Delegate 的Last Heartbeat时间在 30 秒内在 Delegate 服务器上执行ps aux \| grep harness应看到java -jar delegate.jar进程。4.4 创建第一条流水线从零开始的 7 步实操现在进入最激动人心的环节——创建第一条流水线。全程在 Harness UI 中操作无需写 YAML后续可导出Step 1创建 GitLab Connector进入 Project → Connectors → Add Connector → GitNamegitlab-prodConnection TypeHTTPSURLhttps://gitlab.your-company.comAuthenticationPersonal Access Token粘贴之前创建的harness-ci-tokenTest Connection → 应显示Connection successful。Step 2创建 Harbor ConnectorConnectors → Add Connector → Docker RegistryNameharbor-prodURLhttps://harbor.your-company.comAuthenticationUsername and Password填入 Robot Account 凭据Advanced → 勾选Skip SSL verification若用自签名证书Test Connection → 显示Connection successful。Step 3创建 PipelinePipelines → Create a Pipeline → Inline YAMLPaste 3.3 节的最小 YAML替换YOUR_K8S_CONNECTOR_ID为你实际的 K8s Connector IDSave。Step 4配置触发器TriggerPipeline → Triggers → Add TriggerNameon-main-pushEventPushBranchmainGit Connector选择gitlab-prodRepository搜索并选择你的项目如team-a/my-app。Step 5配置 Secrets密钥Account Resources → Secrets → Add Secret → TextNameharbor-creds-usernameValueharbor-robot$team-aAdd Secret → TextNameharbor-creds-passwordValuexxxxxxxxxxRobot Account 密码。Step 6编辑 Pipeline YAML注入 SecretsPipeline → Edit YAML找到push-harborStep将username和password字段改为username: ${secrets.getValue(harbor-creds-username)} password: ${secrets.getValue(harbor-creds-password)}Step 7手动运行流水线Pipeline → Run PipelineBranchmainRun。等待 2-5 分钟观察 Execution Logs。成功标志Checkout CodeStep 显示Cloned repository successfullyBuild Docker ImageStep 显示Successfully built xxxxxxxxPush to HarborStep 显示The push refers to repository [harbor.your-company.com/team-a/app]登录 Harbor Web UI → Projects →team-a→ Repositories →app应看到新 Tag。5. 常见问题与排查技巧实录5.1 “Login failed. Check API token or GitLab version” 错误全解析这是 Harness 连接 GitLab 最高频报错但背后有 5 种完全不同的原因需逐层排查现象根本原因排查命令解决方案日志中出现401 UnauthorizedToken 过期或权限不足curl -I -H PRIVATE-TOKEN: xxx https://gitlab.your-company.com/api/v4/user重新生成 Token确保勾选apiscope日志中出现403 Forbidden用户账户被 GitLab Admin 设置为pending approvalcurl -H PRIVATE-TOKEN: xxx https://gitlab.your-company.com/api/v4/user联系 Admin 在 Admin Area → Users 页面批准该账户日志中出现500 Internal Server ErrorGitLab 12.6.4 的 Merge Request Approvals Bugcurl -H PRIVATE-TOKEN: xxx https://gitlab.your-company.com/api/v4/projects?searchmy-project进入项目 → Merge Requests → 添加空的 Approval Rule日志中出现404 Not FoundHarness 配置的 Project ID 错误非项目名curl -H PRIVATE-TOKEN: xxx https://gitlab.your-company.com/api/v4/projects/12345用curl列出所有项目找到正确 IDcurl -H PRIVATE-TOKEN: xxx https://gitlab.your-company.com/api/v4/projects?per_page100 | jq .[].id, .[].name日志中无任何 HTTP 状态码只显示Connection refusedGitLab 服务器防火墙未开放 443 端口telnet gitlab.your-company.com 443检查 GitLab 服务器安全组放行 Delegate 所在 IP 的 443 端口实操心得我养成了一个习惯——每次配置新 Connector 前先用curl手动模拟 Harness 的请求。因为curl的错误信息比 Harness 日志详细 10 倍且能快速定位是网络层、证书层还是应用层问题。5.2 Harbor 推送失败的 4 类典型场景及修复场景表现根本原因修复命令denied: requested access to the resource is deniedPush to HarborStep 报错Harbor Robot Account 权限未分配给目标项目进入 Harbor → Projects →team-a→ Members → Add Member → 选择 Robot Account → Role:Developerunauthorized: authentication requiredPush to HarborStep 报错Harness YAML 中username/password未正确引用 Secret检查 YAMLusername: ${secrets.getValue(harbor-creds-username)}确认 Secret 名称拼写完全一致区分大小写x509: certificate signed by unknown authorityPush to HarborStep 报错Delegate 未信任 Harbor 证书将 Harbor CA 证书导入 Delegate 的cacertskeytool -import -trustcacerts -file ca.crt -alias harbor-ca -keystore /opt/harness-delegate/certs/cacertsno basic auth credentialsPush to HarborStep 报错Harbor 启用了HTTP Basic Auth但 Connector 未配置在 Harbor Connector 的Authentication中选择Username and Password而非Anonymous5.3 Windows Delegate 构建失败的 3 个致命陷阱陷阱现象原因解决方案The system cannot find the path specified