Kubernetes 基础体系 · 第 55/83 篇。示例基于 Kubernetes 当前稳定 API;弃用、版本偏差、云厂商差异和生产风险会明确说明。

Kustomize 配置管理:Base、Overlay、Patch、Generator 和边界

Kustomize 是 Kubernetes 原生配置定制工具。它读取一组 Kubernetes YAML,按照声明式规则进行组合、变换和生成,最后输出一组可以交给 kubectl 或 GitOps 控制器应用的 YAML。

它与 Helm 的核心区别是:Kustomize 通常不把 YAML 当作模板执行,而是把 YAML 解析成 Kubernetes 对象,再对对象进行结构化修改。它没有 Helm 那样的 Chart、Values、Release 和模板函数体系,因此更适合“已有 YAML 的环境差异管理”,但不适合所有类型的配置复用。


一、先建立模型:Kustomize 处理的是什么

Kustomize 的输入通常是一个目录,其中包含:

  • kustomization.yaml:描述资源、补丁、生成器和变换规则;
  • Kubernetes 资源文件;
  • 其他被引用的 Base 或 Overlay;
  • 生成器所需的文件、字面量或环境变量文件。

最小的 kustomization.yaml 可以是:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

这里的 apiVersion 是 Kustomize 配置文件的 API 版本,不是 Kubernetes 工作负载的 API 版本。它与资源中的:

apiVersion: apps/v1
kind: Deployment

属于两套不同的 API 体系。

Kustomize 的基本处理模型可以抽象为:

O=Tn(Tn1(T2(T1(A(R)))))O = T_n(T_{n-1}(\cdots T_2(T_1(A(R)))\cdots))

其中:

  • RR 是读取到的原始资源集合;
  • AA 是资源累加过程,例如加载 resources 引用的 Base;
  • TiT_i 是某一个变换器,例如补丁、名称前缀、镜像替换或命名空间变换;
  • OO 是最终输出的 Kubernetes YAML。

这个模型表达了三个重要事实:

  1. Kustomize 不是把字符串直接替换后输出;
  2. 资源之间的引用可能随名称变换一起更新;
  3. 最终结果取决于多个变换的组合,而不是单个文件的内容。

实际变换顺序由 Kustomize 内部的资源加载器和变换器决定,不应把它当成可以任意控制的脚本执行顺序。对于有顺序依赖的复杂修改,应通过明确的资源结构和补丁目标消除歧义,而不是依赖某个版本的内部排序。


二、Base 和 Overlay:复用与环境差异的结构

1. Base 是可复用的共同配置

Base 表示一组与环境无关,或者至少可以被多个环境共同使用的资源。

目录示例:

app/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
└── overlays/
    ├── staging/
    │   ├── kustomization.yaml
    │   └── replicas.yaml
    └── production/
        ├── kustomization.yaml
        └── replicas.yaml

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

base/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app.kubernetes.io/name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports:
            - name: http
              containerPort: 80

base/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app.kubernetes.io/name: web
  ports:
    - name: http
      port: 80
      targetPort: http

Base 本身也可以直接构建:

kubectl kustomize base

或者:

kustomize build base

前者使用当前 kubectl 内置的 Kustomize 版本,后者使用独立安装的 Kustomize。两者的支持能力可能不同,因此生产构建应固定工具版本,并在 CI 中验证生成结果。

2. Overlay 是针对某个环境或部署场景的入口

Overlay 通过 resources 引用 Base,然后叠加环境差异。

overlays/staging/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: staging
namePrefix: staging-

resources:
  - ../../base

patches:
  - path: replicas.yaml
    target:
      group: apps
      version: v1
      kind: Deployment
      name: web

overlays/staging/replicas.yaml

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

构建:

kubectl kustomize overlays/staging

输出中的 Deployment 会具有类似结果:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: staging-web
  namespace: staging
spec:
  replicas: 2

Service 也会得到 staging- 前缀和 staging 命名空间。

