跳转至

第16章 GitOps实践

GitOps实践图

GitOps是一种以Git仓库作为单一事实来源(Single Source of Truth)的运维范式,通过声明式配置和自动化同步实现基础设施和应用的持续交付。

目录


1. GitOps核心概念

1.1 什么是GitOps

GitOps由Weaveworks在2017年提出,核心思想:

  • 声明式:用声明式配置描述系统期望状态
  • 版本化:所有配置存储在Git中,变更历史可追溯
  • 自动化:自动将Git中的配置同步到目标环境
  • 自愈:当实际状态偏离期望状态时自动修复

1.2 传统CI/CD vs GitOps

Text Only
传统推送模式 (Push):
┌──────┐   push    ┌──────┐   push    ┌──────────┐
│ 开发者 │ ───────→ │ CI/CD │ ───────→ │ K8s集群   │
└──────┘           └──────┘           └──────────┘
                   CI工具需要集群访问权限(安全风险)

GitOps拉取模式 (Pull):
┌──────┐  commit   ┌──────┐   watch   ┌──────────┐
│ 开发者 │ ───────→ │ Git  │ ←─────── │ GitOps   │
└──────┘           │ Repo │           │ Operator │
                   └──────┘    sync   │ (集群内)  │
                              ──────→ │          │
                                      └──────────┘
                   GitOps agent在集群内部拉取配置(更安全)

1.3 GitOps四大原则

原则 说明
声明式描述 系统的期望状态以声明式的方式定义
版本控制 期望状态存储在Git中,Git作为唯一事实来源
自动应用 经过批准的变更自动应用到系统
持续调谐 Agent持续监控并纠正实际状态与期望状态的偏差

1.4 Git作为单一事实来源

Text Only
GitOps 仓库结构:
├── apps/
│   ├── production/
│   │   ├── frontend/
│   │   │   ├── deployment.yaml
│   │   │   ├── service.yaml
│   │   │   └── ingress.yaml
│   │   └── backend/
│   │       ├── deployment.yaml
│   │       ├── service.yaml
│   │       └── configmap.yaml
│   └── staging/
│       ├── frontend/
│       └── backend/
├── infrastructure/
│   ├── namespaces.yaml
│   ├── rbac.yaml
│   └── monitoring/
└── README.md

2. GitOps工作流

2.1 标准GitOps工作流

Text Only
  开发者         代码仓库        CI流水线        配置仓库        GitOps Agent     K8s集群
   │              │              │              │              │              │
   │──push代码──→│              │              │              │              │
   │              │──触发CI────→│              │              │              │
   │              │              │──构建镜像──→│              │              │
   │              │              │──推送到仓库──→              │              │
   │              │              │──更新配置──→│              │              │
   │              │              │              │──检测变更──→│              │
   │              │              │              │              │──同步配置──→│
   │              │              │              │              │──健康检查──→│

2.2 分支策略

Text Only
环境与分支映射:
┌──────────────────────────────────────────┐
│  main分支      → production环境            │
│  staging分支   → staging环境               │
│  develop分支   → development环境           │
│                                          │
│  推荐:每个环境对应独立目录而非独立分支       │
│  使用Kustomize overlay管理环境差异          │
└──────────────────────────────────────────┘

2.3 镜像更新策略

YAML
# 方式一:CI流水线自动更新配置仓库中的镜像标签
# .github/workflows/ci.yaml
name: CI Pipeline
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build & Push Image
        run: |
          docker build -t myapp:${{ github.sha }} .
          docker push myregistry/myapp:${{ github.sha }}

      - name: Update K8s Manifest
        run: |
          cd gitops-repo
          kustomize edit set image myapp=myregistry/myapp:${{ github.sha }}
          git commit -am "chore: update myapp to ${{ github.sha }}"
          git push

3. Argo CD实战

3.1 Argo CD概述

Argo CD是CNCF毕业项目,是最流行的Kubernetes GitOps工具。

