生产环境 DevOps 实战 | 第 3 天:生产环境 DevOps 架构设计——从代码提交到上线的全链路蓝图

第 3/60 天

引言

在微服务和云原生架构日益普及的今天,一个完整的 DevOps 流水线已经不再是简单的”代码提交→自动构建→自动部署”三步走。生产环境面临多团队协作、多环境管理、安全合规、高可用、灰度发布、制品溯源等复杂需求。如何设计一套既能支撑快速迭代又能保障生产稳定的 DevOps 架构?

本文将以 Tekton(CI)、Harbor(制品仓库)、Argo CD(CD)三件套为核心,从代码提交到生产上线的全链路视角,呈现生产级 DevOps 架构设计蓝图。读完本文,你将清楚每个环节的工具选型、数据流设计、安全边界划分以及高可用考量。

核心概念

全链路架构分层

生产环境 DevOps 架构可分为五个核心层次:

层次 职责 核心组件
代码层 源码管理、分支策略、代码审查 GitHub/GitLab + Webhook
CI 层 代码检查、单元测试、镜像构建、制品推送 Tekton Pipelines + Triggers
制品层 镜像存储、安全扫描、版本管理、多集群同步 Harbor
CD 层 GitOps 声明式部署、多环境管理、渐进式发布 Argo CD + Argo Rollouts
运行时层 应用运行、服务发现、流量管理、可观测性 Kubernetes + Service Mesh

数据流与事件驱动

整个流水线采用事件驱动模型:

代码推送 → GitHub Webhook
    ↓
Tekton EventListener 接收事件
    ↓
Tekton PipelineRun 触发 CI 流水线
    ├── 代码检出
    ├── 单元测试
    ├── 镜像构建(Kaniko)
    └── 镜像推送至 Harbor
        ↓
Harbor Robot Account 验证 → 镜像推送完成
    ↓
Harbor Webhook 或 Image Updater 检测新镜像
    ↓
Argo CD 检测 Git 仓库配置变更
    ↓
Argo CD Sync → Kubernetes 集群部署

关键设计原则

  1. 不可变基础设施:每次部署都是完整的镜像替换,不原地变更
  2. 声明式配置:所有环境状态都以 Git 仓库中的声明为唯一真相来源
  3. 制品可追溯:每个镜像都有唯一标签,关联 Commit SHA 和 CI 构建号
  4. 最小权限:每个组件只拥有完成本职工作的最小权限集

实战步骤

步骤一:定义 Git 仓库结构

合理的仓库结构是 DevOps 架构的基石。推荐按应用仓库、配置仓库、环境仓库三分离:

# 仓库结构示意
repo/
├── apps/                          # 应用源码仓库
│   ├── user-service/              # 用户服务
│   │   ├── src/
│   │   ├── Dockerfile
│   │   ├── tekton/                # 该应用的 CI 流水线
│   │   │   ├── task-build.yaml
│   │   │   └── pipeline-ci.yaml
│   │   └── k8s/                   # 该应用的 K8s 配置
│   │       ├── base/
│   │       │   ├── deployment.yaml
│   │       │   ├── service.yaml
│   │       │   └── kustomization.yaml
│   │       └── overlays/
│   │           ├── dev/
│   │           ├── staging/
│   │           └── prod/
│   └── order-service/
│       └── ...
├── infrastructure/                # 基础设施配置仓库
│   ├── tekton/
│   │   ├── tasks/
│   │   ├── pipelines/
│   │   └── triggers/
│   ├── argocd/
│   │   ├── projects/
│   │   └── applications/
│   └── harbor/
│       └── robot-accounts/
└── environment-configs/           # 环境配置仓库
    ├── dev/
    ├── staging/
    └── prod/

步骤二:CI 流水线设计(Tekton)

