【GitOps·ArgoCD篇】与 Kustomize 集成:多环境配置管理

前言

Kustomize 是 K8s 原生的配置管理工具------不需要模板语法,通过"叠加覆盖"的方式管理多环境差异。ArgoCD 原生支持 Kustomize,本篇从零讲解 Kustomize 的使用和与 ArgoCD 的集成。


一、Kustomize 核心概念

什么是 Kustomize

复制代码
传统方式(Helm):
  模板 + 变量 → 渲染 → 最终 YAML
  问题:模板语法复杂,调试困难

Kustomize:
  基础 YAML + 覆盖 YAML → 叠加 → 最终 YAML
  优势:无模板语法,所见即所得,K8s 原生支持

目录结构

复制代码
myapp-deploy/
├── base/                    # 所有环境共享的基础配置
│   ├── deployment.yaml      # 基础 Deployment
│   ├── service.yaml         # 基础 Service
│   ├── configmap.yaml       # 基础 ConfigMap
│   └── kustomization.yaml   # 基础 Kustomize 配置
└── overlays/                # 环境特定覆盖
    ├── dev/
    │   ├── kustomization.yaml
    │   └── replicas-patch.yaml
    ├── staging/
    │   ├── kustomization.yaml
    │   └── resources-patch.yaml
    └── prod/
        ├── kustomization.yaml
        ├── replicas-patch.yaml
        ├── resources-patch.yaml
        └── ingress.yaml

二、基础配置(base)

base/deployment.yaml

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1                    # 基础值,环境覆盖会修改
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: registry.com/myapp:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi
        env:
        - name: APP_ENV
          value: dev             # 基础值

base/service.yaml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

base/kustomization.yaml

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# 引用的资源文件
resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml

# 公共标签(自动添加到所有资源)
commonLabels:
  app.kubernetes.io/name: myapp
  app.kubernetes.io/managed-by: argocd

# 公共注解
commonAnnotations:
  managed-by: gitops

# 镜像配置(CI 可更新这里来改变镜像版本)
images:
  - name: registry.com/myapp
    newTag: latest

三、环境覆盖(overlays)

overlays/dev/kustomization.yaml

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# 继承 base
resources:
  - ../../base

# 命名空间
namespace: myapp-dev

# 公共标签追加
commonLabels:
  environment: dev

# 镜像覆盖
images:
  - name: registry.com/myapp
    newTag: dev-latest          # dev 用 latest

# 补丁覆盖
patches:
  - path: replicas-patch.yaml
yaml 复制代码
# overlays/dev/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1                    # dev 只需1个副本

overlays/staging/kustomization.yaml

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

namespace: myapp-staging

commonLabels:
  environment: staging

images:
  - name: registry.com/myapp
    newTag: v2.0.0-staging       # staging 用固定版本

patches:
  - path: replicas-patch.yaml
  - path: resources-patch.yaml
yaml 复制代码
# overlays/staging/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 2                    # staging 2个副本
yaml 复制代码
# overlays/staging/resources-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: app
        resources:
          requests:
            cpu: 250m           # staging 更高资源
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 512Mi
        env:
        - name: APP_ENV
          value: staging        # 覆盖环境变量

overlays/prod/kustomization.yaml

yaml 复制代码
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base
  - ingress.yaml                 # prod 专用 Ingress
  - hpa.yaml                     # prod 专用 HPA

namespace: myapp-prod

commonLabels:
  environment: prod

images:
  - name: registry.com/myapp
    newTag: v2.0.0               # prod 用正式版本

patches:
  - path: replicas-patch.yaml
  - path: resources-patch.yaml
yaml 复制代码
# overlays/prod/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 4                    # prod 4个副本
yaml 复制代码
# overlays/prod/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts: [myapp.com]
    secretName: myapp-tls
  rules:
  - host: myapp.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80

四、ArgoCD 中使用 Kustomize

Application 配置

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-prod
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/myapp-deploy.git
    targetRevision: main
    path: overlays/prod           # 指向 overlay 目录
    # ArgoCD 自动检测 kustomization.yaml
    # 不需要额外配置

    # 可选:在 ArgoCD 中覆盖 Kustomize 配置
    kustomize:
      # 覆盖镜像版本(CI 自动更新时用)
      images:
        - registry.com/myapp:v2.0.0

      # 覆盖通用标签
      commonLabels:
        deployed-by: argocd

      # 覆盖名称前缀
      namePrefix: prod-

  destination:
    server: https://kubernetes.default.svc
    namespace: myapp-prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

多环境 ApplicationSet

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-all-envs
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - env: dev
            namespace: myapp-dev
          - env: staging
            namespace: myapp-staging
          - env: prod
            namespace: myapp-prod
  template:
    metadata:
      name: 'myapp-{{env}}'
    spec:
      source:
        repoURL: https://github.com/myorg/myapp-deploy.git
        path: 'overlays/{{env}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