这里的 metadata.name: web 是补丁匹配用的原始资源名;补丁匹配发生在资源名称变换的语义范围内,不能简单地把目标写成最终输出的 staging-web。如果补丁同时指定了 target,应让 target 明确描述原始对象的 Group、Version、Kind 和 Name。

3. Base 与 Overlay 的边界

Base 适合放:

  • 工作负载结构;
  • Service;
  • 通用标签;
  • 通用探针;
  • 默认容器端口;
  • 所有环境都需要的 RBAC 或 ServiceAccount。

Overlay 适合放:

  • 副本数;
  • 镜像版本;
  • 命名空间;
  • 环境变量;
  • 资源请求和限制;
  • Ingress 域名;
  • 生产环境才需要的补丁。

不应把某个环境的绝对路径、云厂商专用注解或生产域名放进 Base,否则 Base 的复用性会下降,Overlay 也会被迫通过反向覆盖来修正错误默认值。

一个 Overlay 引用另一个 Overlay 通常会使层级关系难以推断。更稳妥的结构是:多个环境共同引用同一个 Base,环境之间共享的差异再抽成 Component 或新的中间 Base,而不是让 production 继承 staging


三、Patch:对结构化 Kubernetes 对象进行修改

Patch 是 Kustomize 修改已有资源的机制。现代写法统一使用 patches 字段,它可以承载不同类型的补丁。旧字段 patchesStrategicMergepatchesJson6902 仍可能在旧项目中出现,但应注意版本兼容和弃用状态,新的配置优先使用 patches

1. Strategic Merge Patch

Strategic Merge Patch 按 Kubernetes 对象结构合并 YAML。例如:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: web
          resources:
            requests:
              cpu: 100m
              memory: 128Mi

如果它被应用到原始 Deployment:

spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports:
            - containerPort: 80

合并结果的核心部分是:

spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 100m
              memory: 128Mi

containers 这类列表通常依据 Kubernetes 的结构化合并键进行合并,Deployment 容器列表的键通常是 name。因此 name: web 的容器被修改,而不是简单地把整个列表追加一遍。

可以使用显式的 $patch 指令:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  template:
    spec:
      containers:
        - name: web
          $patch: replace
          image: nginx:1.27
          ports:
            - name: http
              containerPort: 80

这表示用补丁中的容器列表替换原有列表,而不是按容器名合并。

2. JSON Patch

JSON Patch 使用 RFC 6902 风格的操作,适合表达精确修改:

- op: replace
  path: /spec/replicas
  value: 3

对应 Kustomization:

patches:
  - target:
      group: apps
      version: v1
      kind: Deployment
      name: web
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 3

JSON Patch 的路径必须真实存在。以下操作的失败条件不同:

- op: replace
  path: /spec/template/spec/containers/0/image
  value: nginx:1.27

要求数组中确实存在第一个容器以及 image 字段;如果资源结构不同,构建会失败。

- op: add
  path: /spec/template/spec/containers/0/env/-
  value:
    name: LOG_LEVEL
    value: info

要求 env 数组已存在。若 env 不存在,不能假设 /- 会自动创建父数组,通常需要先添加 /env,或使用更合适的结构化补丁。

JSON Patch 的优点是路径精确,缺点是依赖数组索引。容器顺序变化后,/containers/0 可能不再指向原来的容器。

3. CRD 是 Patch 的重要边界

Strategic Merge Patch 依赖 Kubernetes 类型的合并语义。对于许多内置资源,Kustomize 知道列表如何按键合并;对于自定义资源,Kustomize 通常不能自动获得完整的 Kubernetes OpenAPI 合并信息。

因此对 CRD 的列表字段使用 Strategic Merge Patch 可能得到与预期不同的结果,例如列表整体替换、重复追加或字段合并不符合业务语义。修改 CRD 实例时,应优先:

  • 使用 JSON Patch;
  • 使用 CRD 明确支持的结构;
  • 在目标集群和固定 Kustomize 版本上执行构建测试;
  • 不把“看起来像 Kubernetes YAML”误认为“具有内置资源的合并语义”。

