技术博客

GitOps 是什么:从概念到 ArgoCD 快速入门

通俗讲解 GitOps 的核心理念、与传统 CI/CD 的区别,以及如何用 ArgoCD 在 Kubernetes 上实现声明式持续交付——从安装到第一个 Application 上线,含完整命令和配置示例。

GitOpsArgoCDKubernetesCI/CD持续交付DevOps

如果你用过 Kubernetes,一定遇到过这个问题:YAML 改了没 apply、apply 了不知道谁改的、线上和 Git 里的配置不一致……GitOps 就是解决这些问题的方法论,而 ArgoCD 是目前最流行的 GitOps 实现工具。本文从零开始讲清楚概念,并带你完成第一个 ArgoCD Application 的部署。

GitOps 是什么

GitOps 的核心思想很简单:Git 仓库是集群状态的唯一可信来源(Single Source of Truth)

传统部署流程(Push 模式):
开发提交代码 → CI 构建镜像 → 运维手动 kubectl apply → 集群
                                    ↑ 容易出错、无审计、状态难追踪

GitOps 流程(Pull 模式):
开发提交代码 → CI 构建镜像 → 更新 Git 中的 YAML(镜像标签)

                              ArgoCD 检测 Git 变更

                              自动 apply 到集群

                              持续对比 Git ↔ 集群状态(漂移检测)

GitOps 三个核心原则:

  1. 声明式(Declarative):系统期望状态用 YAML/Helm/Kustomize 声明,存在 Git 中
  2. 版本控制(Versioned):每次变更都有 Git commit,可回滚、可审计
  3. 自动协调(Reconciled):GitOps Agent 持续对比“期望状态(Git)“和”实际状态(集群)“,自动修复漂移

ArgoCD 架构

┌─────────────────────────────────────────────────┐
│  Git 仓库(GitHub/GitLab/Gitee)                │
│  k8s/production/deployment.yaml                 │
│  k8s/production/service.yaml                    │
└─────────────────────────┬───────────────────────┘
                          │ 轮询/Webhook

┌─────────────────────────────────────────────────┐
│  ArgoCD(运行在 Kubernetes 中)                 │
│  ┌──────────────────┐  ┌────────────────────┐  │
│  │  API Server      │  │  Repo Server        │  │
│  │  (Web UI + CLI)  │  │  (克隆 Git,渲染   │  │
│  └──────────────────┘  │   Helm/Kustomize)  │  │
│  ┌──────────────────┐  └────────────────────┘  │
│  │  Application     │  ┌────────────────────┐  │
│  │  Controller      │  │  Redis(缓存)      │  │
│  │  (对比+同步)     │  └────────────────────┘  │
│  └──────────────────┘                           │
└─────────────────────────┬───────────────────────┘
                          │ kubectl apply

              Kubernetes 集群(目标环境)

关键概念:

安装 ArgoCD

Helm 安装(推荐生产)

# 创建命名空间
kubectl create namespace argocd

# 添加 Helm 仓库
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

# 安装 ArgoCD
helm install argocd argo/argo-cd \
  --namespace argocd \
  --version 7.8.0 \
  --set server.service.type=LoadBalancer   # 或 NodePort

YAML 安装(快速测试)

kubectl apply -n argocd \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 等待所有组件就绪
kubectl wait --for=condition=available \
  deployment --all -n argocd --timeout=300s

# 查看 Pod 状态
kubectl get pods -n argocd
# NAME                                  READY   STATUS
# argocd-application-controller-0       1/1     Running
# argocd-repo-server-xxx                1/1     Running
# argocd-server-xxx                     1/1     Running
# argocd-redis-xxx                      1/1     Running

访问 ArgoCD UI

# 方法1:端口转发(本地访问)
kubectl port-forward svc/argocd-server -n argocd 8080:443 &
# 访问 https://localhost:8080

# 方法2:修改 Service 为 NodePort
kubectl patch svc argocd-server -n argocd \
  -p '{"spec": {"type": "NodePort"}}'
kubectl get svc argocd-server -n argocd
# NAME           TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)
# argocd-server  NodePort   10.96.1.10   <none>        443:32100/TCP

# 获取初始 admin 密码
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d
# 输出类似:Xf8mK2pQrT9vL3nA

# 修改密码(登录后立即修改)
argocd login localhost:8080 --username admin --password <上面的密> --insecure
argocd account update-password

安装 ArgoCD CLI

# Linux
curl -sSL -o /usr/local/bin/argocd \
  https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd

# 验证
argocd version
# argocd: v2.14.2

第一个 Application

准备 Git 仓库

首先需要一个存放 Kubernetes YAML 的 Git 仓库,目录结构示例:

my-k8s-configs/              ← Git 仓库根目录
├── apps/
│   ├── nginx-demo/
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── ingress.yaml
│   └── redis/
│       ├── deployment.yaml
│       └── service.yaml
└── README.md

