有没有办法让 kustomize 将文件的内容合并到 yaml 文件中?

Is there a way to have kustomize merge the content of a file into a yaml file?

我很想知道是否有办法进行 Kustomize 替换或其他操作以使用 Kustomize 将非 yaml 文件的内容注入到 yaml 文件中。我知道 Kustomize 不是模板引擎,这可以通过 Helm 完成,但是使用我已经在使用的工具,这可能吗?

我的用例是将 OPA 策略存储为本机 rego,这允许使用 OPA 单元测试,并在 Kustomize 部署期间将这些 rego 文件的内容注入到 Gatekeeper 约束中。这将消除自定义管道处理或手动 copy/paste 来完成此操作的要求。

示例opaRule.rego 文件

package k8sdisallowedtags

violation[{"msg": msg}] {
    container := input_containers[_]
    tags := [forbid | tag = input.parameters.tags[_] ; forbid = endswith(container.image, concat(":", ["", tag]))]
    any(tags)
    msg := sprintf("container <%v> uses a disallowed tag <%v>; disallowed tags are %v", [container.name, container.image, input.parameters.tags])
}
...

示例constraintTemplate.yaml 文件

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdisallowedtags
  namespace: kube-system
  annotations:
    description: Requires container images to have an image tag different
      from the ones in a specified list.
spec:
  crd:
    spec:
      names:
        kind: K8sDisallowedTags
      validation:
        openAPIV3Schema:
          properties:
            tags:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |-
        {CONTENT OF OPA RULE POLICY HERE}

答案将包含两部分:

  • 关于如何解决所问问题的想法(因为没有内置功能可用 + 与第二部分集成)
  • 使用补丁(对社区中的其他人有用)

创建自己的插件

Kustomize 允许创建插件来扩展其功能。并且几乎有零限制,包括 security - 这应该由插件的作者处理。

有两种插件:

所有可用信息都可以在 Extending Kustomize - documentation 中找到。

Example of exec plugin注意! 正确的标志是 --enable-alpha-plugins-,而不是示例中的 _)。

使用补丁

Patches (also call overlays) add or override fields on resources. They are provided using the patches Kustomization field.

The patches field contains a list of patches to be applied in the order they are specified.

Each patch may:

  • be either a strategic merge patch, or a JSON6902 patch
  • be either a file, or an inline string target
  • a single resource or multiple resources

Reference to kustomize - patches

下面是如何修补 gatekeeper.yaml 对象的示例。

结构:

$ 树

.
├── gatekeeper.yaml
├── kustomization.yaml
└── opa-gk.yaml

$猫gatekeeper.yaml

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8sdisallowedtags
  namespace: kube-system
  annotations:
    description: Requires container images to have an image tag different
      from the ones in a specified list.
spec:
  crd:
    spec:
      names:
        kind: K8sDisallowedTags
      validation:
        openAPIV3Schema:
          properties:
            tags:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |-
        {CONTENT OF OPA RULE POLICY HERE}

$猫kustomization.yaml

resources:
- gatekeeper.yaml

patches:
- path: opa-gk.yaml
  target:
    group: templates.gatekeeper.sh
    version: v1beta1
    kind: ConstraintTemplate
    name: k8sdisallowedtags

$猫opa-gk.yaml

- op: add
  path: /spec/targets/0/rego
  value: |
    package k8sdisallowedtags
    
    violation[{"msg": msg}] {
        container := input_containers[_]
        tags := [forbid | tag = input.parameters.tags[_] ; forbid = endswith(container.image, concat(":", ["", tag]))]
        any(tags)
        msg := sprintf("container <%v> uses a disallowed tag <%v>; disallowed tags are %v", [container.name, container.image, input.parameters.tags])
    }
    ...

最终结果:

$ kubectl kustomize .

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  annotations:
    description: Requires container images to have an image tag different from the
      ones in a specified list.
  name: k8sdisallowedtags
  namespace: kube-system
spec:
  crd:
    spec:
      names:
        kind: K8sDisallowedTags
      validation:
        openAPIV3Schema:
          properties:
            tags:
              items:
                type: string
              type: array
  targets:
  - rego: |
      package k8sdisallowedtags

      violation[{"msg": msg}] {
          container := input_containers[_]
          tags := [forbid | tag = input.parameters.tags[_] ; forbid = endswith(container.image, concat(":", ["", tag]))]
          any(tags)
          msg := sprintf("container <%v> uses a disallowed tag <%v>; disallowed tags are %v", [container.name, container.image, input.parameters.tags])
      }
      ...
    target: admission.k8s.gatekeeper.sh