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 在构建最终资源时,遵循严格的执行顺序。理解这个顺序对于追踪配置变更至关重要:
- 加载基础资源:读取
resources字段中列出的所有 YAML 文件,以及通过bases引用的其他 kustomization 目录的输出。 - 应用命名空间:如果
namespace字段有值,为所有资源设置metadata.namespace。 - 应用名称前缀/后缀:修改所有资源的
metadata.name。 - 应用公共标签/注解:将
commonLabels和commonAnnotations注入到所有资源。 - 执行补丁:按
patchesStrategicMerge和patchesJson6902的顺序依次应用补丁。 - 执行镜像替换:根据
images字段修改容器镜像。 - 生成 ConfigMap/Secret:执行
configMapGenerator和secretGenerator,并注入到引用它们的资源中。 - 输出最终 YAML:将所有处理后的资源合并为一个多文档 YAML 输出。
下面这张 SVG 图展示了从 base 到 overlay 再到最终输出的完整叠加流程:
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 或补丁引入了错误配置。