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