第 7/60 天
引言
过去六天,我们从技术选型(第 1 天)、工具全景对比(第 2 天)、全链路架构设计(第 3 天)出发,分别深入了 Tekton(第 4 天)、Argo CD(第 5 天)、Harbor(第 6 天)的核心概念。三个组件单独看都很强大,但生产环境的真正价值在于把它们串成一条端到端的自动化链路:
代码提交 → Tekton 构建镜像 → Harbor 存储制品 → GitOps 仓库更新 → Argo CD 同步部署 → 生产集群运行
这一篇是第 1 周的收官之作,我们不再逐个组件讲解,而是把三件套拼成一张完整的”全链路地图”:数据流怎么走、每个环节的职责边界在哪里、集成点有哪些、一次完整的发布旅程长什么样。同时给出最小可运行的三件套联动 YAML 示例,为第 2 ~ 5 周的深入实战建立整体认知框架。
核心概念
三件套的分工与边界
| 组件 | 定位 | 职责 | 核心资源 |
|---|---|---|---|
| Tekton | CI(持续集成) | 拉代码、跑测试、构建镜像、推送制品、产出构建结果 | Task / Pipeline / PipelineRun / Trigger |
| Harbor | 制品仓库 | 存储 OCI 制品、权限隔离、漏洞扫描、复制分发 | Project / Robot Account / Replication / Scan |
| Argo CD | CD(持续交付) | 声明式 GitOps 同步、漂移检测、多环境/多集群交付 | Application / Project / Sync Policy |
关键原则:Tekton 负责”把代码变成制品”、Harbor 负责”把制品安全地存起来并发出去”、Argo CD 负责”把制品按 Git 声明部署到集群”。三者之间尽量只通过制品和 Git 进行松耦合交互,不互相调用内部 API。
端到端数据流(Pull 模型)
[开发者] ──git push──▶ [应用仓库 GitHub/GitLab]
│ webhook 事件
▼
[Tekton EventListener] ──▶ TriggerTemplate
│ 生成 PipelineRun
▼
[Tekton Pipeline: 拉码 → 测试 → kaniko 构建 → 推送]
│ docker login (Harbor Robot Account)
▼
[Harbor 镜像仓库]
(扫描/签名/复制)
│ CI 更新 GitOps 仓库中的镜像 tag(提交)
▼
[GitOps 配置仓库 deployment.yaml]
│ Argo CD 检测到与集群状态不一致(漂移)
▼
[Argo CD Application 执行 Sync]
│ kube-apiserver 下发滚动更新
▼
[K8s 集群 Deployment] ──pull──▶ [Harbor 拉取新镜像]
注意 Argo CD 是 Pull 模型:它主动从 Git 仓库拉取期望状态与集群实际状态对比,发现不一致就收敛(Sync/自愈),而不是由 Harbor 或 CI 主动”推”给集群。这是 GitOps 与传统 CD 工具最本质的区别。
集成点与松耦合解耦原则
| 集成点 | 交互方式 | 避免的耦合 |
|---|---|---|
| Tekton ↔ Harbor | 推送镜像(robot account 认证) | 不要用管理员密码 |
| Tekton ↔ GitOps 仓库 | 更新镜像 tag 并提交 | 不要直接调用 Argo CD API |
| Harbor ↔ Argo CD | 仅通过”镜像名+tag 约定” | Argo CD 不感知 Harbor 内部结构 |
| Git ↔ Argo CD | 监听仓库变化 | 不需要 webhook 也能跑(轮询) |
镜像不可变标签:衔接 CI 与 CD 的契约
三件套联动的核心契约是镜像 tag 策略。生产环境强烈建议使用不可变、可追溯的标签:
harbor.example.com/team-a/order-service:main-3f2a9c1-20260818-0715
└── 项目 ──┘└──── 应用 ────┘└── 分支-SHA-时间戳 ──┘
每个构建产物有唯一身份,CI 产出它、Harbor 保存它、Argo CD 通过 GitOps 仓库引用它——任何一个环节出问题,都能从 tag 精准回溯到某一次 commit。
实战步骤
下面给出三件套联动的最小可运行骨架。整体上我们在同一集群中:Tekton 建在 tekton-pipelines 与 cicd 命名空间,Harbor 部署在 harbor 命名空间(假设域名 harbor.example.com),Argo CD 在 argocd 命名空间,应用部署到 production 命名空间。
步骤 1:创建 Harbor Robot Account(一次性准备)
Robot Account(机器人账号)是给 Tekton CI 用的自动化凭证。权限最小化:仅对 team-a 项目有推送权。用 Harbor API 创建:
# 先登录获取会话,管理员身份创建 robot account
ADMIN_PASS='your-admin-password'
curl -s -u "admin:${ADMIN_PASS}" -H "Content-Type: application/json"
-X POST https://harbor.example.com/api/v2.0/robots
-d '{
"name": "tekton-ci",
"duration": -1,
"level": "project",
"permissions": [{
"kind": "project",
"namespace": "team-a",
"access": [
{"resource": "repository", "action": "push"},
{"resource": "repository", "action": "pull"}
]
}]
}'
# 响应中的 secret 即为推送密码(只显示一次,保存好!)
# 格式: robot$team-a+tekton-ci / <secret>
步骤 2:把 Robot Credential 做成 K8s Secret(dockerconfigjson)
Tekton 推送镜像时使用标准的 docker login 凭证。把 robot account 转成 dockerconfigjson Secret,并关联到 Tekton 使用的 ServiceAccount:
apiVersion: v1
kind: Secret
metadata:
name: harbor-robot-push
namespace: cicd
annotations:
tekton.dev/docker-0: https://harbor.example.com # Tekton 识别的 docker 凭证注解
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"https://harbor.example.com": {
"username": "robot$team-a+tekton-ci",
"password": "REPLACE_WITH_ROBOT_SECRET",
"auth": "REPLACE_WITH_base64(user:pass)"
}
}
}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: pipeline-runner
namespace: cicd
secrets:
- name: harbor-robot-push
步骤 3:Tekton Pipeline——构建并推送镜像到 Harbor
一个完整的 CI Pipeline:clone 代码 → 单元测试 → kaniko 构建 → 推送到 Harbor。注意以 Git commit SHA 生成不可变 tag 并通过 results 传递给下游:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: build-and-push
namespace: cicd
spec:
workspaces:
- name: source # 共享源码目录
- name: dockerconfig # 挂载 Harbor 凭证
params:
- name: git-url
type: string
- name: git-revision
type: string
- name: image
type: string
default: harbor.example.com/team-a/order-service
results:
- name: image-tag # 供下游(更新 GitOps 仓库)使用
tasks:
- name: clone
taskRef:
name: git-clone
params:
- name: url
value: $(params.git-url)
- name: revision
value: $(params.git-revision)
workspaces:
- name: output
workspace: source
- name: test
runAfter: [clone]
taskSpec:
steps:
- name: go-test
image: golang:1.22
workingDir: $(workspaces.source.path)
script: |
go test ./... -race -cover
go vet ./...
workspaces:
- name: source
workspace: source
- name: build-push
runAfter: [test]
workspaces:
- name: source
workspace: source
- name: dockerconfig
workspace: dockerconfig
params:
- name: image
value: $(params.image)
- name: git-revision
value: $(params.git-revision)
taskSpec:
params:
- name: image
- name: git-revision
workspaces:
- name: source
- name: dockerconfig
results:
- name: image-tag
description: 完整镜像引用
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v1.20.0
env:
- name: DOCKER_CONFIG
value: /builder/home/.docker
args:
- --context=$(workspaces.source.path)
- --dockerfile=$(workspaces.source.path)/Dockerfile
- --destination=$(params.image):$(params.git-revision)
- --cache=true
- --cache-repo=harbor.example.com/team-a/cache
- --push-retry=3
volumeMounts:
- name: docker-config
mountPath: /builder/home/.docker
volumes:
- name: docker-config
secret:
secretName: harbor-robot-push
items:
- key: .dockerconfigjson
path: config.json
results:
- name: image-tag-description
说明:
+号在 YAML/Shell 中建议加引号;kaniko 通过DOCKER_CONFIG指向挂载的 dockerconfig.json,不需要集群内 Docker daemon。这是第 15 天将要深度展开的内容。
步骤 4:CI 更新 GitOps 仓库(把新 tag 写进配置仓库)
镜像构建完成并推送到 Harbor 后,CI 需要把新的 image tag 提交进 GitOps 配置仓库,Argo CD 才会知道”期望状态变了”。使用 Git clone + sed + commit 的方式:
# 在 Tekton pipeline 的 gitops-update task 中执行
git clone https://x-access-token:${GIT_TOKEN}@github.com/example/gitops-repo.git /tmp/gitops
cd /tmp/gitops
# 更新 kustomize 的 images 段(也可以是 helm values 或纯 deployment.yaml)
sed -i "s|harbor.example.com/team-a/order-service:.*|harbor.example.com/team-a/order-service:${NEW_TAG}|g"
apps/order-service/overlays/production/kustomization.yaml
git config user.name "tekton-ci"
git config user.email "ci@example.com"
git add apps/order-service/overlays/production/kustomization.yaml
git commit -m "chore(order-service): bump image to ${NEW_TAG} [skip ci]"
git push origin main
步骤 5:Argo CD Application——声明式交付到生产集群
Argo CD 每 3 分钟(默认)轮询 GitOps 仓库,一旦检测到配置变更就自动同步:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: order-service
namespace: argocd
spec:
project: production
source:
repoURL: https://github.com/example/gitops-repo.git
targetRevision: main
path: apps/order-service/overlays/production
kustomize: {}
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated: # 自动同步 + 自愈(第 23 天详解)
prune: true # 删除 Git 中已移除的资源
selfHeal: true # 手动改动会被 Git 状态覆盖
syncOptions:
- CreateNamespace=true
# 使用 Git 中的镜像引用;生产建议结合 argocd-image-updater(第 31 天)
步骤 6:配置仓库里的目标状态(引用来自 Harbor 的镜像)
Argo CD 同步时最终会通过 K8s 下发这样一个 Deployment——注意 image 不是硬编码,而是从 Kustomize overlay 注入:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: production
labels:
app: order-service
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
# 通过 imagePullSecrets 从 Harbor 拉私有镜像
imagePullSecrets:
- name: harbor-pull-secret
containers:
- name: order-service
image: harbor.example.com/team-a/order-service:main-3f2a9c1-20260818-0715
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
步骤 7:全链路验证与观察
# 1) 查看 Tekton 流水线运行状态
tkn pipelinerun list -n cicd
tkn pipelinerun logs $(tkn pipelinerun list -n cicd --no-headers | head -1 | awk '{print $1}') -n cicd
# 2) 确认镜像已进入 Harbor(用 robot account 查询制品清单)
curl -s -u "robot$team-a+tekton-ci:${ROBOT_SECRET}"
"https://harbor.example.com/api/v2.0/projects/team-a/repositories/order-service/artifacts?with_tag=true"
| python3 -m json.tool | head -40
# 3) 观察 Argo CD Application 健康状态
kubectl -n argocd port-forward svc/argocd-server 8080:443 >/dev/null 2>&1 &
argocd app get order-service --grpc-web
argocd app sync order-service # 手动触发一次同步(自动同步下通常不需要)
# 4) 验证生产 Pod 是否滚动更新成功
kubectl rollout status deployment/order-service -n production
kubectl get pods -n production -l app=order-service
常见问题
1. Argo CD 为什么不直接监听 Harbor 的新镜像?
GitOps 的铁律是 Git 是唯一事实来源(Source of Truth)。如果 Argo CD 直接盯着 Harbor 的 tag 变化部署,就绕过了 Git,既无法审计也无法回滚(状态不可收敛到 Git 声明)。正确姿势是:CI 把新 tag 提交进 GitOps 仓库,Argo CD 检测到 Git 变化后再同步。需要”镜像一更新就立即部署”的场景,用 argocd-image-updater(第 31 天)自动提交 Git,仍然是”先进 Git 再同步”。
2. 镜像 tag 用 latest 可以吗?
不可以(生产环境)。latest 是可变、不可追溯的:同一个 tag 在不同时间指向不同内容,回滚时你不知道跑的是哪个版本,K8s 的 imagePullPolicy 还可能因 tag 相同而跳过拉取。务必使用 commit SHA / SemVer + SHA 拼接的不可变 tag(详见第 45 天)。
3. Tekton 推送镜像到 Harbor 报 401 Unauthorized?
大概率是 robot account 问题:① robot account 已过期(创建时 duration=-1 才是永不过期,默认会有有效期);② 权限只给了 push 没给项目读权限;③ dockerconfigjson 里 base64 的 auth 写错。先用 curl -u 'robot$team-a+tekton-ci:<secret>' https://harbor.example.com/v2/ 验证凭证本身是否可用。
4. Argo CD 同步成功了,但 Pod 还在跑旧镜像?
检查三点:① GitOps 仓库里的 image tag 是否真的更新并 push 成功(git log 确认);② Deployment 的 imagePullPolicy——tag 不变时即使模型不一致也可能不拉新镜像,用不可变 tag 天然规避;③ Argo CD 轮询间隔默认 3 分钟,selfHeal 只修配置漂移,不负责”发现新 tag”(新 tag 必须来自 Git 提交)。
5. Webhook 触发不稳定,Tekton EventListener 收不到事件?
排查顺序:① EventListener Service 是否被 Ingress/NodePort 正确暴露、Harbor 或 Git 平台能否访问到;② TriggerBinding/TriggerTemplate 的 event 字段与平台 webhook payload 字段是否匹配;③ 是否配置了 interceptor 的 secret 校验,签名不匹配会被静默丢弃;④ 事件投递失败可先用 curl 手动 POST 一个模拟 payload 验证链路(第 12~13 天详解)。
6. 谁负责更新 GitOps 仓库?CI 里提交还是人工 PR?
两种都可以,取决于团队的变更审批要求:小团队/实验环境用 Tekton 里 git-clone + commit + push 全自动;有审批要求的团队建议 Tekton 只创建 PR,由负责人 review 合并后再触发 Argo CD 同步。关键是一旦引入自动化提交,务必在 commit message 加 [skip ci] 防止触发死循环。
总结
- 一条主线:代码提交 → Tekton 构建 → Harbor 存储 → 更新 GitOps 仓库 → Argo CD 同步 → 生产集群,三件套通过”镜像 + Git”两个契约松耦合联动。
- Pull 模型:Argo CD 主动从 Git 收敛集群状态,而非被推送部署——这是 GitOps 与 Jenkins 式 CD 的本质区别,也是可审计、可回滚的根基。
- Robot Account 是 CI 与 Harbor 之间的凭证桥梁:最小权限、可独立管理、可轮换,绝不能在流水线里写死管理员密码。
- 不可变 tag 是全链路的可追溯性契约:CI 产出唯一制品、Harbor 安全存储、GitOps 精确引用,任何一个环节出问题都能靠 tag 回溯。
- 骨架已就绪:今天的最小联动 YAML 是后续 53 天的”地图”——第 2 周深入 Tekton CI、第 3 周深入镜像构建与 Harbor、第 4 周深入 Argo CD、第 5 周做三件套完整实战。
下期预告
第 8 天:在 Kubernetes 上安装 Tekton Pipelines——kubectl 与 Operator 两种方式
从第 2 周开始我们进入 Tekton CI 深入专题。第 8 天将手把手带你完成 Tekton Pipelines 的两种安装方式(kubectl apply 快速安装 vs Tekton Operator 管理安装),并验证安装结果、了解版本升级与卸载注意事项,为后续所有 Tekton 实战打好地基。
📖 系列目录
- 第 1 天:为什么选择 Tekton + Argo CD + Harbor 三件套——生产级 DevOps 技术选型
- 第 2 天:CI/CD 工具链全景对比——Jenkins、GitLab CI、Tekton、Argo CD、Harbor 怎么选
- 第 3 天:生产环境 DevOps 架构设计——从代码提交到上线的全链路蓝图
- 第 4 天:Tekton 核心概念入门——Task、Pipeline、PipelineRun、Step 详解
- 第 5 天:Argo CD 核心概念入门——Application、Project、Sync 策略详解
- 第 6 天:Harbor 核心概念入门——Registry、Project、Robot Account 详解
- 第 7 天:三件套集成总览——Tekton 构建 → Harbor 存储 → Argo CD 部署的端到端流程 ← 本篇
- 第 8 天:在 Kubernetes 上安装 Tekton Pipelines:kubectl 与 operator 两种方式 🔜
- 第 9 天:Tekton Task 与 Step 实战:编写第一个构建任务 🔜
- 第 10 天:Tekton Pipeline 实战:多阶段流水线的编排与依赖 🔜
- 第 11 天:Tekton 参数、Results 与 Workspaces:流水线数据流核心机制 🔜
- 第 12 天:Tekton Triggers:用 Webhook/Binding/EventListener 触发流水线 🔜
- 第 13 天:Tekton 事件驱动 CI:给流水线接入 GitHub/GitLab 事件 🔜
- 第 14 天:tkn CLI 完全指南:用命令行管理 Tekton 资源 🔜
- 第 15~60 天:镜像构建与 Harbor、Argo CD 深入、三件套集成实战、GitOps 进阶、生产实践与运维、生态与扩展、高级主题与展望 🔜















暂无评论内容