4. Patch 的匹配必须唯一

如果一个补丁匹配多个对象,结果可能不是预期的单对象修改;如果匹配不到对象,构建通常会报错。诊断时先执行:

kubectl kustomize overlays/staging > rendered.yaml
kubectl get -f rendered.yaml --dry-run=client -o name

也可以直接检查目标对象:

kubectl kustomize overlays/staging | grep -n -A8 -B3 'name: staging-web'

生产流水线不应只检查 kubectl kustomize 命令成功,还应检查输出中关键字段,例如副本数、镜像、命名空间和 Service 选择器。


四、Generator:从输入生成 ConfigMap 和 Secret

Generator 不是运行时读取配置,而是在构建阶段生成 Kubernetes 资源。最常见的两种生成器是:

  • configMapGenerator
  • secretGenerator

1. ConfigMapGenerator

示例:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml

configMapGenerator:
  - name: web-config
    literals:
      - LOG_LEVEL=info
      - FEATURE_X_ENABLED=false

它会生成一个名字类似下面的 ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config-7k5m6d8f4c
data:
  FEATURE_X_ENABLED: "false"
  LOG_LEVEL: info

默认情况下,生成器会根据内容计算哈希后缀。只要 data 内容变化,名称就会变化。

Deployment 可以这样引用:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web
    spec:
      containers:
        - name: web
          image: nginx:1.27
          envFrom:
            - configMapRef:
                name: web-config

Kustomize 会识别这个引用,并把它改写为带哈希的实际名称,例如:

envFrom:
  - configMapRef:
      name: web-config-7k5m6d8f4c

因此配置变化同时导致:

  1. 新 ConfigMap 名称生成;
  2. Deployment 引用名称改变;
  3. Pod Template 的内容改变;
  4. Deployment 触发滚动更新。

这是一条由内容哈希驱动的发布链路,而不是 Kubernetes 自动比较 ConfigMap 内容后重启 Pod。

2. SecretGenerator

secretGenerator:
  - name: web-secret
    literals:
      - username=admin
      - password=change-me

生成结果中的 data 通常是 Base64 编码:

apiVersion: v1
kind: Secret
metadata:
  name: web-secret-6g7h8k9m2b
type: Opaque
data:
  password: Y2hhbmdlLW1l
  username: YWRtaW4=

Base64 不是加密。任何能够读取该 Secret 的人都可以解码;如果把明文凭据放进 Git,再由 secretGenerator 生成 Secret,Git 历史中仍然存在明文风险。

更安全的方案包括:

  • 使用外部 Secret 管理系统;
  • 使用 Git 加密方案;
  • 让 GitOps 控制器在集群侧解密;
  • 严格限制仓库、构建日志和生成产物的访问权限。

secretGenerator 只解决“如何生成 Kubernetes Secret YAML”,不解决密钥保管、轮换、审计和访问控制。

3. Generator 的行为和名称冲突

生成器可以配置:

configMapGenerator:
  - name: shared-config
    behavior: merge
    literals:
      - LOG_LEVEL=debug

常见的 behavior 语义是:

  • create:创建;
  • replace:替换同名生成结果;
  • merge:与已有生成结果合并。

这里的“已有”通常指 Kustomize 当前资源累加范围中已存在的生成对象,不是指向 Kubernetes API 查询一个线上对象。Kustomize build 默认不读取集群状态,因此不能把集群里已有的 ConfigMap 当作输入进行合并。

如果多个资源最终产生相同的资源身份,Kustomize 可能报告资源 ID 冲突。不要用 behavior: merge 掩盖两个环境无意中复用了同一个名称的问题,应先确认名称、层级和数据来源是否合理。

4. 是否关闭哈希后缀

可以通过:

generatorOptions:
  disableNameSuffixHash: true

