DevOps全链路实战 | 第 17 天:全链路端到端演示:代码提交→构建→代码检查→灰度→监控→告警完整流程

第 17/19 天

引言:把所有齿轮咬合在一起

K8s

经过前 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 高可用方案,讨论如何把这些组件从”能跑”升级到”生产级可靠”,涵盖多副本部署、数据备份、故障切换和容量规划。

系列大纲

  1. 全链路架构总览:从代码提交到灰度发布的完整管道设计
  2. K8s 集群与网络基础:kubeadm 离线部署与 Cilium 网络插件
  3. Harbor 私有镜像仓库部署与验证:Helm 安装与镜像推送
  4. GitLab CE 自托管部署:代码仓库与项目管理平台
  5. GitLab Runner 配置:K8s Executor 与 RBAC 权限设置
  6. GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建
  7. Harbor 镜像版本管理与 Tag 策略配置
  8. Argo CD 部署与 GitOps 配置仓库创建
  9. CI 与 CD 联动:从代码提交到部署的全自动闭环
  10. SonarQube 代码质量检查:SonarQube 部署与 GitLab CI 集成
  11. Prometheus 部署:kube-prometheus-stack 与 ServiceMonitor 指标采集
  12. Grafana 看板搭建:K8s 标准面板与自定义业务看板
  13. 告警规则与 Alertmanager:钉钉/邮件通知渠道配置
  14. Argo Rollouts 安装与基础概念:CRD 与 Rollout 资源定义
  15. 金丝雀发布实战:setWeight 流量分割与 pause 步骤
  16. AnalysisTemplate 指标分析与自动回滚机制
  17. 全链路端到端演示:代码提交→构建→代码检查→灰度→监控→告警完整流程(今天)
  18. 生产化加固要点:Harbor/GitLab/Argo CD/SonarQube 高可用方案
  19. 供应链安全闭环:Trivy 扫描 + cosign 签名 + Kyverno 验签
微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容