如何用Kustomize从Base层在指定Overlay中复制特定对象?
我有一个base层以及dev、prod两个overlay,base层中定义的所有对象(Deployment、StatefulSet、Service等)均被两个overlay继承。现在需要在prod overlay中将特定Service "foo"复制为"foo-a"、"foo-b"、"foo-c",而dev overlay中的该Service保持不变,目录结构如下:
. ├── base │ ├── Service:foo │ ├── Deployment:bar │ ├── StatefulSet:baz │ └── ... └── overlays ├── dev │ ├── Service:foo <-- base/Service:foo kept unchanged │ ├── Deployment:bar │ ├── StatefulSet:baz │ └── ... └── prod ├── Service:foo-a <-- duplicated from base/Service:foo ├── Service:foo-b <-- duplicated from base/Service:foo ├── Service:foo-c <-- duplicated from base/Service:foo ├── Deployment:bar ├── StatefulSet:baz └── ...
试过multibases方案,但它会复制整个层的所有对象,而非特定对象。希望用Kustomize原生方式实现,求解决思路。
1. 拆分base层,抽离需复制的Service
将base中需要复制的Service:foo单独放到子目录base/foo-service,原base目录保留其他通用对象(Deployment、StatefulSet等),调整后目录结构:
. ├── base │ ├── common │ │ ├── Deployment:bar │ │ ├── StatefulSet:baz │ │ └── ... │ └── foo-service │ └── Service:foo └── overlays ├── dev └── prod
2. 配置dev overlay保留原Service
在dev/kustomization.yaml中同时引用base/common和base/foo-service,直接继承原Service:foo与其他通用对象:
# overlays/dev/kustomization.yaml resources: - ../../base/common - ../../base/foo-service
3. 配置prod overlay生成多实例Service
方式一:用Kustomize Components实现(推荐,便于后续维护)
创建组件目录components/foo-service-variant,用于生成带不同后缀的Service实例:
components/ └── foo-service-variant ├── kustomization.yaml └── rename-service.yaml
rename-service.yaml:通过变量替换Service名称
apiVersion: v1 kind: Service metadata: name: foo $patch: replace metadata: name: foo-$(SUFFIX)
foo-service-variant/kustomization.yaml:关联base的foo-service并定义变量来源
resources: - ../../base/foo-service patches: - path: rename-service.yaml vars: - name: SUFFIX objref: apiVersion: v1 kind: Service name: foo fieldref: fieldpath: metadata.labels.suffix
在prod/kustomization.yaml中引用通用对象,通过添加不同标签生成三个Service实例:
# overlays/prod/kustomization.yaml resources: - ../../base/common components: - ../../components/foo-service-variant patches: - target: kind: Service name: foo patch: |- - op: add path: /metadata/labels/suffix value: a - target: kind: Service name: foo patch: |- - op: add path: /metadata/labels/suffix value: b - target: kind: Service name: foo patch: |- - op: add path: /metadata/labels/suffix value: c
方式二:直接复制修改Service文件(简单场景适用)
在prod目录下创建三个Service文件,复制base/foo-service/Service:foo的内容,分别修改名称为foo-a、foo-b、foo-c,然后在prod/kustomization.yaml中引用:
# overlays/prod/kustomization.yaml resources: - ../../base/common - ./foo-a-service.yaml - ./foo-b-service.yaml - ./foo-c-service.yaml
注意:这种方式如果base中的foo Service有修改,需要手动同步三个文件。
4. 验证效果
执行kustomize build overlays/dev可看到原Service:foo与通用对象;执行kustomize build overlays/prod可看到Service:foo-a、foo-b、foo-c与通用对象,原Service:foo不会出现在prod输出中。
内容的提问来源于stack exchange,提问作者Kelvin Hu

