三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

【GitOps·入门篇】四大原则:声明式、版本控制、自动应用、持续协调

【GitOps·入门篇】四大原则:声明式、版本控制、自动应用、持续协调

前言

GitOps 不是某个工具,而是一套原则。OpenGitOps 社区定义了 GitOps 的四大原则,任何工具只要满足这四个原则就可以称为"GitOps 工具"。理解这四个原则,你就能判断一个工具是否真正是 GitOps,也能理解为什么 GitOps 比传统 CI/CD 更安全。


一、原则一:声明式(Declarative)

原则描述

系统期望状态必须用声明式的方式描述——"我要什么"而非"我要做什么"。

命令式 vs 声明式

# 命令式(Imperative)——告诉系统怎么做 # kubectl create deployment myapp --image=myapp:v1 --replicas=3 # → 一步步执行命令,最终结果是隐含的 # 声明式(Declarative)——描述期望状态 apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 # 我要3个副本 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: myapp:v1 # 用这个镜像 resources: limits: cpu: 500m memory: 512Mi

为什么声明式是 GitOps 的基础

命令式的问题: 脚本: kubectl scale deployment myapp --replicas=4 kubectl set image deployment myapp app=myapp:v2 kubectl apply configmap app-config --from-file=config.yaml → 三条命令执行完,集群状态是什么?你不确定 → 如果中间有命令失败了呢? → 如果有人又执行了别的命令呢? 声明式的优势: Git 仓库中的 YAML 描述了完整的期望状态 → 集群应该有3个副本、用 v2 镜像、有这个 ConfigMap → GitOps 工具负责让集群达到这个状态 → 不管集群当前是什么状态,最终都会变成期望状态

实践建议

应该做的: ✓ 用 YAML 声明 K8s 资源 ✓ 用 Helm Chart 声明应用 ✓ 用 Kustomize 管理多环境差异 不应该做的: ✗ 用 kubectl create/scale/set 等命令式操作 ✗ 在 CI 中写 Shell 脚本执行部署 ✗ 用 kubectl edit 直接改集群中的资源

培训要点:判断是否声明式的方法——如果删除工具,集群状态是否会变?如果会变,说明是命令式(工具在维持状态);如果不会变,说明是声明式(YAML 已经描述了完整状态)。


二、原则二:版本控制(Version Controlled)

原则描述

所有声明式配置必须存储在 Git 仓库中,Git 是唯一可信源(Single Source of Truth)。

为什么用 Git

特性Git 的价值
版本历史每次变更都有记录,可以追溯到任意版本
审计追踪谁、什么时候、改了什么、为什么改
变更审批PR/MR Review 机制,变更前必须审查
快速回滚git revert 即可回滚到任意版本
分支管理不同分支对应不同环境
协作多人可以同时修改,Git 处理冲突

仓库策略

策略一:应用代码和部署清单在同一仓库

myapp/ ├── src/ # 应用源码 ├── Dockerfile ├── deploy/ # 部署清单 │ ├── base/ # 基础配置 │ │ ├── deployment.yaml │ │ ├── service.yaml │ │ └── kustomization.yaml │ └── overlays/ # 环境差异 │ ├── test/ │ ├── staging/ │ └── prod/

策略二:应用代码和部署清单分离(推荐)

仓库1: myapp-code/ # 应用代码 ├── src/ ├── Dockerfile └── Jenkinsfile 仓库2: myapp-deploy/ # 部署清单(GitOps 仓库) ├── base/ │ ├── deployment.yaml │ └── service.yaml └── overlays/ ├── test/ ├── staging/ └── prod/

培训要点:推荐分离仓库策略。原因:部署清单仓库可以设更严格的权限(只有 DevOps 能改生产配置),而应用代码仓库可以开放给所有开发人员。CI 完成镜像构建后,自动更新部署清单仓库中的镜像版本。

策略三:统一部署仓库(多服务集中管理)

deployments/ # 统一部署仓库 ├── services/ │ ├── user-service/ │ │ ├── base/ │ │ └── overlays/ │ ├── order-service/ │ │ ├── base/ │ │ └── overlays/ │ └── payment-service/ │ ├── base/ │ └── overlays/ └── infrastructure/ # 基础设施 ├── ingress/ ├── cert-manager/ └── monitoring/

三、原则三:自动应用(Automated Application)

原则描述

从 Git 仓库到集群的变更应该是自动的——不需要人手动运行kubectl apply

自动应用 vs 手动应用

手动应用(不满足 GitOps): 修改 Git 仓库 → 人手动执行 kubectl apply → 集群更新 问题:容易遗忘、不一致、不能自动响应变更 自动应用(满足 GitOps): 修改 Git 仓库 → GitOps 工具自动检测 → 自动应用到集群 优势:3秒内响应、每次变更都同步、无人值守

