目录
-
- 引言
-
- Harness 是什么
- 2.1 Harness 组件全景
-
- 核心概念:先把术语讲清楚
- 3.1 Project / Org / Account
- 3.2 Pipeline / Stage / Step
- 3.3 Service / Environment / Infrastructure
- 3.4 Connector / Delegate
- 3.5 Template / Variable
-
- 架构与执行流程
-
- 环境准备与安装
- 5.1 需要准备什么
- 5.2 创建项目和 Delegate
- 5.3 创建 Connectors
-
- 第一条 CI 流水线:构建与测试
- 6.1 Pipeline YAML 全貌
- 6.2 关键 Step 解读
- 6.3 内建表达式
-
- CD 实战:部署到 Kubernetes
- 7.1 准备部署清单
- 7.2 CD Stage 配置
- 7.3 部署策略对比
-
- 高级实战技巧
- 8.1 变量分层与环境隔离
- 8.2 用 Template 消除重复
- 8.3 人工审批
- 8.4 自动回滚
- 8.5 失败策略与重试
-
- 项目实战:一个完整的交付 Pipeline
- 触发方式
-
- 生产落地建议与避坑
- 10.1 Delegate 别装错地方
- 10.2 密钥管理
- 10.3 权限最小化
- 10.4 关注执行成本与时长
- 10.5 小步推广
-
- 总结
1. 引言
在云原生与微服务浪潮下,持续集成(CI)、持续交付(CD)已经从"可选实践"变成了工程团队的默认能力。提到 CI/CD,很多人会想到 Jenkins、GitLab CI、GitHub Actions,但真正在企业级场景中,一位后来者正以"易用、可控、可观测"快速崛起------它就是 Harness。
Harness 不只是一个跑流水线的工具,它把「软件交付」抽象成了一套完整的工程化体系:CI 负责构建与测试,CD 负责部署与发布,IaCM 管理基础设施,FF 做特性开关,以及贯穿始终的治理、审计、成本与回滚能力。
本文不会停留在官方文档的搬运,而是从一个真实项目出发,带你完成:
- 理解 Harness 的核心概念与架构;
- 搭建自己的 Harness 环境与 Delegate;
- 编写第一条可运行的 CI 流水线;
- 实现从构建到 K8s 部署的完整 CD 流水线;
- 掌握变量、模板、审批、回滚等实战技巧;
- 梳理生产环境落地时的避坑建议。
读完本文,你应该能把 Harness 用在一个中小型项目中,并具备向团队推广的基础。
2. Harness 是什么
Harness 是新一代软件交付平台,由前 AppDynamics 创始人 Jyoti Bansal 于 2017 年创立。它的核心定位是:让软件交付过程智能、安全、可观测、可治理,而不是简单地"定义一条脚本流水线"。
与传统 Jenkins 相比,Harness 有几个显著差异:
| 维度 | Jenkins | Harness |
|---|---|---|
| 模型抽象 | 自由风格/脚本化 Pipeline | 结构化 Pipeline、Stage、Step |
| 配置方式 | Groovy / UI 混杂 | YAML 优先,UI 可视化 |
| 部署策略 | 自行实现 | 内置 Canary、Blue-Green、Rolling |
| 失败处理 | 手动排查为主 | 自动回滚、失败分析 |
| 治理审计 | 较弱 | 内置 RBAC、策略、审计 |
| 运行架构 | 节点常驻 agent | Delegate 轻量代理 |
Harness 的价值并不在于"比 Jenkins 快几秒",而在于把交付流程中的人、代码、环境、审批、安全策略统一管理起来,让发布行为对团队透明、可追溯。
2.1 Harness 组件全景
Harness 平台由模块构成,实际项目中常用以下模块:
- CI(Continuous Integration):构建、测试、镜像打包;
- CD(Continuous Delivery):部署、发布策略、回滚;
- STO(Security Testing Orchestration):安全扫描编排;
- FF(Feature Flags):特性开关;
- CCM(Cloud Cost Management):云成本管理;
- SRM(Service Reliability Management):可靠性管理;
- IaCM(Infrastructure as Code Management):基础设施即代码。
本文聚焦最核心的 CI + CD,这也是绝大多数工程的起点。
3. 核心概念:先把术语讲清楚
Harness 的配置模型非常结构化,新手最容易被一堆名词绕晕。我按"从大到小"的顺序帮你梳理:
3.1 Project / Org / Account
- Account(账户):公司级租户,包含所有资源;
- Org(组织):账户下的隔离单元,如按业务线或大部门划分;
- Project(项目):实际交付的最小管理单元,包含 Pipeline、Service、Environment 等。
通常一个团队一个 Project,一个部门一个 Org。
3.2 Pipeline / Stage / Step
这是 Harness 交付流程的核心三元组:
- Pipeline:一次交付流程,由多个 Stage 串联或并行;
- Stage :流水线中的阶段,例如
Build、Test、Deploy; - Step :阶段中的具体步骤,例如
Run、Build and Push to Docker Registry。
一个典型的 Pipeline 结构:
text
Pipeline
├── Stage: Build(CI)
│ ├── Step: Run - 执行测试
│ └── Step: Build and Push - 构建镜像
├── Stage: Deploy to Staging(CD)
│ └── Step: K8s Rolling Deploy
└── Stage: Deploy to Production(CD)
├── Step: Approval - 人工审批
└── Step: K8s Rolling Deploy
3.3 Service / Environment / Infrastructure
CD 模块把"部署什么"和"部署到哪"分开了:
- Service(服务):你要交付的应用,关联镜像、manifest、变量;
- Environment(环境) :目标环境,如
dev、staging、prod; - Infrastructure Definition(基础设施定义):环境的具体落地,如某个 K8s 集群与命名空间。
这种分离的好处是:同一个 Service 可以部署到多个 Environment,而每个 Environment 又可以有不同的集群配置。
3.4 Connector / Delegate
- Connector(连接器):Harness 连接外部系统的凭证封装,如 GitHub、Docker Registry、K8s 集群、AWS;
- Delegate(代理):真正执行流水线任务的轻量组件,通常部署在你的 VPC/集群内。
连接器保存"连到哪、用什么密钥",Delegate 负责"带着任务实际去执行"。
3.5 Template / Variable
- Template(模板):把可复用的 Step、Stage 或 Pipeline 抽象出来,避免重复配置;
- Variable(变量):在 Pipeline、Stage、Step 多个层级定义,支持表达式引用。
4. 架构与执行流程
Harness 采用 SaaS 控制面 + 本地 Delegate 执行面 的架构。
#mermaid-svg-qD2K2uxvotj9ztQa{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qD2K2uxvotj9ztQa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qD2K2uxvotj9ztQa .error-icon{fill:#552222;}#mermaid-svg-qD2K2uxvotj9ztQa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qD2K2uxvotj9ztQa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qD2K2uxvotj9ztQa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qD2K2uxvotj9ztQa .marker.cross{stroke:#333333;}#mermaid-svg-qD2K2uxvotj9ztQa svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qD2K2uxvotj9ztQa p{margin:0;}#mermaid-svg-qD2K2uxvotj9ztQa .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qD2K2uxvotj9ztQa .cluster-label text{fill:#333;}#mermaid-svg-qD2K2uxvotj9ztQa .cluster-label span{color:#333;}#mermaid-svg-qD2K2uxvotj9ztQa .cluster-label span p{background-color:transparent;}#mermaid-svg-qD2K2uxvotj9ztQa .label text,#mermaid-svg-qD2K2uxvotj9ztQa span{fill:#333;color:#333;}#mermaid-svg-qD2K2uxvotj9ztQa .node rect,#mermaid-svg-qD2K2uxvotj9ztQa .node circle,#mermaid-svg-qD2K2uxvotj9ztQa .node ellipse,#mermaid-svg-qD2K2uxvotj9ztQa .node polygon,#mermaid-svg-qD2K2uxvotj9ztQa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qD2K2uxvotj9ztQa .rough-node .label text,#mermaid-svg-qD2K2uxvotj9ztQa .node .label text,#mermaid-svg-qD2K2uxvotj9ztQa .image-shape .label,#mermaid-svg-qD2K2uxvotj9ztQa .icon-shape .label{text-anchor:middle;}#mermaid-svg-qD2K2uxvotj9ztQa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qD2K2uxvotj9ztQa .rough-node .label,#mermaid-svg-qD2K2uxvotj9ztQa .node .label,#mermaid-svg-qD2K2uxvotj9ztQa .image-shape .label,#mermaid-svg-qD2K2uxvotj9ztQa .icon-shape .label{text-align:center;}#mermaid-svg-qD2K2uxvotj9ztQa .node.clickable{cursor:pointer;}#mermaid-svg-qD2K2uxvotj9ztQa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qD2K2uxvotj9ztQa .arrowheadPath{fill:#333333;}#mermaid-svg-qD2K2uxvotj9ztQa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qD2K2uxvotj9ztQa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qD2K2uxvotj9ztQa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qD2K2uxvotj9ztQa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qD2K2uxvotj9ztQa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qD2K2uxvotj9ztQa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qD2K2uxvotj9ztQa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qD2K2uxvotj9ztQa .cluster text{fill:#333;}#mermaid-svg-qD2K2uxvotj9ztQa .cluster span{color:#333;}#mermaid-svg-qD2K2uxvotj9ztQa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qD2K2uxvotj9ztQa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qD2K2uxvotj9ztQa rect.text{fill:none;stroke-width:0;}#mermaid-svg-qD2K2uxvotj9ztQa .icon-shape,#mermaid-svg-qD2K2uxvotj9ztQa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qD2K2uxvotj9ztQa .icon-shape p,#mermaid-svg-qD2K2uxvotj9ztQa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qD2K2uxvotj9ztQa .icon-shape .label rect,#mermaid-svg-qD2K2uxvotj9ztQa .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qD2K2uxvotj9ztQa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qD2K2uxvotj9ztQa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qD2K2uxvotj9ztQa :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 下发任务
拉取代码
执行构建
推送镜像
执行部署
Harness SaaS 控制面
Delegate 代理
GitHub / GitLab
CI Runner 容器
Docker Registry
K8s 集群 / 云主机
一次执行的大致流程:
- 用户在 Harness 控制台触发 Pipeline;
- 控制面解析 Pipeline YAML,确定需要哪些 Delegate;
- Delegate 从消息队列拉取任务;
- Delegate 在目标环境启动容器执行 Step;
- 每个 Step 的日志、状态实时回传控制面。
Delegate 可以是单机部署,也可以是 K8s 部署。生产环境建议用 K8s Delegate,具备更好的弹性和高可用。
5. 环境准备与安装
5.1 需要准备什么
开始之前,你需要:
- 一个 Harness 账户,免费版即可体验绝大部分功能;
- 一个代码仓库,比如 GitHub;
- 一个镜像仓库,比如 Docker Hub;
- 一个 K8s 集群(部署目标),本地 Minikube 即可;
- 一台能访问上述资源的主机,用来安装 Delegate。
5.2 创建项目和 Delegate
登录 Harness 后:
- 创建 Project,命名如
demo-app; - 进入 Delegates 页面,选择安装 K8s Delegate;
- 复制页面生成的 YAML,应用到你的 K8s 集群:
bash
kubectl apply -f delegate.yaml
kubectl get pods -n harness-delegate-ng
看到 Delegate Pod 状态为 Running,且控制台显示 CONNECTED,说明连接成功。
5.3 创建 Connectors
按实际资源创建以下连接器:
- GitHub Connector:关联你的代码仓库;
- Docker Registry Connector:关联镜像仓库;
- Kubernetes Cluster Connector:关联目标集群。
创建连接器时,Harness 会自动通过 Delegate 做连通性测试,这是排查"凭据对不对"的第一道关卡。
6. 第一条 CI 流水线:构建与测试
我们从最实用的场景开始:代码提交后自动构建、测试、推送镜像。
6.1 Pipeline YAML 全貌
在 Harness 中,所有流水线最终都以 YAML 表示。下面是一条典型 CI 流水线:
yaml
pipeline:
name: demo-ci
identifier: demo_ci
projectIdentifier: demo_app
orgIdentifier: default
tags: {}
stages:
- stage:
name: Build
identifier: Build
type: CI
spec:
cloneCodebase: true
execution:
steps:
- step:
type: Run
name: Run Tests
identifier: run_tests
spec:
connectorRef: account.docker_hub
image: node:20-alpine
shell: Sh
command: |
npm install
npm test
- step:
type: BuildAndPushDockerRegistry
name: Build and Push
identifier: build_push
spec:
connectorRef: account.docker_hub
repo: yourname/demo-app
tags:
- <+pipeline.sequenceId>
6.2 关键 Step 解读
Run Step:最基础的执行步骤,可以在指定容器镜像中运行任意 Shell 命令,适合跑测试、lint、脚本。
yaml
- step:
type: Run
name: Code Lint
identifier: code_lint
spec:
connectorRef: account.docker_hub
image: node:20-alpine
shell: Sh
command: |
npm run lint
BuildAndPushDockerRegistry Step:内置的镜像构建与推送步骤,底层封装了 docker build + push,并支持增量缓存。
6.3 内建表达式
注意上面的 <+pipeline.sequenceId>,这是 Harness 的表达式语法,会在运行时被替换为实际值。常用表达式:
| 表达式 | 含义 |
|---|---|
<+pipeline.sequenceId> |
本次执行序号 |
<+stage.name> |
阶段名称 |
<+pipeline.variables.xxx> |
管道变量 |
<+secrets.getValue("xxx")> |
获取密钥 |
表达式不仅用于 YAML,也常用在日志、通知标题中,非常灵活。
7. CD 实战:部署到 Kubernetes
有了镜像,接下来把应用部署到 K8s。这是 Harness 的看家本领。
7.1 准备部署清单
假设我们有一个很简单的 Node 应用,部署清单如下:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: <+infra.namespace>
spec:
replicas: 2
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: <+artifact.image>
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: demo-app-svc
namespace: <+infra.namespace>
spec:
selector:
app: demo-app
type: ClusterIP
ports:
- port: 80
targetPort: 3000
注意 <+artifact.image> 和 <+infra.namespace> 是 Harness 在部署时注入的运行时值,让我们能把 manifest 模板化。
7.2 CD Stage 配置
yaml
- stage:
name: Deploy to K8s
identifier: deploy_k8s
type: Deployment
spec:
service:
serviceRef: demo_service
environment:
environmentRef: demo_env
deployToAll: false
infrastructureDefinitions:
- identifier: demo_infra
execution:
steps:
- step:
type: K8sRollingDeploy
name: Rolling Deploy
identifier: rolling_deploy
timeout: 10m
rollbackSteps:
- step:
type: K8sRollingRollback
name: Rollback
identifier: rollback_step
7.3 部署策略对比
Harness CD 内置了多种部署策略,这是它比自建脚本最大的优势:
| 策略 | 原理 | 适合场景 |
|---|---|---|
| Rolling | 逐步替换旧版本 | 无状态服务,通用 |
| Canary | 小流量切换验证 | 高风险发布、核心链路 |
| Blue-Green | 新旧环境整套切换 | 需要快速回滚的场景 |
| Basic | 单次直接部署 | 简单场景、内部工具 |
以 Canary 为例,你可以按 10% → 30% → 100% 分多阶段放量,并配合验证步骤自动判断继续或回滚:
yaml
steps:
- step:
type: K8sCanaryDeploy
name: Canary 10%
identifier: canary_10
spec:
instanceSelection:
type: Count
spec:
count: 1
- step:
type: K8sCanaryDeploy
name: Canary 50%
identifier: canary_50
spec:
instanceSelection:
type: Percentage
spec:
percentage: 50
8. 高级实战技巧
8.1 变量分层与环境隔离
Harness 支持多层级变量,优先级从低到高:
text
Account < Org < Project < Pipeline < Stage < Step
典型做法是在 Environment 级别定义环境相关变量,比如数据库地址:
yaml
environment:
name: Production
identifier: production
variables:
- name: DB_HOST
type: String
value: prod-db.internal
在 Pipeline 中引用:
yaml
echo "DB is <+env.variables.DB_HOST>"
开发环境只需修改 Environment 的变量值,Pipeline 完全不用动。
8.2 用 Template 消除重复
如果公司有 20 个微服务,每个都要执行相同的"构建 + 扫描 + 推送",就应该抽象成模板。
创建 Stage Template 后,各服务的 Pipeline 只需引用模板并传入参数:
yaml
- stage:
type: CI
spec:
steps:
- step:
templateRef: account.BuildAndPushTemplate
templateInputs:
repo: yourname/payment-service
模板修改一次,所有引用处同步生效,这是企业级治理的关键。
8.3 人工审批
生产发布前加一道审批,是许多团队的硬性要求。Harness 里只需一个 Step:
yaml
- step:
type: HarnessApproval
name: Prod Approval
identifier: prod_approval
spec:
approvalMessage: 请确认生产环境发布
includePipelineExecutionHistory: true
approvers:
minimumCount: 1
userGroups:
- account.prod_reviewers
审批人会在 Harness 控制台收到待办,审批通过后流水线继续。
8.4 自动回滚
CD Stage 中配置 rollbackSteps 后,当部署失败或验证失败时,Harness 会自动执行回滚:
yaml
rollbackSteps:
- step:
type: K8sRollingRollback
name: Rollback
identifier: rollback_step
相比自己写"检测失败 → 调用旧版本"的脚本,内置回滚要可靠得多。
8.5 失败策略与重试
可以在 Step 级别配置失败策略:
yaml
- step:
type: Run
name: Flaky Integration Test
identifier: flaky_test
spec:
command: ./run-integration-test.sh
failureStrategies:
- onFailure:
errors:
- AllErrors
action:
type: Retry
spec:
retryCount: 2
retryIntervals:
- 30s
- 1m
这样对偶发失败的网络测试非常实用,避免整条流水线动不动就红。
9. 项目实战:一个完整的交付 Pipeline
下面把前面的内容串起来,构建一个真实可用的流水线:代码提交 → 测试构建 → 推送镜像 → 部署 Staging → 部署 Prod(带审批)。
yaml
pipeline:
name: demo-app-delivery
identifier: demo_app_delivery
projectIdentifier: demo_app
orgIdentifier: default
stages:
- stage:
name: CI Build
identifier: ci_build
type: CI
spec:
cloneCodebase: true
execution:
steps:
- step:
type: Run
name: Test
identifier: test
spec:
connectorRef: account.docker_hub
image: node:20-alpine
shell: Sh
command: |
npm install
npm test
- step:
type: BuildAndPushDockerRegistry
name: Push Image
identifier: push_image
spec:
connectorRef: account.docker_hub
repo: yourname/demo-app
tags:
- <+pipeline.sequenceId>
- stage:
name: Deploy Staging
identifier: deploy_staging
type: Deployment
spec:
service:
serviceRef: demo_service
environment:
environmentRef: staging_env
infrastructureDefinitions:
- identifier: staging_infra
execution:
steps:
- step:
type: K8sRollingDeploy
name: Deploy
identifier: deploy
- stage:
name: Deploy Production
identifier: deploy_prod
type: Deployment
spec:
service:
serviceRef: demo_service
environment:
environmentRef: prod_env
infrastructureDefinitions:
- identifier: prod_infra
execution:
steps:
- step:
type: HarnessApproval
name: Approval
identifier: approval
spec:
approvalMessage: 确认发布到生产环境
approvers:
minimumCount: 1
userGroups:
- account.prod_reviewers
- step:
type: K8sRollingDeploy
name: Deploy
identifier: deploy
- step:
type: K8sRollingRollback
name: Rollback
identifier: rollback
触发方式
在 Pipeline 的 Triggers 中添加 Webhook 触发器,选择 GitHub 事件 Push to main。之后每一次合并到 main 分支,整条交付链路自动跑起来。
10. 生产落地建议与避坑
10.1 Delegate 别装错地方
Delegate 必须能访问你的代码仓库、镜像仓库和目标集群。如果 Delegate 和一个私有仓库不在同一网络,连接器的连通性测试会直接失败。常见做法是把 Delegate 部署在目标 K8s 集群中,或与 CI 构建资源同网段。
10.2 密钥管理
不要把数据库密码、镜像仓库密码写进 Pipeline YAML。统一使用 Secrets Manager 或 Harness 内置密钥,通过:
yaml
<+secrets.getValue("prod_db_password")>
引用。密钥与 Pipeline 解耦,也方便轮换。
10.3 权限最小化
不要给所有人 Production 环境的部署权限。利用 Harness 的 RBAC:
- 开发者:只能操作 Dev/Staging;
- 发布负责人:可操作 Production;
- 运维/安全:只读或审计权限。
权限矩阵建议在项目启动时就定好,事后补救成本很高。
10.4 关注执行成本与时长
Harness 按 CI 构建分钟数等维度计费。注意:
- 合理设置 Build 缓存,避免每次都全量拉依赖;
- 并行拆分测试 Stage;
- 对无明显收益的 Step 设置超时,避免挂起。
10.5 小步推广
不要一上来把全部服务迁到 Harness。建议选一个边界清晰、部署频繁的服务做试点,跑通"构建 - 部署 - 回滚 - 审计"全流程后,再逐步推广。同时沉淀 Template 和命名规范,避免重蹈 Jenkins "千奇百怪流水线"的覆辙。
11. 总结
Harness 的核心竞争力在于"结构化":Pipeline、Stage、Step 层次清晰,Service 与 Environment 分离,变量与模板消除重复,内置策略与回滚降低操作风险。对工程团队来说,它更像一套交付操作系统,而不是又一个需要自己维护插件的脚本执行器。
本文从一个空项目出发,走完了:
- 理解核心概念;
- 部署 Delegate 与连接外部资源;
- 编写 CI 流水线完成测试和镜像构建;
- 借助 K8s Deployment 实现滚动部署;
- 引入模板、审批、回滚等企业级能力;
- 串起完整的 Staging → Production 交付链路。
如果你正准备把 Harness 引入团队,建议从最小可行的交付链路开始,先把"提交即构建、审批后发布、失败可回滚"这三件事做扎实,再逐步叠加安全扫描、成本管理、特性开关等模块。
工程化的本质不是工具多强大,而是流程可重复、结果可预期。Harness 恰好是把这两件事做到位的那个平台。