使用 Kustomize Replacements 将一个基数中的值替换为另一个基数中的值?

问题描述 投票:0回答:2

我正在更新一些 Kubernetes 配置,以在 kustomize 中使用

'replacements'
'resources'
,因为
'vars'
'bases'
已被弃用。

之前,我在底座 (

'vars'
) 中使用了
/base/secrets/
,如下所示:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

secretGenerator:
- name: test_secret
  env: secret.env

vars:
- name : SECRET_VALUE
  objref:
    kind: Secret
    name: test_secret
    apiVersion: v1
  fieldref:
    fieldpath: metadata.name

该基础用于不同服务的各种覆盖:

namespace: test-overlay

bases:
- ../../base/secrets/
- ../../base/service/

现在,对于

'resources'
'replacements'
,我的理解是不可能像以前一样从
/base/service/
替换
/base/secrets/
中的值。我可以在叠加层本身中应用
'replacement'
并定位我想要修改的基础,但我更愿意从基础执行操作,以实现可重用性和易用性。

这就是我正在尝试做的事情:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

secretGenerator:
- name: test_secret
  env: secret.env

replacements:
- source:
    name: test_secret
    kind: Secret
  targets:
  - select:
      kind: Deployment
      name: service
    fieldPaths:
    - spec.template.spec.<field>

'replacements'
指令中,
 spec.template.spec.<field>
是我尝试替换的部署资源中的字段。

我正在使用 kustomize 版本

v5.1.0

我怎样才能让

'replacements'
瞄准其他基地,以便可以从任何覆盖层使用它们?这种情况的最佳实践是什么?

我尝试在叠加层本身中应用“替换”,并定位我想要修改的基础,如下所示:

namespace: test-overlay

resources:
- ../../base/secrets/
- ../../base/service/

replacements:
- source:
    kind: Secret
    name: test_secret
  targets:
  - select:
      kind: Deployment
      name: service
    fieldPaths:
    - spec.template.spec.<field>

虽然这确实将替换应用于服务,但对我来说这不是一个令人满意的解决方案,因为我有多个覆盖,所有覆盖都需要对各种部署使用相同的替换。我更愿意在基础中定义一次替换,而不是在每个覆盖中定义它。

编辑:更清晰的最小可重现示例

/base
  /secrets
    kustomization.yaml
  /service
    deployment.yaml
    kustomization.yaml
/overlays
  /test-overlay
    kustomization.yaml

/secrets/
实现为:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

secretGenerator:
- name: test_secret
  env: secret.env

replacements:
- source:
    name: test_secret
    kind: Secret
  targets:
  - select:
      kind: Deployment
      name: service
    fieldPaths:
    - spec.template.spec.volumes.name

这将是

/service/

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
    
resources:
- deployment.yaml

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: service
spec:
  template:
    spec:
      volumes:
      - name: placeholder_value
        emptyDir: {}

/test-overlay/

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: test-overlay

resources:
- ../../base/secrets/
- ../../base/service/

我尝试将

'replacements'
包含在测试覆盖
kustomization
文件中,该文件确实有效,但不太理想,然后让替换在基础中定义

kubernetes kubernetes-secrets configuration-management kustomize
2个回答
3
投票

感谢您通过示例更新您的问题。

我在这里发布的答案仍然是在多个覆盖之间共享替换配置方面的正确解决方案,但是您的

replacement
语法中存在一些错误:您无法定位
spec.template.spec.volumes.name
,因为
volumes
是一个列表并且没有
name
属性。

您只能使用

[name=value]
样式选择器定位列表元素,因此:

replacements:
  - source:
      name: test_secret
      kind: Secret
    targets:
      - select:
          kind: Deployment
          name: service
        fieldPaths:
          - spec.template.spec.volumes.[name=placeholder_value].name

A

kustomization.yaml
只能将转换(标签、补丁、替换等)应用于该
kustomization.yaml
发出的资源——这意味着如果您希望转换影响所有资源,则需要将其应用于“最外层”定制。

这意味着您无法将某些内容放置在“基础”中来修改叠加层中生成的资源。

不过不用担心,有解决办法! 组件允许您重用自定义片段。如果我们将您的替换配置移至组件中,我们可以获得您想要的行为。

例如,这是一个具有基础和两个覆盖层的项目:

.
├── base
│   ├── deployment.yaml
│   └── kustomization.yaml
├── components
│   └── replace-username-password
│       └── kustomization.yaml
└── overlay
    ├── env1
    │   └── kustomization.yaml
    └── env2
        └── kustomization.yaml

base/deployment.yaml
看起来像这样:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: example
          image: docker.io/alpine:latest
          command:
            - sleep
            - inf
          env:
            - name: USER_NAME
              value: update-via-replacement
            - name: USER_PASSWORD
              value: update-via-replacement

并且

base/kustomization.yaml
看起来像:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  app: replacement-example

resources:
  - deployment.yaml

secretGenerator:
  - name: example
    literals:
      - password=secret

configMapGenerator:
  - name: example
    literals:
      - username=alice

因此

base
目录会生成一个 Deployment、一个 Secret 和一个 ConfigMap。有两个叠加层:
env1
env2
。在这两个覆盖层中,我想应用相同的替换配置,因此我将其放入
components/replace-username-password/kustomization.yaml
:

apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component

replacements:
  - source:
      kind: ConfigMap
      name: example
      fieldPath: data.username
    targets:
      - select:
          kind: Deployment
          name: example
        fieldPaths:
          - spec.template.spec.containers.[name=example].env.[name=USER_NAME].value
  - source:
      kind: Secret
      name: example
      fieldPath: data.password
    targets:
      - select:
          kind: Deployment
          name: example
        fieldPaths:
          - spec.template.spec.containers.[name=example].env.[name=USER_PASSWORD].value

现在在

overlays/env1/kustomization.yaml
我可以使用这个组件:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  envName: env1

resources:
  - ../../base

components:
  - ../../components/replace-username-password

overlays/env2
一样:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  envName: env2

resources:
  - ../../base

components:
  - ../../components/replace-username-password

0
投票

语法很容易出错。如果

source
有问题,它会告诉您问题是什么。但是,如果问题出在
targets.select
上,它不会告诉您任何信息。因此,如果您的更新目标没有被修改,请确保
select.kind
select.name
和所有
fieldPaths
实际上与您要定位的对象和字段匹配。

© www.soinside.com 2019 - 2024. All rights reserved.