2. Kustomize 基础回顾:kustomization.yaml 结构、资源叠加与补丁机制

在进入蓝绿部署与事件流追踪之前,必须牢固掌握 Kustomize 的核心概念。Kustomize 并非模板引擎,而是一种 声明式资源叠加 工具。它通过 kustomization.yaml 文件描述“如何从基础资源生成最终资源”,整个过程遵循 base → overlay → patch 的三层模型。

2.1 kustomization.yaml 核心结构

每个 Kustomize 目录必须包含一个 kustomization.yaml,它是整个配置的入口。以下是最常用的字段及其作用:

字段 作用 示例值
apiVersion Kustomize 配置版本 kustomize.config.k8s.io/v1beta1
kind 固定为 Kustomization Kustomization
resources 声明要包含的原始 YAML 文件或目录 ["deployment.yaml", "service.yaml"]
bases (旧版)引用另一个 kustomization 目录作为基础 ["../base"]
patchesStrategicMerge 使用战略合并补丁覆盖资源字段 ["patch_replicas.yaml"]
patchesJson6902 使用 JSON Patch 操作精确修改资源 [{"target":{"kind":"Deployment","name":"my-app"},"patch":...}]
namespace 为所有资源设置目标命名空间 production
namePrefix / nameSuffix 为所有资源名称添加前缀或后缀 prod-
commonLabels 为所有资源添加公共标签 {app.kubernetes.io/env: production}
images 修改镜像名称、标签或摘要 [{"name":"nginx","newTag":"1.25.0"}]
configMapGenerator 从文件或字面值生成 ConfigMap [{"name":"app-config","literals":["key=value"]}]
关键理解: Kustomize 不修改原始 YAML 文件,而是通过 kustomization.yaml 描述“如何叠加”,最终输出一份完整的、合并后的 YAML。这种设计使得基础配置可以复用,环境差异通过 overlay 隔离。

2.2 资源叠加:Base → Overlay 模型

Kustomize 的目录结构通常分为 base 和 overlays 两层:

project/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── production/
    │   ├── kustomization.yaml
    │   └── patch_replicas.yaml
    └── staging/
        ├── kustomization.yaml
        └── patch_env.yaml
  • base:存放所有环境通用的资源定义,如 Deployment、Service、ConfigMap 的原始形态。
  • overlays:每个子目录代表一个环境(如 production、staging),通过 resources 或 bases 引用 base,再叠加补丁。

叠加过程是 幂等 的:多次执行 kustomize build overlays/production 得到完全相同的输出。这种模型天然适合 GitOps 工作流。

实践建议: 在蓝绿部署场景中,base 层定义应用的通用 Deployment 模板(如容器端口、健康检查),overlays 层则通过补丁修改 spec.replicas、spec.selector.matchLabels 以及 spec.template.metadata.labels 来区分蓝绿版本。

2.3 补丁机制:Strategic Merge Patch 与 JSON Patch

Kustomize 提供两种补丁方式,理解它们的差异是故障排查的关键:

特性 Strategic Merge Patch JSON Patch (RFC 6902)
语法 部分 YAML,只写要覆盖的字段 操作数组:op、path、value
适用场景 覆盖或添加字段,合并列表 精确删除、替换、测试字段值
列表合并策略 按 patchStrategicMerge 策略合并(如 replace、merge) 完全替换整个列表
示例 patchesStrategicMerge: [{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"my-app"},"spec":{"replicas":5}}] patchesJson6902: [{"target":{"kind":"Deployment","name":"my-app"},"patch":[{"op":"replace","path":"/spec/replicas","value":5}]}]
故障排查难度 中等(需理解合并策略) 较低(操作路径明确)
常见陷阱: 当使用 Strategic Merge Patch 修改 spec.selector.matchLabels 时,如果 base 中已经定义了 labels,补丁中的 labels 会与 base 中的 labels 合并,而不是替换。这可能导致 Deployment 的 selector 与 Pod template 的 labels 不匹配,引发蓝绿切换时的流量中断。建议在补丁中显式写出完整的 matchLabels 和 template.metadata.labels。

2.4 补丁执行流程与资源叠加顺序

Kustomize 在构建最终资源时,遵循严格的执行顺序。理解这个顺序对于追踪配置变更至关重要:

  1. 加载基础资源:读取 resources 字段中列出的所有 YAML 文件,以及通过 bases 引用的其他 kustomization 目录的输出。
  2. 应用命名空间:如果 namespace 字段有值,为所有资源设置 metadata.namespace。
  3. 应用名称前缀/后缀:修改所有资源的 metadata.name。
  4. 应用公共标签/注解:将 commonLabels 和 commonAnnotations 注入到所有资源。
  5. 执行补丁:按 patchesStrategicMerge 和 patchesJson6902 的顺序依次应用补丁。
  6. 执行镜像替换:根据 images 字段修改容器镜像。
  7. 生成 ConfigMap/Secret:执行 configMapGenerator 和 secretGenerator,并注入到引用它们的资源中。
  8. 输出最终 YAML:将所有处理后的资源合并为一个多文档 YAML 输出。

下面这张 SVG 图展示了从 base 到 overlay 再到最终输出的完整叠加流程:

Kustomize 资源叠加与补丁执行流程 Kustomize 资源叠加与补丁执行流程 Base 资源 deployment.yaml, service.yaml Overlay 层 kustomization.yaml 补丁应用 Strategic / JSON Patch 最终输出 YAML kustomize build 结果 叠加执行顺序(自上而下) 1. 加载 Base 资源 2. 设置 Namespace / NamePrefix / CommonLabels 3. 应用补丁(Strategic Merge / JSON Patch) 4. 镜像替换 → ConfigMap/Secret 生成 → 输出 🔍 故障排查线索 • 补丁顺序影响最终结果:后应用的补丁会覆盖先应用的补丁。 • 使用 kustomize build --reorder none 可查看原始叠加顺序。

2.5 实战示例:通过补丁修改蓝绿版本标签

在蓝绿部署中,最关键的补丁操作是修改 spec.selector.matchLabels 和 spec.template.metadata.labels。以下是一个典型的 Strategic Merge Patch 示例:

# overlays/blue/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patchesStrategicMerge:
  - patch_blue_version.yaml
images:
  - name: my-app
    newTag: v2.0.0-blue
# overlays/blue/patch_blue_version.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: blue   # 显式覆盖为 blue
  template:
    metadata:
      labels:
        app: my-app
        version: blue   # 必须与 selector 一致
    spec:
      containers:
        - name: my-app
          env:
            - name: DEPLOY_VERSION
              value: "blue"
关键检查点: 在蓝绿切换时,如果补丁只修改了 template.metadata.labels 而忘记同步修改 selector.matchLabels,Service 的流量将无法路由到新版本的 Pod。这是最常见的故障原因之一。建议在补丁中始终同时显式设置这两个字段。

2.6 使用 kustomize build 验证叠加结果

在应用配置到集群之前,务必使用 kustomize build 命令验证最终输出:

# 构建 blue 环境的最终配置
kustomize build overlays/blue

# 将输出重定向到文件,便于 diff 对比
kustomize build overlays/blue > blue-final.yaml
kustomize build overlays/green > green-final.yaml

# 对比两个版本的差异
diff blue-final.yaml green-final.yaml

通过 diff 可以快速发现 selector、labels、镜像版本等关键字段的差异,这是故障排查的第一步。

可观测性集成: 在 CI/CD 流水线中,将 kustomize build 的输出与预期基线进行对比,可以自动检测配置漂移。结合事件流追踪,可以精确定位是哪个 overlay 或补丁引入了错误配置。