核心特性: - 声明式GitOps持续交付 - 多集群管理 - SSO集成(OIDC, OAuth2, LDAP) - Web UI + CLI + API - 支持Helm/Kustomize/Jsonnet/Plain YAML - 自动同步与手动同步策略

3.2 安装Argo CD

Bash
# 创建命名空间并安装
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 获取初始密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# 安装CLI
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd && sudo mv argocd /usr/local/bin/  # &&前一个成功才执行后一个;||前一个失败才执行

# 登录
argocd login <ARGOCD_SERVER> --username admin --password <PASSWORD>

3.3 Application定义

YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/gitops-repo.git
    targetRevision: main
    path: apps/production/backend
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true        # 删除Git中移除的资源
      selfHeal: true     # 自动修复手动变更
    syncOptions:
      - CreateNamespace=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

3.4 ApplicationSet(多环境/多集群)

YAML
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-app-set
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: staging
            url: https://staging-cluster.example.com
            namespace: staging
          - cluster: production
            url: https://prod-cluster.example.com
            namespace: production
  template:
    metadata:
      name: 'my-app-{{cluster}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/myorg/gitops-repo.git
        targetRevision: main
        path: 'apps/{{cluster}}/backend'
      destination:
        server: '{{url}}'
        namespace: '{{namespace}}'

3.5 同步策略

策略 说明 适用场景
手动同步 需要手动触发同步 生产环境
自动同步 Git变更后自动同步 开发/测试环境
自动修剪 删除Git中不存在的资源 与自动同步配合
自愈 修复手动对集群的变更 防止配置漂移

4. Flux CD实战

4.1 Flux概述

Flux是CNCF毕业项目,采用GitOps Toolkit模块化架构。

核心组件:

Text Only
┌────────────────────────────────────────────┐
│             Flux GitOps Toolkit             │
├──────────────┬──────────┬─────────────────┤
│ Source       │ Kustomize │ Helm            │
│ Controller   │ Controller│ Controller      │
├──────────────┼──────────┼─────────────────┤
│ Notification │ Image    │ Image           │
│ Controller   │ Reflector│ Automation      │
└──────────────┴──────────┴─────────────────┘

4.2 Flux安装与配置

Bash
# 安装Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash  # |管道:将前一命令的输出作为后一命令的输入

# 引导Flux到集群
flux bootstrap github \
  --owner=myorg \
  --repository=gitops-repo \
  --branch=main \
  --path=clusters/production \
  --personal

# 检查状态
flux check
flux get all

4.3 Flux资源定义

YAML
# GitRepository源
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/myorg/gitops-repo
  ref:
    branch: main
---
# Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 5m
  path: ./apps/production
  prune: true
  sourceRef:
    kind: GitRepository
    name: my-app
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: backend
      namespace: production

4.4 Flux镜像自动更新

YAML
# 镜像仓库扫描
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  image: myregistry/my-app
  interval: 5m
---  # YAML文档分隔符
# 镜像策略(使用最新semver标签)
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: my-app
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: my-app
  policy:
    semver:
      range: '>=1.0.0'
---
# 自动更新配置
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: my-app
  git:
    commit:
      author:
        name: fluxcdbot
        email: fluxcd@example.com
      messageTemplate: 'chore: update image to {{.NewImage}}'
    push:
      branch: main
  update:
    path: ./apps/production
    strategy: Setters

5. GitOps与Kubernetes集成

5.1 Kustomize环境管理

Text Only
kustomize/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
├── overlays/
│   ├── staging/
│   │   ├── kustomization.yaml
│   │   └── replicas-patch.yaml
│   └── production/
│       ├── kustomization.yaml
│       ├── replicas-patch.yaml
│       └── resources-patch.yaml
YAML
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml

# overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patches:
  - path: replicas-patch.yaml
  - path: resources-patch.yaml
namespace: production

# overlays/production/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 5