apps/nginx-demo/deployment.yaml 内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
  namespace: demo
  labels:
    app: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx
        image: nginx:1.27
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "256Mi"

方法一:通过 UI 创建 Application

  1. 登录 ArgoCD UI
  2. 点击 “NEW APP”
  3. 填写:
    • Application Name: nginx-demo
    • Project: default
    • Sync Policy: Automatic(自动同步)
    • Repository URL: https://github.com/your-org/my-k8s-configs
    • Revision: HEAD(或指定分支/Tag)
    • Path: apps/nginx-demo
    • Cluster: https://kubernetes.default.svc(当前集群)
    • Namespace: demo
  4. 点击 “CREATE”

方法二:通过 YAML 创建 Application(推荐,GitOps 管理 ArgoCD 自身)

# argocd-app-nginx-demo.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-demo
  namespace: argocd
  # finalizer 确保删除 Application 时同步删除集群资源
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/my-k8s-configs
    targetRevision: HEAD   # 或 main、v1.2.3
    path: apps/nginx-demo  # 仓库中的目录路径
  destination:
    server: https://kubernetes.default.svc  # 当前集群
    namespace: demo
  syncPolicy:
    automated:
      prune: true     # 删除 Git 中不再存在的资源
      selfHeal: true  # 检测到漂移时自动修复
    syncOptions:
    - CreateNamespace=true  # 自动创建目标命名空间
kubectl apply -f argocd-app-nginx-demo.yaml

# 查看 Application 状态
kubectl get application -n argocd nginx-demo
# NAME         SYNC STATUS   HEALTH STATUS
# nginx-demo   Synced        Healthy

# 详细状态
argocd app get nginx-demo
# Name:               nginx-demo
# Project:            default
# Server:             https://kubernetes.default.svc
# Namespace:          demo
# URL:                https://localhost:8080/applications/nginx-demo
# Repo:               https://github.com/your-org/my-k8s-configs
# Target:             HEAD
# Path:               apps/nginx-demo
# SyncWindow:         Sync Allowed
# Sync Policy:        Automated (Prune)
# Sync Status:        Synced to HEAD (a1b2c3d)
# Health Status:      Healthy

方法三:CLI 创建

argocd app create nginx-demo \
  --repo https://github.com/your-org/my-k8s-configs \
  --path apps/nginx-demo \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace demo \
  --sync-policy automated \
  --auto-prune \
  --self-heal

漂移检测演示

GitOps 的核心价值之一是发现并修复“计划外变更”:

# 模拟有人直接修改集群(绕过 GitOps)
kubectl scale deployment nginx-demo -n demo --replicas=5

# ArgoCD 立即检测到漂移(约 3 分钟内,或 Webhook 触发后立即)
kubectl get application -n argocd nginx-demo
# NAME         SYNC STATUS   HEALTH STATUS
# nginx-demo   OutOfSync     Healthy
# ← OutOfSync 表示集群状态与 Git 不一致

# 如果开启了 selfHeal=true,ArgoCD 自动将副本数改回 Git 中的 2
# 可以在 UI 看到同步事件记录

# 手动触发同步
argocd app sync nginx-demo

# 查看同步历史
argocd app history nginx-demo
# ID  DATE                REVISION
# 1   2026-07-22 10:00:00  a1b2c3d (HEAD)
# 2   2026-07-22 10:15:32  a1b2c3d (HEAD)  ← selfHeal 触发的同步

常用运维命令

# 列出所有 Application
argocd app list

# 查看 Application 详情
argocd app get <app-name>

# 手动触发同步
argocd app sync <app-name>

# 回滚到上一个版本
argocd app rollback <app-name>

# 回滚到指定历史版本
argocd app rollback <app-name> <HISTORY-ID>

# 删除 Application(同时删除集群资源,因为有 finalizer)
argocd app delete <app-name>

# 暂停自动同步(维护窗口)
argocd app pause <app-name>

# 恢复自动同步
argocd app resume <app-name>

# 查看 Application 日志(查看同步过程)
argocd app logs <app-name>

私有仓库配置

# 添加私有 HTTPS 仓库
argocd repo add https://gitlab.company.com/k8s-configs \
  --username git \
  --password <personal-access-token>

# 添加 SSH 私钥认证
argocd repo add git@github.com:your-org/k8s-configs \
  --ssh-private-key-path ~/.ssh/id_rsa

# 查看已配置的仓库
argocd repo list

小结

GitOps 不是技术革新,而是工作流规范:所有变更通过 Git PR 审查、自动部署、自动漂移检测,消灭了传统运维中“谁改了线上”的黑盒问题。ArgoCD 的上手成本很低——安装 5 分钟,第一个 Application 10 分钟——但它带来的可观测性和可回滚能力是长期红利。下一篇将讲解如何用 Helm + Kustomize 管理多环境(dev/staging/production)的差异化配置。