ArgoCD 自动应用配置

# ArgoCD Application apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: myapp namespace: argocd spec: source: repoURL: https://github.com/myorg/myapp-deploy targetRevision: main path: overlays/prod destination: server: https://kubernetes.default.svc namespace: myapp-prod syncPolicy: automated: # ← 自动同步 prune: true # 自动删除 Git 中不存在的资源 selfHeal: true # 自动修复漂移 syncOptions: - CreateNamespace=true

Flux 自动应用配置

# Flux Kustomization apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: myapp namespace: flux-system spec: interval: 30s # ← 每30秒检查一次 Git 仓库 path: ./overlays/prod sourceRef: kind: GitRepository name: myapp-deploy prune: true # 自动清理 healthChecks: - apiVersion: apps/v1 kind: Deployment name: myapp namespace: myapp-prod

什么时候需要手动审批

# ArgoCD 中可以配置部分自动、部分手动 spec: syncPolicy: automated: prune: true selfHeal: true # 对于生产环境,可以用 Sync Window 限制自动同步时间 # 或者用 ArgoCD ApplicationSet + environment 标签控制

培训要点:自动应用不代表全自动无人值守。测试和预发环境可以完全自动,生产环境可以设置"自动同步但需要审批"或"仅工作时间自动同步"。


四、原则四:持续协调(Continuous Reconciliation)

原则描述

GitOps 工具持续比较 Git 仓库中的期望状态和集群中的实际状态,发现差异时自动行动。

协调循环

持续运行的协调循环: ┌─────────────────────────────────────┐ │ 每 30 秒循环一次 │ │ │ │ 1. 从 Git 读取期望状态 │ │ Git 仓库: replicas=3, image=v2 │ │ │ │ 2. 从集群读取实际状态 │ │ K8s 集群: replicas=2, image=v2 │ │ │ │ 3. 比较差异 │ │ 差异: replicas 3≠2 │ │ │ │ 4. 根据策略处理 │ │ 策略A: 自动修复 → kubectl scale 3│ │ 策略B: 只告警 → 发送通知 │ │ │ │ 5. 记录结果 │ │ 状态: OutOfSync → Syncing → Synced│ └─────────────────────────────────────┘

漂移(Drift)检测

场景:有人手动修改了集群 开发者 SSH 到节点: kubectl scale deployment myapp --replicas=1 → 集群实际状态: replicas=1 → Git 仓库状态: replicas=3 GitOps 工具下一次协调: → 检测到漂移: 实际(1) ≠ 期望(3) → selfHeal=true: 自动修复 → replicas 恢复为 3 → 发送漂移告警: "检测到手动变更,已自动修复" selfHeal=false: → 只告警不修复 → 需要人工确认是否要修改 Git 仓库

ArgoCD 漂移检测配置

spec: syncPolicy: automated: selfHeal: true # 自动修复漂移 prune: true # 自动清理 Git 中已删除的资源

协调频率

工具默认协调间隔配置方式
ArgoCD3分钟(默认)argocd.argoproj.io/sync-options: "..."
Flux1分钟spec.interval: 30s

踩坑提示:协调间隔不是越短越好。太频繁的协调会给 API Server 带来压力。建议测试环境30秒,生产环境1-3分钟。


五、四原则的实践检查清单

原则一: 声明式 □ 所有部署配置用 YAML/Helm Chart/Kustomize 描述 □ 没有使用 kubectl create/scale/set 命令式操作 □ 集群状态可以完全从 Git 仓库还原 原则二: 版本控制 □ 所有部署配置在 Git 仓库中 □ Git 仓库有分支保护(main 分支不能直接 push) □ 变更通过 PR/MR Review 合并 □ Git 仓库是唯一可信源 原则三: 自动应用 □ 使用 ArgoCD/Flux 等 GitOps 工具 □ Git 变更后自动同步到集群 □ 不需要人手动 kubectl apply 原则四: 持续协调 □ GitOps 工具持续运行 □ 配置了漂移检测 □ 有漂移告警通知

六、本篇要点回顾

  1. 声明式:描述"要什么"而非"做什么",YAML 描述完整期望状态
  2. 版本控制:Git 是唯一可信源,PR Review 审批每次变更
  3. 自动应用:GitOps 工具自动将 Git 变更同步到集群
  4. 持续协调:持续比较期望与实际,发现漂移自动修复或告警
  5. 四个原则缺一不可——满足全部才是真正的 GitOps

下一篇预告:《推模型 vs 拉模型:GitOps 与传统 CI/CD 的核心差异》——用两条具体的流水线对比推模型和拉模型的差异。

← 返回列表