Chapter 05

Kustomize 集成与多环境

用 Kustomize 的 base + overlays 模式管理多环境配置,让同一份基础资源在 dev、staging、prod 三个环境灵活差异化,配合 CI 实现镜像自动更新。

Kustomize 简介

Kustomize 是 Kubernetes 官方的配置管理工具(已集成进 kubectl),它不使用模板引擎,而是通过"补丁(patch)"的方式对基础 YAML 进行差异化定制。核心思想是 DRY(Don't Repeat Yourself):维护一份 base 配置,通过 overlay 叠加环境差异,避免三套环境复制三份相似的 YAML。

Kustomize vs Helm

  • Kustomize:无模板语法,纯 YAML 补丁,简单直观
  • Helm:Go 模板语法,功能强大,学习曲线较陡
  • Kustomize 适合:自有应用、简单环境差异化
  • Helm 适合:复杂配置逻辑、对外发布的可重用 Chart
  • ArgoCD 可以同时使用两者

ArgoCD 自动检测 Kustomize

无需在 Application source 中显式声明使用 Kustomize,ArgoCD 的 Repo Server 会自动检测目录下是否存在 kustomization.yaml,若存在则自动调用 kustomize build 渲染。

三环境目录结构

推荐的 Kustomize 多环境目录组织方式:

my-gitops-config/
└── apps/
    └── my-app/
        ├── base/                        # 基础配置(所有环境共享)
        │   ├── kustomization.yaml
        │   ├── deployment.yaml
        │   ├── service.yaml
        │   └── hpa.yaml
        └── overlays/
            ├── dev/                     # 开发环境覆盖
            │   ├── kustomization.yaml
            │   └── replica-patch.yaml
            ├── staging/                 # 预发环境覆盖
            │   ├── kustomization.yaml
            │   └── resources-patch.yaml
            └── prod/                    # 生产环境覆盖
                ├── kustomization.yaml
                ├── replica-patch.yaml
                └── hpa-patch.yaml

base 配置

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- hpa.yaml

# base/deployment.yaml(基础,镜像 tag 用 latest 占位)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: ghcr.io/my-org/my-app:latest
        resources:
          requests:
            cpu: 50m
            memory: 64Mi

overlay 配置(生产环境)

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production                 # 覆盖所有资源的 namespace
namePrefix: prod-                     # 所有资源名称加前缀(可选)
commonLabels:
  env: production                    # 为所有资源添加公共标签

bases:
- ../../base                          # 引用 base

images:                              # 镜像 tag 覆盖(CI 更新此字段)
- name: ghcr.io/my-org/my-app
  newTag: v1.5.2                      # CI 构建后更新此 tag

patches:                             # 生产环境差异化补丁
- path: replica-patch.yaml
- path: hpa-patch.yaml

# overlays/prod/replica-patch.yaml(生产副本数)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 5                         # 生产5副本(base 是1)
  template:
    spec:
      containers:
      - name: my-app
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 512Mi

images 字段:配合 CI 自动更新镜像 Tag

GitOps 中,CI 构建完镜像后需要将新 tag 写入 Git 配置仓库,ArgoCD 才能同步部署。推荐流程:

CI → Git → ArgoCD 自动更新流程

┌──────────┐   代码提交   ┌──────────────┐  构建推送镜像  ┌─────────────┐
 开发推送  ├────────────►│   GitHub     ├──────────────►│ ghcr.io     
 代码                      Actions                    my-app:v1.6 
└──────────┘             └──────┬───────┘               └─────────────┘
                                  
                    更新配置仓库 kustomization.yaml
                    images[0].newTag: v1.6
                                  
┌─────────────┐   Git Poll   ┌──────────────┐  auto-sync   ┌─────────────┐
 配置仓库    ├─────────────►│   ArgoCD     ├─────────────►│  K8s 集群   
 (Git)                       检测变更                    部署新版本  
└─────────────┘             └──────────────┘              └─────────────┘
# CI 脚本:构建完成后更新配置仓库中的 image tag
IMAGE_TAG="v${GITHUB_RUN_NUMBER}"

# 克隆配置仓库
git clone https://github.com/my-org/my-gitops-config
cd my-gitops-config

# 使用 kustomize edit 更新镜像 tag
cd apps/my-app/overlays/prod
kustomize edit set image \
  ghcr.io/my-org/my-app=ghcr.io/my-org/my-app:${IMAGE_TAG}

# 提交更新
git add .
git commit -m "chore: update my-app image to ${IMAGE_TAG}"
git push

ConfigMap 与 Secret 生成器

Kustomize 的生成器能自动为 ConfigMap/Secret 添加内容 hash 后缀,实现配置变更时自动滚动更新 Pod:

# kustomization.yaml 中的生成器
configMapGenerator:
- name: app-config
  files:
  - config.properties
  options:
    disableNameSuffixHash: false   # 默认 false,自动添加 hash 后缀

secretGenerator:
- name: app-secrets
  envs:
  - .env.secret                    # 注意:此文件不应提交到 Git!
  options:
    disableNameSuffixHash: true    # Secret 通常不需要 hash(结合 AVP)

ArgoCD Application:多环境分别部署

# 生产环境 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-prod
  namespace: argocd
spec:
  project: production
  source:
    repoURL: https://github.com/my-org/my-gitops-config
    targetRevision: main
    path: apps/my-app/overlays/prod   # 指向 prod overlay
    kustomize:
      version: v5.0.0               # 指定 Kustomize 版本(可选)
  destination:
    server: https://prod-cluster.example.com:6443
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
source.kustomize 字段可省略

如果 path 指向的目录中存在 kustomization.yaml 文件,ArgoCD 会自动以 Kustomize 模式渲染,无需显式写 kustomize 字段。kustomize.version 字段用于锁定特定版本,建议在生产环境指定,避免 ArgoCD 升级后 Kustomize 版本变化导致意外差异。

本章小结

Kustomize 的 base + overlays 模式让一套配置适配多个环境,避免重复维护。images 字段配合 CI 自动更新镜像 tag 是 GitOps 流水线的关键环节。ConfigMap 生成器的 hash 后缀机制确保配置变更能触发 Pod 滚动更新。相比 Helm,Kustomize 更适合自有应用的多环境管理。