前言
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 会很麻烦。
七、本篇要点回顾
- Kustomize 结构:base(共享)+ overlays(环境覆盖),无模板语法
- 补丁机制:
patches覆盖特定字段,configMapGenerator合并 ConfigMap - ArgoCD 自动检测
kustomization.yaml,spec.source.path指向 overlay 目录 - CI 更新镜像:用
kustomize edit set image更新 kustomization.yaml - ApplicationSet + Kustomize 实现多环境一键管理
namePrefix慎用------后期加 prefix 导致资源重建
下一篇预告:《RBAC 与多租户:团队权限隔离实战》------从配置管理进入权限管理,学习如何在 ArgoCD 中实现团队隔离。