下面是一个完整的 Tekton CI Pipeline YAML 定义,包含代码检出、测试、构建、推送四个阶段:

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: ci-pipeline
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
    - name: revision
      description: 分支或 Commit SHA
      default: "main"
    - name: image-name
      description: 镜像名称(不含标签)
  workspaces:
    - name: source
    - name: dockerconfig
  tasks:
    # 1. 代码检出
    - name: checkout
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: source
      params:
        - name: url
          value: $(params.repo-url)
        - name: revision
          value: $(params.revision)

    # 2. 单元测试
    - name: unit-test
      runAfter: [checkout]
      taskRef:
        name: pytest
      workspaces:
        - name: source
          workspace: source
      params:
        - name: test-dir
          value: ./tests

    # 3. Kaniko 镜像构建
    - name: build-image
      runAfter: [unit-test]
      taskRef:
        name: kaniko
      workspaces:
        - name: source
          workspace: source
        - name: dockerconfig
          workspace: dockerconfig
      params:
        - name: IMAGE
          value: $(params.image-name):$(params.revision)
        - name: DOCKERFILE
          value: ./Dockerfile

    # 4. 推送镜像到 Harbor
    - name: push-to-harbor
      runAfter: [build-image]
      taskSpec:
        params:
          - name: image-ref
        steps:
          - name: push
            image: gcr.io/go-containerregistry/crane:debug
            script: |
              crane push /kaniko/image $(params.image-ref)
      params:
        - name: image-ref
          value: harbor.internal.io/$(params.image-name):$(params.revision)

步骤三:Harbor 配置(Robot Account + 复制规则)

Harbor 在架构中充当”可信制品枢纽”。为 CI 系统创建 Robot Account:

{
  "name": "tekton-ci-bot",
  "description": "Tekton CI 流水线推送镜像专用账号",
  "level": "project",
  "project_name": "devops-team",
  "permissions": [
    {
      "namespace": "devops-team",
      "kind": "project",
      "access": [
        {"resource": "repository", "action": "push"},
        {"resource": "repository", "action": "pull"},
        {"resource": "artifact", "action": "list"},
        {"resource": "tag", "action": "create"}
      ]
    }
  ],
  "duration": -1,
  "disable": false
}

跨集群镜像同步的复制规则配置:

# 通过 Harbor API 创建复制规则
POST /api/v2.0/replication/policies
{
  "name": "sync-to-dr-cluster",
  "description": "主动同步到灾备集群 Harbor",
  "src_registry": {"id": 0},  # 0 = 本地
  "dest_registry": {
    "id": 1,  # 远程 Harbor 实例 ID
    "name": "harbor-dr.internal.io"
  },
  "dest_namespace": "devops-team",
  "filters": [
    {"type": "name", "value": "devops-team/**"},
    {"type": "resource", "value": "image"}
  ],
  "trigger": {
    "type": "event_based",
    "settings": {"deployment": "all"}
  },
  "enabled": true,
  "override": false
}

步骤四:Argo CD Application 定义

CD 层的核心是 Argo CD Application,它定义了从 Git 仓库到 Kubernetes 集群的映射关系:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  namespace: argocd
spec:
  project: devops-team
  source:
    repoURL: https://github.com/company/applications.git
    targetRevision: main
    path: user-service/k8s/overlays/prod
    # 使用 Kustomize 管理配置差异
    kustomize:
      images:
        - harbor.internal.io/devops-team/user-service:v1.2.3
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true          # 自动删除不在 Git 中的资源
      selfHeal: true       # 自动修复配置漂移
      allowEmpty: false    # 不允许空同步
    syncOptions:
      - CreateNamespace=true
      - PruneLast=true
      - ApplyOutOfSyncOnly=true
    retry:
      limit: 5
      backoff:
        duration: 30s
        maxDuration: 5m
        factor: 2

步骤五:镜像更新自动触发部署(End-to-End 联动)

当 CI 推送新镜像到 Harbor 后,需要自动触发 CD 更新。下面是一个 Argo CD Image Updater 配置,实现全自动闭环:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: user-service
  annotations:
    # 自动更新镜像版本
    argocd-image-updater.argoproj.io/image-list: user-service=harbor.internal.io/devops-team/user-service
    argocd-image-updater.argoproj.io/user-service.update-strategy: semver
    argocd-image-updater.argoproj.io/user-service.semver.range: ">=1.0.0 <2.0.0"
    # 推送策略:直接写入 Git 仓库,由 Argo CD 自动同步
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/git-branch: main

步骤六:完整架构的部署脚本

将上述组件一次性部署到 Kubernetes 集群的脚本:

#!/bin/bash
# 生产环境 DevOps 三件套一键部署脚本
set -euo pipefail

NAMESPACE_DEVTOOLS="devtools"
NAMESPACE_ARGO="argocd"
NAMESPACE_HARBOR="harbor"

echo "=== 1. 创建命名空间 ==="
kubectl create ns "$NAMESPACE_DEVTOOLS" --dry-run=client -o yaml | kubectl apply -f -
kubectl create ns "$NAMESPACE_ARGO" --dry-run=client -o yaml | kubectl apply -f -
kubectl create ns "$NAMESPACE_HARBOR" --dry-run=client -o yaml | kubectl apply -f -

