如何在Kustomize覆盖层修补Base资源并让Base替换规则生效?
你遇到的核心问题是Kustomize的执行顺序导致的:base层的replacements会在overlay层的patches之前执行,所以base里的替换规则读取的是补丁前的Ingress主机名,无法同步overlay补丁修改后的值。
以下两种方式可以实现「一处设置主机名,同步到Ingress和Deployment」的需求:
方案一:将replacements移至Overlay层
把base里的替换规则移到staging overlay中,这样它会在overlay的补丁执行后运行,读取修改后的Ingress主机名同步到Deployment:
修改staging/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../base patches: - target: kind: Ingress name: myingress2 path: ingress.json # 添加替换规则到overlay,在补丁后执行 replacements: - source: kind: Ingress name: myingress2 fieldPath: spec.rules.0.host targets: - select: kind: Deployment name: mydeployment fieldPaths: - spec.template.spec.containers.[name=flask].env.[name=MYVAR].value
执行kustomize build staging后,补丁先修改Ingress主机名,再通过replacements同步到Deployment的环境变量。
方案二:用ConfigMap作为单一数据源(推荐)
定义一个存储主机名的ConfigMap作为唯一数据源,所有需要主机名的地方都通过replacements从这个ConfigMap同步,只需修改ConfigMap的值就能实现全量同步:
1. 在base层添加ConfigMap
创建base/hostname-config.yaml:
apiVersion: v1 kind: ConfigMap metadata: name: app-host-config data: APP_HOST: default.example.com
2. 修改base层的kustomization.yaml
添加ConfigMap到资源列表,并更新replacements规则,从ConfigMap同步到Ingress和Deployment:
resources: - ... - hostname-config.yaml replacements: - source: kind: ConfigMap name: app-host-config fieldPath: data.APP_HOST targets: # 同步到Ingress的规则主机名 - select: kind: Ingress name: myingress2 fieldPaths: - spec.rules.0.host # 同步到Ingress的TLS主机名 - select: kind: Ingress name: myingress2 fieldPaths: - spec.tls.0.hosts.0 # 同步到Deployment的环境变量 - select: kind: Deployment name: mydeployment fieldPaths: - spec.template.spec.containers.[name=flask].env.[name=MYVAR].value
3. 修改staging层的补丁
不再直接修改Ingress,而是修改ConfigMap的值:
staging/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../base patches: - target: kind: ConfigMap name: app-host-config path: host-config-patch.json
创建staging/host-config-patch.json:
[ { "op": "replace", "path": "/data/APP_HOST", "value": "myhostname.example.com" } ]
这样执行kustomize build staging时,会先加载base的ConfigMap,应用补丁修改主机名,最后通过replacements同步到Ingress的两个字段和Deployment的环境变量,完全实现一处修改、多处同步。
内容的提问来源于stack exchange,提问作者RubenLaguna

