Kubernetes无模板化的声明式配置定制工具
kustomize命令 是 Kubernetes 原生的配置定制工具,通过覆盖(overlay)的方式在不修改原始 YAML 的前提下,为不同环境生成定制后的资源清单。
与 Helm 的区别很关键:
{{ }},渲染结果依赖 values 的完整程度。kubectl apply -f 直接可用,不需要模板语法。kustomize 自 1.14 起内置于 kubectl,可以直接用 kubectl apply -k 而无需额外安装独立二进制。
# kubectl 内置(推荐,无需额外安装)
kubectl version --client # 输出中的 Kustomize Version 即内置版本
kubectl kustomize --help
# macOS / Linux (Homebrew)
brew install kustomize
# 官方脚本
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
# Go 安装
go install sigs.k8s.io/kustomize/kustomize/v5@latest
# 通过 Krew 安装
kubectl krew install kustomize
kustomize build <目录> [选项]
kustomize create [选项]
kustomize edit <子命令>
kustomize build . # 渲染当前目录
kustomize build overlays/prod # 渲染指定 overlay
kustomize build overlays/prod -o out.yaml
kustomize create --autodetect # 扫描目录下的 YAML 生成 kustomization.yaml
kustomize create --resources=deploy.yaml,svc.yaml
kustomize edit add resource deploy.yaml
kustomize edit add patch --path patch.yaml --group apps --version v1 --kind Deployment --name my-app
kustomize edit set image nginx=nginx:1.27
kustomize edit set namespace prod
kustomize edit set nameprefix prod-
kustomize edit set replicas my-app=3
kustomize edit add configmap app-config --from-file=app.properties
kustomize edit add label env:prod
kustomize edit fix # 把旧版字段自动升级为 v5 字段名
典型的多环境布局:
myapp/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
├── dev/
│ ├── kustomization.yaml
│ └── replicas-patch.yaml
└── prod/
├── kustomization.yaml
├── replicas-patch.yaml
└── resources-patch.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# 引用 base(相对路径),v5 中 bases 字段已废弃
resources:
- ../../base
# 命名空间与名称前后缀会同步更新所有引用处
namespace: prod
namePrefix: prod-
nameSuffix: -v2
# 统一追加标签与注解
labels:
- pairs:
env: prod
team: platform
includeSelectors: true # 同时写入 selector,注意会导致 Deployment 滚动重建
commonAnnotations:
owner: ops@example.com
# 替换镜像地址(按 name 匹配,不写 newTag 则保留原 tag)
images:
- name: nginx
newName: registry.example.com/nginx
newTag: "1.27"
# 副本数覆盖
replicas:
- name: my-app
count: 5
v5 推荐的统一写法是 patches,它同时支持 strategic merge 与 JSON patch:
patches:
# 1. 外部文件 + target 选择器(strategic merge patch)
- path: replicas-patch.yaml
target:
kind: Deployment
name: my-app
# 2. 内联 JSON patch(6902)
- patch: |-
- op: replace
path: /spec/template/spec/containers/0/resources/limits/cpu
value: "2"
target:
kind: Deployment
name: my-app
# 3. 内联 strategic merge patch
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
env:
- name: LOG_LEVEL
value: warn
replicas-patch.yaml(strategic merge,按 name 字段合并,列表元素按 name 对齐):
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
template:
spec:
containers:
- name: app
resources:
requests:
cpu: 500m
memory: 512Mi
v4 及以前的写法(v5 仍能识别但已标记废弃):
patchesStrategicMerge:
- replicas-patch.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-app
path: patch.json
configMapGenerator 会自动计算内容哈希并追加到名称上,内容一变名称就变,从而触发 Deployment 滚动更新:
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=info
files:
- app.properties
envs:
- app.env
secretGenerator:
- name: app-secret
literals:
- password=s3cr3t
envs:
- secret.env
# 关闭哈希后缀(不推荐,会失去自动滚动更新能力)
generatorOptions:
disableNameSuffixHash: true
labels:
generated-by: kustomize
components 与 overlay 类似,但不是完整配置,而是一组可插拔的补丁片段,适合注入 sidecar、开关监控等:
# overlays/prod/kustomization.yaml
components:
- ../../components/logging
# components/logging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
patches:
- path: sidecar.yaml
# 渲染预览(不提交到集群)
kubectl kustomize overlays/prod
kubectl kustomize overlays/prod > rendered.yaml
# 直接应用
kubectl apply -k overlays/prod
kubectl delete -k overlays/prod
# 查看将要发生的变更
kubectl diff -k overlays/prod
# 服务端 dry-run 校验
kubectl apply -k overlays/prod --dry-run=server
patchesStrategicMerge 与 patches 的区别:前者是 v3/v4 的旧字段,只能接受文件路径,且同一文件无法指定 target;patches 是 v5 的统一入口,既能引用文件也支持内联字符串,并能用 target 精确选择对象。新项目一律用 patches,老项目可用 kustomize edit fix 自动迁移。name 对齐列表元素、按字段合并,适合改容器配置;JSON patch 按数组下标与路径操作,适合精确替换。用错会导致整个列表被覆盖而不是合并。--enable-helm(Helm Chart 膨胀功能)。需要渲染 Helm Chart 时必须安装独立 kustomize。labels 加 includeSelectors: true 会改动 Deployment 的 selector,而 selector 不可变,直接 apply 会报 field is immutable,必须先删除再重建工作负载。configMapGenerator 生成的名称带哈希后缀,因此 Deployment 里不能硬编码 configMapRef.name,必须写原始名称,由 kustomize 负责替换引用。若引用名写了带哈希的全名,渲染后会找不到对象。resources 与 bases 不能同时出现。v5 中 bases 已废弃,混用会直接报错。kustomization.yaml,否则 kubectl apply -k 报 unable to find one of 'kustomization.yaml' ...。--load-restrictor LoadRestrictionsRootOnly 禁止引用上级目录之外的文件,把 base 放在仓库外会被拒绝。确实需要时用 --load-restrictor LoadRestrictionsNone(会削弱可移植性)。secretGenerator 生成的 Secret 内容以明文写在 kustomization.yaml 或 env 文件里,会进入 Git 历史,生产环境应改用 Sealed Secrets、External Secrets 等方案。namespace: prod 只会给资源加上 namespace 元数据,不会自动创建 Namespace 对象,需要单独维护或用 resources 引入。kubectl — Kubernetes集群管理工具helm — Kubernetes包管理器kubeadm — Kubernetes集群安装工具velero — 集群备份与恢复