Skip to content

Kustomize

Kustomize 用来在不改原始 YAML 的情况下叠加环境差异。它的核心思路是把公共资源放在 base,不同环境用 overlay 添加镜像版本、副本数、域名、资源规格、补丁和 ConfigMap/Secret 生成规则。

Helm 更像应用包和模板系统,Kustomize 更像 YAML 叠加器。两者都能用于发布:Helm 适合 Chart 化的应用和第三方组件;Kustomize 适合原生 YAML、环境差异、GitOps 部署仓库。Argo CD 同时支持 Helm 和 Kustomize。

一、目录结构

常见结构:

text
deploy/
  base/
    deployment.yaml
    service.yaml
    kustomization.yaml
  overlays/
    dev/
      kustomization.yaml
      patch-replicas.yaml
    prod/
      kustomization.yaml
      patch-replicas.yaml

base/kustomization.yaml

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

渲染:

bash
kubectl kustomize deploy/base
kubectl apply -k deploy/base

kubectl 内置了 Kustomize 能力,简单场景不用单独安装 kustomize 命令。

二、base 资源

base/deployment.yaml

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: registry.example.com/demo/web:latest
          ports:
            - name: http
              containerPort: 8080

base/service.yaml

yaml
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - name: http
      port: 80
      targetPort: http

base 里放所有环境都一致的结构。比如容器端口、Service 名称、基本 label、探针路径、通用环境变量。环境不同的镜像 tag、副本数、域名和资源规格放到 overlay。

三、overlay 覆盖镜像和命名空间

overlays/prod/kustomization.yaml

yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: prod
namePrefix: prod-
resources:
  - ../../base
images:
  - name: registry.example.com/demo/web
    newTag: "1.3.5"
patches:
  - path: patch-replicas.yaml

patch-replicas.yaml

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3

渲染 prod 环境:

bash
kubectl kustomize deploy/overlays/prod
kubectl apply -k deploy/overlays/prod

namePrefix 会影响资源名称。Service、Deployment、ConfigMap 的引用关系会由 Kustomize 尽量更新,但外部系统、监控规则、Ingress/Gateway 里写死的名称要特别检查。

四、ConfigMap 和 Secret 生成

Kustomize 可以从文件或字面量生成 ConfigMap:

yaml
configMapGenerator:
  - name: web-config
    literals:
      - LOG_LEVEL=info
      - FEATURE_FLAG=false

生成的 ConfigMap 名称默认带 hash,比如 web-config-7g6m8k9b5m。内容变化时名称变化,Deployment 引用也跟着更新,从而触发 Pod 滚动。这个机制比固定 ConfigMap 名称更容易让配置变更生效。

Secret 也能生成:

yaml
secretGenerator:
  - name: web-secret
    literals:
      - DB_PASSWORD=change-me

Secret 明文放在 Git 仓库里风险很高。真实环境里更常见的做法是 External Secrets、Sealed Secrets、SOPS,或者由 CI/CD 在部署阶段注入。

五、patch 的两种方式

Strategic merge patch 适合改 Kubernetes 内置资源:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  template:
    spec:
      containers:
        - name: web
          resources:
            requests:
              cpu: 200m
              memory: 256Mi

JSON6902 patch 适合精确修改字段:

yaml
patches:
  - target:
      kind: Deployment
      name: web
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 3

patch 过多时,overlay 会变得难读。环境差异很大的应用,与其堆很多 patch,不如重新审视 base 是否抽得太满,或者拆成更清楚的组件目录。

六、和 Helm 的配合

Kustomize 可以直接管理 Helm 渲染后的 YAML,也可以由 Argo CD 分别支持 Helm 和 Kustomize。常见组合:

场景写法
第三方组件Helm Chart + values
自研服务Kustomize base/overlay 或自研 Helm Chart
多环境 GitOps每个环境一个 overlay
平台组件轻微差异Helm values 分环境管理

Kustomize 不负责 release history,回滚主要依赖 Git 版本和 Argo CD 同步记录。Helm 有 release history,但 values 和 Chart 来源也要能追溯。

七、排查入口

现象查看方式
渲染结果不符合预期kubectl kustomize <dir>
patch 没生效target 的 kind/name/namespace 是否匹配
ConfigMap 变化没滚动是否禁用了 name hash,Deployment 是否引用生成后的名称
apply 后资源名称变化检查 namePrefixnameSuffix
Argo CD 同步异常看渲染结果、应用事件和差异比较

Kustomize 的排查关键是看最终渲染结果。源文件只是输入,集群最终收到的 YAML 才是实际对象。