第 17/19 天
引言:把所有齿轮咬合在一起

经过前 16 天的逐层搭建,我们已经拥有了 Harbor 私有镜像仓库、GitLab 代码托管平台与 CI 流水线、SonarQube 代码质量门禁、Argo CD GitOps 引擎、Prometheus + Grafana 可观测性体系,以及 Argo Rollouts 渐进式交付能力。这些组件如同一个个独立齿轮,单独运转时只能发出嗡嗡声,真正让 DevOps 管道”转起来”的是把它们咬合在一起的端到端流程。
今天这一篇是全链路的”总装演示”。我们将从一次真实的代码提交开始,走完 提交 → 构建 → 代码检查 → 镜像推送 → GitOps 同步 → 金丝雀灰度 → 指标分析 → 自动推进/回滚 → 监控告警 的完整闭环,验证每个环节的衔接是否顺畅,并定位最常见的断点。
核心概念:端到端流水线的数据流
在动手演示之前,先理清数据在各组件间的流向。一条完整的 DevOps 管道包含两条核心链路:
- CI 链路(推送链路):开发者提交代码 → GitLab 触发流水线 → Kaniko 构建镜像并推送到 Harbor → SonarQube 质量检查 → 更新 GitOps 配置仓库中的镜像 Tag。
- CD 链路(同步链路):Argo CD 监听配置仓库变更 → 同步 Rollout 资源到 K8s → Argo Rollouts 按策略执行金丝雀 → AnalysisTemplate 查询 Prometheus 指标 → 自动推进或回滚。
两条链路通过 GitOps 配置仓库 这个”接合齿轮”咬合:CI 只负责把新镜像 Tag 写进 Git,CD 只负责把 Git 中的声明同步到集群,两者解耦又协同。
开发者 ──git push──▶ GitLab ──CI──▶ Harbor(镜像) + SonarQube(质量)
│
更新 Tag ──▶ GitOps 配置仓库
│
Argo CD 监听同步
│
Argo Rollouts 金丝雀
│
AnalysisTemplate ← Prometheus 指标
│
自动推进 / 回滚
│
Grafana 看板 + Alertmanager 告警
实战步骤一:准备演示工程
我们用一个极简的 Go HTTP 服务作为演示工程,它能暴露 /version 端点返回当前版本号,并暴露 /metrics 供 Prometheus 采集。
# 初始化演示工程
mkdir -p ~/demo-app && cd ~/demo-app
git init
git remote add origin git@gitlab.stellardata.top:devops/demo-app.git
# 目录结构
mkdir -p deploy/manifests deploy/rollout k8s
touch main.go Dockerfile .gitlab-ci.yml sonar-project.properties
deploy/rollout/rollout.yaml deploy/rollout/analysis.yaml
k8s/service.yaml k8s/ingress.yaml
核心代码 main.go 如下:
package main
import (
"fmt"
"net/http"
"os"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
version := os.Getenv("APP_VERSION")
if version == "" {
version = "unknown"
}
http.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "version: %sn", version)
})
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
实战步骤二:编写 GitLab CI 流水线
.gitlab-ci.yml 是 CI 链路的”大脑”,它串起构建、扫描、质量检查和配置回写四个阶段。注意每个阶段都要设为 rules 条件触发,避免无效运行。
stages:
– build
– quality
– publish
– sync
variables:
HARBOR_REGISTRY: "harbor.stellardata.top"
IMAGE_NAME: "${HARBOR_REGISTRY}/devops/demo-app"
IMAGE_TAG: "${CI_COMMIT_SHORT_SHA}"
# 阶段1:Kaniko 无守护进程构建
build_image:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
– mkdir -p /kaniko/.docker
– echo "{"auths":{"${HARBOR_REGISTRY}":{"auth":"$(echo -n 'robot$ci:Harbor12345' | base64)"}}}" > /kaniko/.docker/config.json
– /kaniko/executor
–context "${CI_PROJECT_DIR}"
–dockerfile "${CI_PROJECT_DIR}/Dockerfile"
–destination "${IMAGE_NAME}:${IMAGE_TAG}"
–destination "${IMAGE_NAME}:latest"
–cache=true
# 阶段2:SonarQube 代码质量门禁
sonar_check:
stage: quality
image: sonarsource/sonar-scanner-cli:latest
script:
– sonar-scanner
-Dsonar.projectKey=demo-app
-Dsonar.host.url=http://sonarqube.stellardata.top
-Dsonar.login=${SONAR_TOKEN}
allow_failure: false
# 阶段3:Trivy 镜像漏洞扫描
trivy_scan:
stage: publish
image: aquasec/trivy:latest
script:
– trivy image –exit-code 1 –severity HIGH,CRITICAL "${IMAGE_NAME}:${IMAGE_TAG}"
# 阶段4:更新 GitOps 配置仓库中的镜像 Tag
sync_gitops:
stage: sync
image: alpine/git:latest
script:
– git clone https://gitlab-ci-token:${GITOPS_TOKEN}@gitlab.stellardata.top/devops/gitops-config.git
– cd gitops-config
– sed -i "s|image:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" apps/demo-app/rollout.yaml
– git commit -am "chore: update demo-app to ${IMAGE_TAG}"
– git push origin main
only:
– main
这条流水线把”构建产物”和”配置变更”解耦:前三个阶段产出镜像并验证质量,第四个阶段只做一件轻量的事——把新 Tag 写进 GitOps 仓库。Argo CD 会监听到这个 Git 提交,自动触发下游 CD 链路。
实战步骤三:配置 Argo CD Application 与 Rollout
GitOps 配置仓库中的 apps/demo-app/rollout.yaml 定义了 Argo Rollouts 资源,它是 CD 链路的核心声明。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: demo-app
namespace: demo
labels:
app: demo-app
spec:
replicas: 4
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
– name: demo-app
image: harbor.stellardata.top/devops/demo-app:placeholder
ports:
– containerPort: 8080
env:
– name: APP_VERSION
valueFrom:
fieldRef:
fieldPath: metadata.labels['rollouts.argoproj.io/revision']
readinessProbe:
httpGet:
path: /version
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
strategy:
canary:
canaryService: demo-app-canary
stableService: demo-app-stable
trafficRouting:
nginx:
stableIngress: demo-app-ingress
steps:
– setWeight: 20
– pause: { duration: 2m }
– analysis:
templates:
– templateName: success-rate
– setWeight: 50
– pause: { duration: 2m }
– analysis:
templates:
– templateName: success-rate
– setWeight: 100
– pause: { duration: 1m }
analysis.yaml 定义了基于 Prometheus 指标的自动推进/回滚策略。当金丝雀 Pod 的 HTTP 错误率超过阈值时,Rollouts 会自动中止并回滚。
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: demo
spec:
metrics:
– name: success-rate
interval: 30s
count: 5
successCondition: result[0] >= 0.95
failureLimit: 2
provider:
prometheus:
address: http://prometheus-server.monitoring.svc:9090
query: |
sum(rate(http_requests_total{job="demo-app",status!~"5.."}[2m]))
/
sum(rate(http_requests_total{job="demo-app"}[2m]))
Argo CD 的 Application 声明把 GitOps 仓库与集群同步关联起来:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: demo-app
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.stellardata.top/devops/gitops-config.git
targetRevision: main
path: apps/demo-app
destination:
server: https://kubernetes.default.svc
namespace: demo
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
– CreateNamespace=true
实战步骤四:触发端到端流程
一切就绪后,用一次代码提交点燃整条管道。我们故意把版本号写进代码,方便后续在金丝雀阶段观察流量切分。
# 提交一个新版本
cd ~/demo-app
echo 'const Version = "v2.1.0"' >> version.txt
git add -A
git commit -m "release: v2.1.0 with metrics endpoint"
git push origin main
提交后,在 GitLab 流水线页面可以看到四个阶段依次执行。使用 kubectl 实时观察 CD 链路的状态变化:
# 观察 Rollout 状态
kubectl argo rollouts get rollout demo-app -n demo –watch
# 典型输出:
# Name: demo-app
# Status: ॥ Paused
# Strategy: Canary
# Step: 1/7
# SetWeight: 20
# ActualWeight: 20
# Images:
# harbor.stellardata.top/devops/demo-app:abc1234 (canary)
# harbor.stellardata.top/devops/demo-app:def5678 (stable)
金丝雀阶段会依次执行:20% 流量 → 暂停 2 分钟 → 分析指标 → 50% 流量 → 暂停 → 分析 → 100% 流量。如果 AnalysisTemplate 查询到错误率高于 5%,会立即回滚,旧版本 Pod 保持稳定。
实战步骤五:验证监控与告警链路
在金丝雀推进期间,Prometheus 会通过 ServiceMonitor 采集 demo-app 的 /metrics 端点。我们可以在 Grafana 看板中实时观察版本流量分布。同时,Alertmanager 已经配置了针对 demo-app 的告警规则:
# PrometheusRule:错误率告警
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: demo-app-alerts
namespace: demo
labels:
prometheus: kube-prometheus
spec:
groups:
– name: demo-app.rules
rules:
– alert: DemoAppHighErrorRate
expr: |
sum(rate(http_requests_total{job="demo-app",status=~"5.."}[5m]))
/ sum(rate(http_requests_total{job="demo-app"}[5m])) > 0.05
for: 2m
labels:
severity: critical
team: devops
annotations:
summary: "demo-app 错误率高于 5%"
description: "当前 5xx 错误率 {{ $value | humanizePercentage }},请检查金丝雀版本。"
当告警触发时,Alertmanager 会通过钉钉 Webhook 和邮件两个渠道并行通知。这样,即使 Argo Rollouts 的自动回滚机制因为指标查询延迟而未能及时响应,运维同学也能第一时间收到通知并手动介入。
常见问题:端到端流程的典型断点
Q1:CI 流水线构建成功,但 Argo CD 没有触发同步?
检查 sync_gitops 阶段是否真的推送到 GitOps 仓库。最常见的原因是 Git 推送使用的是 HTTPS 但 Token 权限不足。在 GitLab 项目设置中确认 Token 拥有 write_repository 权限。另外,确认 Argo CD Application 的 syncPolicy.automated.selfHeal 已开启,否则需要手动点击 Sync。
Q2:金丝雀流量切分不生效,稳定版和金丝雀各占 50%?
这通常是因为 Nginx Ingress Controller 没有正确识别 canary annotation。检查 stable Service 和 canary Service 的 selector 是否与 Rollout 的 trafficRouting.nginx.stableIngress 一致。同时确认 Ingress Controller 版本支持 canary annotation(≥0.20)。
Q3:AnalysisTemplate 查询返回空,导致分析超时?
Prometheus 查询需要时间窗口内有足够的数据点。如果 demo-app 刚启动,rate() 函数会返回空。在 AnalysisTemplate 中将 count 设为 5、interval 设为 30s,给指标 2.5 分钟的采集窗口。同时确保 ServiceMonitor 的 interval 不超过 30s。
Q4:Trivy 扫描阶段失败导致流水线中断,但镜像是可用的?
将 trivy_scan 的 allow_failure 设为 true 可以让流水线在扫描失败时继续执行,但会在 GitLab 界面标记为警告。生产环境中建议保留 exit-code 1 的严格策略,同时在 Harbor 中配置 Trivy 自动扫描策略,形成双重保险。
总结:端到端闭环的核心价值
今天的演示验证了 DevOps 全链路的完整闭环:一次 git push 触发了 CI 构建和代码质量门禁,产出的镜像经过漏洞扫描后被推送到 Harbor,CI 自动更新 GitOps 仓库中的镜像 Tag,Argo CD 监听到变更后同步 Rollout 资源,Argo Rollouts 按金丝雀策略逐步切分流量,AnalysisTemplate 在每个阶段查询 Prometheus 指标决定推进或回滚,Grafana 看板全程可视化,Alertmanager 在异常时多渠道告警。
这条管道的核心价值在于”一切皆 Git“——CI 产物和 CD 声明都以 Git 提交为唯一事实来源,任何环节都可追溯、可审计、可回滚。每个组件都是独立可替换的齿轮,只要接口契约不变,就能灵活升级。
下期预告
明天我们将进入 第 18 天:生产化加固要点:Harbor/GitLab/Argo CD/SonarQube 高可用方案,讨论如何把这些组件从”能跑”升级到”生产级可靠”,涵盖多副本部署、数据备份、故障切换和容量规划。
系列大纲
- 全链路架构总览:从代码提交到灰度发布的完整管道设计
- K8s 集群与网络基础:kubeadm 离线部署与 Cilium 网络插件
- Harbor 私有镜像仓库部署与验证:Helm 安装与镜像推送
- GitLab CE 自托管部署:代码仓库与项目管理平台
- GitLab Runner 配置:K8s Executor 与 RBAC 权限设置
- GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建
- Harbor 镜像版本管理与 Tag 策略配置
- Argo CD 部署与 GitOps 配置仓库创建
- CI 与 CD 联动:从代码提交到部署的全自动闭环
- SonarQube 代码质量检查:SonarQube 部署与 GitLab CI 集成
- Prometheus 部署:kube-prometheus-stack 与 ServiceMonitor 指标采集
- Grafana 看板搭建:K8s 标准面板与自定义业务看板
- 告警规则与 Alertmanager:钉钉/邮件通知渠道配置
- Argo Rollouts 安装与基础概念:CRD 与 Rollout 资源定义
- 金丝雀发布实战:setWeight 流量分割与 pause 步骤
- AnalysisTemplate 指标分析与自动回滚机制
- 全链路端到端演示:代码提交→构建→代码检查→灰度→监控→告警完整流程(今天)
- 生产化加固要点:Harbor/GitLab/Argo CD/SonarQube 高可用方案
- 供应链安全闭环:Trivy 扫描 + cosign 签名 + Kyverno 验签

















暂无评论内容