echo "=== 2. 安装 Tekton Pipelines ==="
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
kubectl -n tekton-pipelines wait --for=condition=Ready pods --all --timeout=300s

echo "=== 3. 安装 Tekton Triggers ==="
kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl -n tekton-pipelines wait --for=condition=Ready pods --all --timeout=300s

echo "=== 4. 安装 Tekton Dashboard(可选)==="
kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml

echo "=== 5. 安装 Harbor(通过 Helm)==="
helm repo add harbor https://helm.goharbor.io
helm upgrade --install harbor harbor/harbor 
  --namespace "$NAMESPACE_HARBOR" 
  --values harbor-values.yaml 
  --wait

echo "=== 6. 安装 Argo CD ==="
kubectl create namespace "$NAMESPACE_ARGO" --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -n "$NAMESPACE_ARGO" -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

echo "=== 7. 安装 Argo CD Image Updater ==="
kubectl apply -n "$NAMESPACE_ARGO" -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

echo "=== 8. 安装 Argo Rollouts(可选)==="
kubectl create namespace argo-rollouts --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

echo "=== 部署完成!==="
echo "Tekton Dashboard:  kubectl proxy --port=8080 -> http://localhost:8080/tekton/"
echo "Argo CD UI:        kubectl -n argocd get svc argocd-server"
echo "Argo CD 初始密码:  kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d"
echo "Harbor UI:         kubectl -n harbor get svc harbor-portal"

常见问题

Q1:为什么选择 Tekton 而不是 Jenkins X 或 GitLab CI?

Tekton 是 Kubernetes 原生的 CI 引擎,它的 CRD(Custom Resource Definition)设计让 Pipeline 变成一等 K8s 资源,可被 GitOps 管理。Jenkins 需要额外插件和控制器,GitLab CI 绑定 GitLab 平台。Tekton 的灵活性最高,适合多云/混合云场景。

Q2:Harbor 和 Docker Hub / ECR 相比,优势在哪里?

Harbor 部署在企业内部,不依赖公网。它原生支持 OCI 制品(Helm Chart、SBOM、Cosign 签名)、漏洞扫描(Trivy/Clair)、复制规则(跨机房同步)、Robot Account 无密钥认证,是生产环境制品仓库的工业标准。

Q3:Argo CD 的自动同步安全吗?如果部署出问题怎么办?

自动同步配合 prune: true 确实有风险。建议分级策略:dev/staging 环境开启自动同步,prod 环境使用 manual 模式 + 人工审批。结合 Argo Rollouts 的渐进式发布(Blue-Green / Canary),可以在问题出现时秒级回滚。

Q4:微服务数量多起来后,Pipeline 和 Application 的 YAML 文件太多怎么管理?

使用 App of Apps 模式,让 Argo CD 管理自身。创建一个根 Application,它通过目录扫描自动发现子应用。Tekton 方面,利用社区共享的 Task Hub,复用通用 Task,每个微服务只需维护自己的 Pipeline 参数。

Q5:三件套之间的凭据如何管理?

最佳实践:Tekton 使用 Harbor Robot Account(无密码,仅 token)推送镜像;Argo CD 通过 Kubernetes Secret 存储 Harbor 拉取凭据和 Git 仓库 SSH Key;所有凭据使用 Sealed Secrets / External Secrets Operator 加密,不暴露在 Git 仓库中。

总结

  1. 全链路架构:代码推送 → Tekton CI(构建+测试)→ Harbor 存储(制品管理+安全扫描)→ Argo CD(GitOps 部署)→ Kubernetes 运行,五个环节环环相扣
  2. 三件套各司其职:Tekton 管”构建什么”,Harbor 管”存储什么”,Argo CD 管”部署到哪里”,职责边界清晰
  3. 事件驱动闭环:Webhook 触发 CI → CI 完成触发 Harbor 同步 → 新镜像触发 CD 更新,全自动化无需人工介入
  4. 安全设计贯穿始终:Robot Account 无密码认证、镜像签名验证、最小权限 RBAC、TLS 双向加密,每一层都有安全防护
  5. 可扩展性:架构设计支持多集群、多环境、多团队,通过 Kubernetes 命名空间、Harbor 项目、Argo CD Project 三层隔离机制实现
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

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

    暂无评论内容