关闭生成资源的哈希后缀,但这会失去“配置变更自动改变 Pod Template”的机制。此时更新 ConfigMap 后,已运行的 Pod 是否重新读取配置取决于应用本身:

  • 有些应用只在启动时读取;
  • 有些应用会监听文件变化;
  • 通过环境变量注入时,进程通常不会自动获得新环境变量。

关闭哈希不是单纯的命名偏好,而是改变了配置发布和进程重启语义。


五、名称、命名空间和引用变换

Kustomize 支持对资源名称添加前缀和后缀:

namePrefix: prod-
nameSuffix: -v2

资源名称会变成类似:

prod-web-v2

Kustomize 还会尝试更新已知的名称引用,例如:

  • Deployment 的 configMapRef
  • Pod 的 secretRef
  • ServiceAccount 引用;
  • 某些卷引用;
  • Service 相关引用。

这种引用识别依赖 Kustomize 已知的字段路径。自定义 CRD 中的任意字符串字段不会自动被当作资源引用。例如:

spec:
  configName: web-config

如果这是某个 CRD 的业务字段,Kustomize 不一定知道它需要跟随 namePrefix 或生成器哈希变化。此时需要使用补丁、替换机制或由控制器自身处理。

namespace 变换也不是简单的文本替换:

namespace: production

它通常会作用于命名空间级资源,但不会把集群级资源,例如 ClusterRole,变成命名空间资源。某些 CRD 字段中的命名空间字符串也不会因为“看起来像 namespace”就自动改变。

常见错误是把 metadata.namespace、Service DNS 名称和应用配置中的任意字符串混为一谈。Kustomize 只能变换它理解的 Kubernetes 结构和已知引用。


六、一个完整可运行的构建示例

目录:

demo/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── kustomization.yaml
│   └── app.env
└── overlays/
    └── production/
        ├── kustomization.yaml
        └── replicas.yaml

base/app.env

LOG_LEVEL=info
FEATURE_X_ENABLED=false

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

configMapGenerator:
  - name: web-config
    envs:
      - app.env

base/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app.kubernetes.io/name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web
    spec:
      containers:
        - name: web
          image: nginx:1.27
          envFrom:
            - configMapRef:
                name: web-config
          ports:
            - name: http
              containerPort: 80

base/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app.kubernetes.io/name: web
  ports:
    - name: http
      port: 80
      targetPort: http

overlays/production/replicas.yaml

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

overlays/production/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: production
namePrefix: prod-

resources:
  - ../../base

images:
  - name: nginx
    newTag: "1.27"

patches:
  - path: replicas.yaml
    target:
      group: apps
      version: v1
      kind: Deployment
      name: web

构建:

kubectl kustomize demo/overlays/production

预期结果包括:

metadata:
  name: prod-web
  namespace: production

Deployment 的副本数为 3,并且引用类似:

envFrom:
  - configMapRef:
      name: prod-web-config-<hash>

其中 <hash> 只是说明位置,实际值由文件内容计算,不能在脚本中硬编码。

应用前先查看差异:

kubectl diff -k demo/overlays/production

应用:

kubectl apply -k demo/overlays/production

验证:

kubectl -n production get deployment,service,configmap,pods
kubectl -n production rollout status deployment/prod-web

这里必须区分三个阶段:

  1. kustomize buildkubectl kustomize:只在本地构建 YAML,不访问 API Server;
  2. kubectl diff -k:使用构建结果与集群对象比较;
  3. kubectl apply -k:把构建结果提交给 API Server。

如果 Deployment 已存在但镜像拉取失败,Kustomize 构建仍可能成功;失败发生在 Kubernetes 调度、拉取镜像或容器启动阶段。因此“构建成功”不等于“部署成功”。

删除时:

kubectl delete -k demo/overlays/production

它会根据当前构建结果删除当前清单中的资源。配置内容变化导致生成 ConfigMap 名称变化后,旧 ConfigMap 可能不再出现在新清单中,普通 apply 不一定自动删除它。长期运行的环境需要单独设计旧生成资源的清理策略,并避免未经限定的 prune 删除其他系统或团队的资源。


