Kustomize 插件

Kustomize 插件指南

Kustomize 提供一个插件框架,允许用户开发自己的 生成器转化器

通过插件,实现 [generatorOptions] 和 [transformerconfigs] 无法满足的需求。

  • generator 插件生成 k8s 资源,比如 helm chart inflator 是一个 generator 插件,基于少量自由变量生成一个 12-factor 应用所包含的全部组件 deployment,service,scaler,ingress 等)也是一个 generator 插件。
  • transformer 插件转化(修改)k8s 资源,比如可能会执行对特殊容器命令行的编辑,或为其他内置转换器(namePrefixcommonLabels 等)无法转换的内容提供转换。

kustomization.yaml 的格式

从为添加 generatorstransformers 字段开始。

字段内容为一个 string list:

  1. generators:
  2. - relative/path/to/some/file.yaml
  3. - relative/path/to/some/kustomization
  4. - /absolute/path/to/some/kustomization
  5. - https://github.com/org/repo/some/kustomization
  6. transformers:
  7. - {as above}

格式要求与 resources 字段相同,generatorstransformers 列表的每一列内容都必须是一个 YAML 文件的相对路径或者指向 kustomization 的 URL。

从磁盘上读取 YAML 文件,kustomization 的路径或 URL 会触发 kustomization 的运行。由此产生的每个的对象都会被 kustomize 进一步解析为 plugin configuration 对象。

配置

kustomization 文件可以包含如下内容:

  1. generators:
  2. - chartInflator.yaml

像这样,kustomization 进程将在 kustomization root 下寻找到一个名为 chartInflator.yaml 的文件。

chartInflator.yaml 为插件配置文件,该文件包含 YAML 配置对象,内容如下:

  1. apiVersion: someteam.example.com/v1
  2. kind: ChartInflator
  3. metadata:
  4. name: notImportantHere
  5. chartName: minecraft

apiVersionkind 字段用于定位插件。

同时由于 kustomize 插件配置对象也是一个 k8s 对象,因此这些字段是必要的。

为了让插件准备好生成或转换,它包含了配置文件的全部内容。

更多关于插件配置 YAML 的例子,请浏览根目录下 plugins 中的单元测试,例如 ChartInflatorNameTransformer

植入

每个插件都有自己的专用目录,名为:

  1. $XDG_CONFIG_HOME/kustomize/plugin
  2. /${apiVersion}/LOWERCASE(${kind})

The default value of XDG_CONFIG_HOME is $HOME/.config.

XDG_CONFIG_HOME 的默认值为 $HOME/.config

为了便于插件包(源码、测试、插件数据文件等)的共享,要求每个目录存放一个插件。

Go 插件中,还可以为单个插件提供一个 go.mod 文件,可以缓解包版本依赖性偏移的问题。

加载时,kustomize 首先会寻找一个 可执行 文件,名为:

  1. $XDG_CONFIG_HOME/kustomize/plugin
  2. /${apiVersion}/LOWERCASE(${kind})/${kind}

如果没有找到这个文件,或者这个文件不是可执行的,kustomize 会在同一目录下寻找一个名为 ${kind}.so 的文件,并尝试将其作为 Go插件 加载。

如果这两项检查都失败,则插件加载失败,kustomize build 失败。

执行情况

插件只有在运行 kustomize build 命令时使用。

生成器插件是在处理完 resources 字段后运行的(resources 字段本身也可以看成是一个简单地从磁盘上读取对象的生成器)。

之后所有资源将被传递到转换管道中,由其中内置的转换器,如 namePrefixcommonLabel 等先转换应用(如果 kustomization 文件中指定了他们),然后再转换用户指定的 transformers 字段。

由于无法指定转化的顺序,所以需要遵守 transformers 字段中指定的顺序。

No Security

Kustomize 插件不会在任何形式的 kustomize 提供的沙盒中运行。不存在 “plugin security” 的概念。

kustomize build 会尝试使用插件,但如果省略了 --enable_alpha_plugins,将导致插件无法加载,并且会有一个关于插件使用的警告。

使用这个 flag 就是承认使用不稳定的插件 API(alpha)、承认使用缺少出处插件,以及插件不属于 kustomize 的事实。

简单的说,一些从网上下载的 kustomize 插件可能会奇妙地将 k8s 的配置以理想的方式进行改造,同时也会悄悄地对运行 kustomize build 的系统做任何用户可以做的事情。

编写插件