五、CI 自动更新镜像版本

在 CI 中更新 Kustomize images

bash 复制代码
# CI 流水线中更新镜像版本
# 方式1:直接修改 kustomization.yaml
cd myapp-deploy
sed -i 's|newTag:.*|newTag: abc123|' overlays/prod/kustomization.yaml
git commit -am "update prod image to abc123"
git push origin main

# 方式2:用 kustomize CLI
kustomize edit set image registry.com/myapp=registry.com/myapp:abc123
# 会自动更新 kustomization.yaml 中的 images 部分

GitLab CI 示例

yaml 复制代码
update-image:
  stage: deploy
  needs: [package]
  script:
    - |
      cd deploy-repo
      # 更新各环境的镜像版本
      for env in dev staging prod; do
        kustomize edit set image \
          registry.com/myapp=registry.com/myapp:${CI_COMMIT_SHORT_SHA} \
          --path overlays/${env}
      done
    - git config user.email "ci-bot@mycompany.com"
    - git config user.name "CI Bot"
    - git add .
    - git commit -m "update image to ${CI_COMMIT_SHORT_SHA}"
    - git push "https://ci-bot:${GITLAB_TOKEN}@github.com/myorg/myapp-deploy.git" main
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

六、Kustomize 高级技巧

configMapGenerator

yaml 复制代码
# base/kustomization.yaml
configMapGenerator:
  - name: app-config
    literals:
      - LOG_LEVEL=info
      - MAX_CONNECTIONS=100

# overlays/prod/kustomization.yaml
configMapGenerator:
  - name: app-config
    behavior: merge            # 合并而非替换
    literals:
      - LOG_LEVEL=warn         # 覆盖
      - MAX_CONNECTIONS=1000   # 覆盖
      - ALERT_WEBHOOK=https://hooks.slack.com/...  # 新增

secretGenerator

yaml 复制代码
# 用文件创建 Secret(不加密,需配合 Sealed Secrets)
secretGenerator:
  - name: app-secret
    files:
      - db-password.txt
      - api-key.txt
    # 会自动 base64 编码

namePrefix / nameSuffix

yaml 复制代码
# overlays/prod/kustomization.yaml
namePrefix: prod-    # 所有资源名加前缀
# deployment.yaml 中的 myapp → 变成 prod-myapp

nameSuffix: -v2      # 所有资源名加后缀
# → prod-myapp-v2

踩坑提示namePrefix 会改变资源名,导致 ArgoCD 在同步时需要创建新资源而非更新现有资源。迁移时需要先删除旧资源。建议从一开始就规划好命名,后期加 prefix 会很麻烦。


七、本篇要点回顾

  1. Kustomize 结构:base(共享)+ overlays(环境覆盖),无模板语法
  2. 补丁机制:patches 覆盖特定字段,configMapGenerator 合并 ConfigMap
  3. ArgoCD 自动检测 kustomization.yamlspec.source.path 指向 overlay 目录
  4. CI 更新镜像:用 kustomize edit set image 更新 kustomization.yaml
  5. ApplicationSet + Kustomize 实现多环境一键管理
  6. namePrefix 慎用------后期加 prefix 导致资源重建

下一篇预告:《RBAC 与多租户:团队权限隔离实战》------从配置管理进入权限管理,学习如何在 ArgoCD 中实现团队隔离。

相关推荐
heimeiyingwang1 天前
【GitOps·ArgoCD篇】RBAC与多租户:团队权限隔离实战
argocd·gitops
heimeiyingwang1 天前
【GitOps·ArgoCD篇】健康检查与资源钩子:自定义健康状态
argocd·gitops
heimeiyingwang4 天前
【GitOps·ArgoCD篇】同步策略:自动同步、手动同步与同步钩子
argocd·gitops
heimeiyingwang7 天前
【GitOps·入门篇】工具生态:ArgoCD、Flux、Jenkins X 对比选型
jenkins·flux·argocd·gitops
xiaoxiangsiyan17 天前
GitLab CI/CD 自托管(EE 企业版)+ Kubernetes Runner 集群 + ArgoCD(GitOps 部署)
运维·网络·ci/cd·容器·kubernetes·gitlab·argocd
nvd1117 天前
ArgoCD 双层轮询深入拆解:从 redis-app.yaml 注册到缓存重建的完整链路
redis·缓存·argocd
meijinmeng18 天前
EKS 集群 ArgoCD `v3.0.6 → v3.1.x → v3.2.x` 备份,恢复,升级,巡检手册
argocd·cicd
运维大师20 天前
【K8S 运维实战】32-GitOps实践ArgoCD
运维·kubernetes·argocd
spider_xcxc20 天前
Argo CD Webhook 完全指南:从原理到实战,实现 Git 变更即时同步
argocd