七、常见变换:镜像、标签和副本数

镜像替换可以写成:

images:
  - name: nginx
    newName: registry.example.com/platform/nginx
    newTag: "1.27.3"

它不是全局字符串替换,而是针对 Kubernetes 已知的镜像字段进行处理。镜像名称、仓库路径和标签的匹配应与资源中实际使用的镜像引用一致。

副本数也可以使用专门字段:

replicas:
  - name: web
    count: 3

但当修改同时涉及容器、探针或资源限制时,patches 通常更清晰,因为所有变更可以在一个目标明确的补丁中表达。

标签变更尤其需要谨慎。Deployment 的:

spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: web

一旦创建,通常不能随意修改。若给 Pod Template 添加标签却没有同步 Service selector,Service 可能找不到 Endpoint;若修改 Deployment selector,API Server 可能拒绝更新。Kustomize 能生成语法正确的 YAML,但不能保证标签语义和控制器关系正确。


八、Kustomize 的执行状态与并发边界

Kustomize build 本质上是一个本地构建过程:

文件与目录
   │
   ├── 读取 Base
   ├── 累加资源
   ├── 执行 Generator
   ├── 执行 Patch 和字段变换
   └── 输出 YAML

它通常不维护类似 Helm Release 的发布历史,也不负责持续调谐。多个构建进程可以同时读取同一目录;真正的并发控制发生在应用阶段,由 API Server 处理资源更新、冲突和字段所有权。

应用到 Kubernetes 后,状态路径是:

本地 Git 清单
    │ kubectl apply -k
    ▼
API Server 接收对象
    ▼
控制器创建或更新实际资源
    ▼
Scheduler、Kubelet、Ingress Controller 等继续处理
    ▼
集群实际状态

因此:

  • Kustomize 生成的是期望配置;
  • API Server 负责校验和持久化;
  • 控制器负责把对象推进到运行状态;
  • Kustomize 本身不会检测配置漂移;
  • Kustomize 本身不会在一段时间后自动恢复被手工修改的对象。

如果另一个管理员直接修改了线上 Deployment,只有再次执行 apply,或者交给 GitOps 控制器持续调谐,期望配置才可能重新覆盖该修改。若多人或多个控制器同时管理同一字段,还会出现字段所有权冲突或反复覆盖。

使用 Server-Side Apply 时可以显式指定字段管理者,例如:

kubectl apply \
  --server-side \
  --field-manager=platform-kustomize \
  -k demo/overlays/production

这不会改变 Kustomize 的构建语义,只改变 API Server 处理字段所有权和冲突的方式。生产环境必须明确哪些字段由 Kustomize、Helm、Operator 或人工管理,不能让多个系统无约定地写同一对象。


九、失败表现和诊断路径

1. 资源重复

错误通常类似“已存在相同资源身份”。常见原因是两个 Base 都定义了相同的:

group + version + kind + namespace + name

诊断方法:

kubectl kustomize overlays/production > rendered.yaml
kubectl apply --dry-run=client -f rendered.yaml

然后搜索重复的 kindmetadata.name。修复方式通常是删除重复引用,而不是盲目增加前缀。

2. 补丁找不到目标

表现为构建阶段报找不到匹配资源。检查:

  • group 是否正确;
  • version 是否写成 v1v1beta1
  • kind 大小写是否正确;
  • name 是否是 Base 中的原始名称;
  • 目标资源是否被另一个条件分支排除。

可以先只构建 Base,再构建 Overlay,定位目标在哪一层消失或被重命名。

3. JSON Patch 路径错误

表现为 /spec/... 路径不存在。不要凭印象填写路径,应先查看实际输出:

kubectl kustomize demo/overlays/production

然后确认字段层级、数组索引和父对象是否存在。对于结构变化频繁的资源,战略合并补丁通常比数组索引 JSON Patch 更耐维护,但 CRD 场景又可能需要 JSON Patch,这取决于对象的 schema 和变更目标。

