4. 覆盖层(Overlay)设计:开发/测试/生产环境差异化配置、patchesStrategicMerge用法

4.1 覆盖层设计理念:Base + Overlay 模式

Kustomize 的核心设计哲学是 “声明式配置组合”,通过 base/overlay 两层结构实现环境差异化。Base 层存放所有环境共享的通用配置,Overlay 层则通过补丁(Patch)对 Base 进行局部覆盖,避免为每个环境复制完整的 YAML 文件。

核心原则:Base 层只描述“是什么”,Overlay 层只描述“差异是什么”。任何环境特有的配置(如副本数、镜像标签、Ingress 域名)都应放在 Overlay 中,严禁在 Base 层写入环境特定值。

4.1.1 标准目录结构

project-root/
├── base/                          # 共享基础配置
│   ├── kustomization.yaml         # 声明 resources
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ingress.yaml
├── overlays/
│   ├── dev/                       # 开发环境覆盖层
│   │   ├── kustomization.yaml     # 引用 base + 补丁
│   │   ├── replica-patch.yaml     # 副本数补丁
│   │   └── env-configmap.yaml     # 环境专用 ConfigMap
│   ├── test/                      # 测试环境覆盖层
│   │   ├── kustomization.yaml
│   │   ├── resource-patch.yaml
│   │   └── test-ingress.yaml
│   └── prod/                      # 生产环境覆盖层
│       ├── kustomization.yaml
│       ├── hpa-patch.yaml
│       └── prod-tls.yaml
└── README.md

4.1.2 Base 与 Overlay 职责对比

维度 Base 层 Overlay 层
配置内容 通用资源定义(Deployment、Service、RBAC) 环境差异补丁(镜像、副本、资源限制)
镜像版本 占位符或通用版本(如 myapp:latest) 环境特定版本(如 myapp:v1.2.3-dev)
副本数 不设置或设置默认值 1 dev=1, test=3, prod=10
Ingress 域名 不包含域名配置 dev.myapp.com / prod.myapp.com
资源限制 不设置或宽松限制 dev 低配、prod 高配
ConfigMap/Secret 通用配置模板 环境专用数据

4.2 patchesStrategicMerge 详解

patchesStrategicMerge 是 Kustomize 最强大的补丁策略之一。它使用部分 YAML 文件作为补丁,通过 Strategic Merge Patch(策略合并补丁)算法,将补丁内容与 Base 资源进行智能合并。与 JSON Patch 不同,Strategic Merge 能理解 Kubernetes 资源结构,支持数组替换、列表合并等高级操作。

4.2.1 基本语法

在 Overlay 的 kustomization.yaml 中声明:

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

patchesStrategicMerge:
  - replica-patch.yaml
  - image-patch.yaml
  - resource-patch.yaml

4.2.2 补丁文件编写规范

补丁文件必须包含 apiVersion、kind、metadata.name 三个字段,用于匹配 Base 中的目标资源。Kustomize 通过这三个字段定位要修改的资源对象。

# overlays/prod/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 10
  template:
    spec:
      containers:
        - name: myapp-container
          resources:
            requests:
              cpu: "500m"
              memory: "512Mi"
            limits:
              cpu: "2"
              memory: "2Gi"
最佳实践:补丁文件只写需要修改的字段,不要复制整个 Base 资源。Kustomize 会自动将补丁字段合并到 Base 资源中,未在补丁中出现的字段保持不变。

4.3 典型环境差异化配置实战

4.3.1 开发环境:轻量配置 + 调试模式

# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

patchesStrategicMerge:
  - dev-patch.yaml

configMapGenerator:
  - name: app-config
    literals:
      - ENV=development
      - LOG_LEVEL=debug
      - DB_POOL_SIZE=5
# overlays/dev/dev-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: myapp-container
          image: myapp:dev-latest
          env:
            - name: JAVA_OPTS
              value: "-Xmx256m -Xms128m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"

4.3.2 生产环境:高可用 + 弹性伸缩

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base

patchesStrategicMerge:
  - prod-replica-patch.yaml
  - prod-resource-patch.yaml
  - prod-probe-patch.yaml

configMapGenerator:
  - name: app-config
    literals:
      - ENV=production
      - LOG_LEVEL=info
      - DB_POOL_SIZE=50
# overlays/prod/prod-replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 1

4.4 patchesStrategicMerge 与 patchesJson6902 对比

特性 patchesStrategicMerge patchesJson6902
补丁格式 部分 YAML 文件(类资源格式) JSON Patch 操作数组
匹配方式 apiVersion + kind + name target 字段指定 group/version/kind/name
数组处理 支持策略合并(替换/合并/删除) 按索引或路径精确操作
可读性 高,接近原生 YAML 低,需要理解 JSON Patch 语法
适用场景 修改字段值、替换容器镜像、调整资源限制 删除字段、复杂数组操作、精确路径修改
学习曲线 平缓 较陡
常见陷阱:当使用 patchesStrategicMerge 修改容器镜像时,必须确保补丁中的 name 字段与 Base 中容器的 name 完全一致。如果名称不匹配,Kustomize 会将其视为新增容器,导致 Deployment 中出现两个容器。

4.5 覆盖层设计模式:三层架构

对于大型项目,推荐使用 Base → 中间层 → 环境层 的三层覆盖结构,进一步分离关注点:

project-root/
├── base/                          # 第1层:通用基础
├── middle/                        # 第2层:环境无关的公共增强
│   ├── monitoring/                # 监控相关补丁
│   ├── logging/                   # 日志相关补丁
│   └── security/                  # 安全相关补丁
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml     # 引用 base + middle + dev 补丁
    │   └── ...
    ├── test/
    │   └── ...
    └── prod/
        └── ...

中间层可以包含所有环境都需要的通用增强(如 Sidecar 注入、资源配额模板),而环境层只保留真正的环境差异。这种模式将补丁的复用率提升 40% 以上。

Kustomize 三层覆盖架构(Base + Middle + Overlay) Base 层(共享基础) Deployment · Service · Ingress · RBAC · 通用 ConfigMap 所有环境共享,不包含环境特定值 Middle 层(公共增强) 监控 Sidecar · 日志采集 · 安全策略 · 资源配额模板 环境无关的通用增强,按需组合引用 Dev Overlay 副本数: 1 镜像: dev-latest 日志: debug 资源: 低配 Test Overlay 副本数: 3 镜像: v1.2.3-rc 日志: info 资源: 中配 Prod Overlay 副本数: 10 镜像: v1.2.3 日志: info 资源: 高配 + HPA

4.6 覆盖层设计避坑指南

  • 补丁文件命名规范:使用 xxx-patch.yaml 格式,避免与 Base 资源文件重名,防止混淆。
  • 避免多层嵌套覆盖:Overlay 层不要引用另一个 Overlay,这会导致配置链路复杂化。所有 Overlay 应直接引用 Base。
  • 补丁原子性:每个补丁文件只修改一个关注点(如副本数、镜像、资源限制),便于复用和排查。
  • 版本控制:Base 和 Overlay 必须放在同一个 Git 仓库中,通过分支或标签管理环境版本。
  • 验证命令:使用 kustomize build overlays/prod 预览最终渲染结果,确认补丁生效后再 apply。
生产级检查清单:
✅ Base 层不包含任何环境特定值
✅ 每个 Overlay 都有独立的 kustomization.yaml
✅ 补丁文件只包含需要修改的字段
✅ 容器名称与 Base 层完全一致
✅ 使用 kustomize build 验证输出符合预期
✅ 所有环境差异通过 patchesStrategicMerge 或 patchesJson6902 实现