插件有 execGo 两种.

Exec 插件

exec 插件 是一个可以在命令行中接收参数可执行文件,该参数指向包含 kustomization 配置的 YAML 文件。

TODO: 对插件的限制,允许同一个 exec 插件 同时被 generatorstransformers 字段所触发。

  • 第一个参数可以是固定的字符串 generatetransform,(配置文件的名称移动到第2个参数)
  • 默认情况下,exec plugin 会作为一个转化器,除非提供了标志 -g,将 exec 插件切换为生成器。

示例

生成器插件无需在 stdin 上输入任何东西,就会将生成的资源输出到 stdout

转化器插件需要在 stdin 上输入资源的 YAML,并转化后的资源输出到 stdout

kustomize 会使用 exec 插件适配器,为 stdin 提供的资源,并获取 stdout 以进行下一步的处理。

Generator 选项

生成器 exec 插件可以通过设置以下内部注释中的一个来调整生成器选项。

注意:这些注释只会在本地的 kustomize 中,不会出现在最终输出中。

kustomize.config.k8s.io/needs-hash

通过包含 needs-hash 注释,可以将资源标记为需要由内部哈希转换器处理的资源。当设置注释的有效值为 "true""false" 时,分别启用或禁用资源的哈希后缀。忽略该注解相当于将值设置为 "false"

如果此注释被设置在不受哈希转换器支持的资源上,将导致构建将失败。

示例:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: cm-test
  5. annotations:
  6. kustomize.config.k8s.io/needs-hash: "true"
  7. data:
  8. foo: bar

kustomize.config.k8s.io/behavior

behavior 注释为当资源发生冲突时插件的处理方式,有效值包括:“create”、“merge “和 “replace”,默认为 “create”。

示例:

  1. apiVersion: v1
  2. kind: ConfigMap
  3. metadata:
  4. name: cm-test
  5. annotations:
  6. kustomize.config.k8s.io/behavior: "merge"
  7. data:
  8. foo: bar

Go 插件

请务必阅读 Go 插件注意事项

如果一个 .go 文件声明 package main,并附加了有用的功能标志,那么它就可以成为一个 Go 插件

如果标志被命名为 “KustomizePlugin”,并且附加的函数实现了 ConfigurableGeneratorTransformer 接口,那么它可以进一步作为 kustomize 插件使用。

kustomize 的一个 Go 插件看起来是这样的:

  1. package main
  2. import (
  3. "sigs.k8s.io/kustomize/api/ifc"
  4. "sigs.k8s.io/kustomize/api/resmap"
  5. ...
  6. )
  7. type plugin struct {...}
  8. var KustomizePlugin plugin
  9. func (p *plugin) Config(
  10. ldr ifc.Loader,
  11. rf *resmap.Factory,
  12. c []byte) error {...}
  13. func (p *plugin) Generate() (resmap.ResMap, error) {...}
  14. func (p *plugin) Transform(m resmap.ResMap) error {...}

需要使用标识符 pluginKustomizePlugin 并且需要实现方法签名 Config

实现 GeneratororTransformer 方法允许(分别)将插件的配置文件添加到 kustomization 文件的 generatorsortransformers 字段中,并根据需要执行。

示例

  • service generator - 使用 name 和 port 参数生成一个 service。
  • string prefixer - 使用 metadata/name 值作为前缀。这个特殊的示例是为了展示插件的转化行为。详见 target 包中的 TestTransformedTransformers 测试。
  • date prefixer - 将当前日期作为前缀添加到资源名称上,这是一个用于修改刚才提到的字符串前缀插件的简单示例。
  • secret generator - 从 toy 数据库生成 secret。
  • sops encoded secrets - 一个更复杂的 secret 生成器。
  • All the builtin plugins. 用户自制的插件与内置插件是一样的。

Go 插件既可以是生成器,也可以是转化器。Generate 方法将在 Transform 方法运行之前与所有其他生成器一起运行。

如下的构建命令,假设插件源代码位于 kustomize 期望查找 .so 文件的目录中:

  1. d=$XDG_CONFIG_HOME/kustomize/plugin\
  2. /${apiVersion}/LOWERCASE(${kind})
  3. go build -buildmode plugin \
  4. -o $d/${kind}.so $d/${kind}.go

内置插件

内置插件

Exec 插件示例

60 秒在 Linux 构建一个 Exec 插件

Go 插件注意事项

Go 插件注意事项

Go 插件示例

Go 插件示例