5.2 Helm Chart GitOps

YAML
# Argo CD with Helm
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: prometheus
spec:
  source:
    repoURL: https://prometheus-community.github.io/helm-charts
    chart: kube-prometheus-stack
    targetRevision: 45.0.0
    helm:
      values: |
        prometheus:
          retention: 30d
        grafana:
          enabled: true
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring

5.3 Secret管理

YAML
# 方案一:Sealed Secrets
apiVersion: bitnami.com/v1alpha1  # apiVersion指定K8s API版本
kind: SealedSecret  # kind指定资源类型
metadata:
  name: my-secret
spec:  # spec定义资源的期望状态
  encryptedData:
    password: AgBy3i...encrypted...

# 方案二:SOPS + Age/PGP
# .sops.yaml
creation_rules:
  - path_regex: .*\.enc\.yaml$
    age: age1...publickey...

# 加密后可安全存入Git
sops --encrypt --age age1... secret.yaml > secret.enc.yaml

# 方案三:External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: my-secret
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: my-secret
  data:
    - secretKey: password
      remoteRef:
        key: /myapp/production/db-password

6. GitOps最佳实践

6.1 仓库策略

策略 说明 适用场景
单仓库(Monorepo) 应用+配置在同一仓库 小团队、少量应用
双仓库 代码仓库 + 配置仓库分离 中大型团队(推荐)
多仓库 每个团队/应用独立配置仓库 大型组织

6.2 变更管理

Text Only
推荐的GitOps变更流程:
1. 开发者创建PR修改配置
2. 自动化检查(lint、diff预览、策略检查)
3. 团队Review + 批准
4. 合并到主分支
5. GitOps Agent自动同步
6. 监控告警确认部署健康

6.3 回滚策略

Bash
# Argo CD回滚
argocd app rollback my-app

# Git回滚(推荐)
git revert HEAD
git push origin main
# GitOps agent会自动同步到回滚后的状态

7. 面试题精选

Q1: GitOps与传统CI/CD的核心区别?

维度 传统CI/CD GitOps
部署方式 Push(CI推送到集群) Pull(Agent从Git拉取)
事实来源 CI/CD工具配置 Git仓库
安全模型 CI需要集群凭证 Agent在集群内运行
漂移检测 持续监控+自愈
审计追踪 CI日志 Git历史
回滚 重新执行旧版本Pipeline git revert

Q2: Argo CD和Flux如何选型?

维度 Argo CD Flux
UI 内置强大Web UI 无官方UI(可用Weave GitOps)
架构 单体应用 模块化Toolkit
多集群 原生支持 需Hub-Spoke模式
镜像自动更新 需Argo CD Image Updater 原生支持
学习曲线 较低 中等
CNCF状态 毕业项目 毕业项目

Q3: GitOps如何处理Secret?

  1. Sealed Secrets:加密后存入Git,集群内解密
  2. SOPS:使用KMS/PGP加密YAML文件
  3. External Secrets Operator:从外部Secret管理器(Vault/AWS SM)同步
  4. Vault Agent Injector:HashiCorp Vault直接注入

原则:永远不要将明文Secret存入Git。

Q4: 如何防止配置漂移?

  • 启用GitOps Agent的自愈功能(selfHeal)
  • 使用OPA/Kyverno策略禁止手动kubectl变更
  • RBAC限制集群直接写权限
  • 定期审计实际状态与Git状态的差异

Q5: GitOps的多环境管理策略?

  • 推荐:目录分离 —— 同一仓库不同目录对应不同环境
  • 可选:分支分离 —— 不同分支对应不同环境(PR合并=升级环境)
  • 使用Kustomize overlay管理环境差异
  • 通过ApplicationSet自动生成多环境Application

8. 推荐资源


下一步学习:结合05-CI-CD流水线设计完整的GitOps交付管道,并参考17-基础设施即代码实现基础设施的声明式管理。