4. Service 没有流量

构建成功、Deployment 也正常,但 Service 没有 Endpoint,常见原因是:

Service.spec.selector

与:

Pod.metadata.labels

不一致。

名称前缀不会自动修复业务标签选择器错误。验证:

kubectl -n production get pods --show-labels
kubectl -n production get endpointslice
kubectl -n production describe service prod-web

5. 配置更新但 Pod 没有重启

如果使用了生成器默认哈希,检查 Deployment 的 Pod Template 是否引用了新名称:

kubectl -n production get deployment prod-web -o yaml
kubectl -n production get configmap

如果关闭了哈希后缀,则配置更新本身通常不会改变 Pod Template。此时需要应用主动热加载,或通过显式的 Pod Template 变更触发滚动更新。


十、Kustomize 与 Helm、GitOps 的边界

Kustomize 和 Helm 都可以产生 Kubernetes YAML,但抽象层不同。

Helm 的核心流程是:

Chart + Values + Template
        │
        ▼
渲染 YAML + Release 管理

Kustomize 的核心流程更接近:

已有 YAML + Patch + Generator + Transformer
        │
        ▼
变换后的 YAML

因此:

  • 需要循环、条件、模板函数、Chart 分发和参数化安装时,Helm 更自然;
  • 已有一套 Kubernetes YAML,只需按环境修改少量字段时,Kustomize 更直接;
  • Helm 模板过于复杂时,Kustomize 可以作为渲染后的二次定制层,但这样会增加调试链路;
  • Kustomize 不提供 Helm Release 的原生历史、Hook 和回滚模型。

与 GitOps 的关系也需要区分。GitOps 控制器可以执行 Kustomize 构建,并持续将 Git 中的期望状态调谐到集群。此时:

  • Kustomize 负责生成清单;
  • Git 仓库负责期望状态来源;
  • 控制器负责持续调谐;
  • API Server 负责对象校验和持久化;
  • Kubernetes 控制器负责实际运行状态。

没有 GitOps 控制器时,kubectl apply -k 只是一次性操作;它不会自行监控漂移,也不会自动晋级或回滚。


十一、生产使用时必须明确的边界

Kustomize 能保证的是构建规则和输出结构,不保证:

  • 镜像一定存在;
  • Pod 一定能调度;
  • PVC 一定绑定成功;
  • Ingress Controller 一定支持所写注解;
  • 云厂商 LoadBalancer 一定按预期分配;
  • CRD 一定已经安装;
  • 应用一定能理解生成的配置;
  • Secret 一定安全;
  • 变更一定可回滚。

在不同 Kubernetes 发行版、不同 kubectl 内置版本和不同独立 Kustomize 版本之间,字段支持、弃用行为和变换细节可能存在差异。应在 CI 中固定构建工具,执行:

kubectl kustomize path/to/overlay > rendered.yaml
kubectl apply --dry-run=server -f rendered.yaml
kubectl diff -f rendered.yaml

其中 --dry-run=server 需要访问 API Server,并会使用目标集群的 schema、准入控制和 API 能力进行校验,比纯本地构建更接近真实应用条件。

真正适合 Kustomize 的配置管理边界可以概括为:

Kustomize=资源组合+结构化变换+构建期生成\text{Kustomize} = \text{资源组合} + \text{结构化变换} + \text{构建期生成}

它不是:

模板语言+密钥保险库+发布控制器+运行时调谐器\text{模板语言} + \text{密钥保险库} + \text{发布控制器} + \text{运行时调谐器}

理解这个边界后,Base 负责稳定的共同结构,Overlay 负责环境差异,Patch 负责精确修改,Generator 负责构建期资源生成,而 Kubernetes API Server 和 GitOps 控制器分别承担校验、持久化与持续交付职责。


系列导航与关联阅读

官方资料

本文依据 Kubernetes、CNCF 与相关项目官方文档重新梳理;正文和生产清单由 WR BLOG 编写。