mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
remove duplicate contents and redirect
This commit is contained in:
@@ -7,263 +7,6 @@ description: >
|
||||
Kustomize 插件指南
|
||||
---
|
||||
|
||||
Kustomize 提供一个插件框架,允许用户开发自己的 _生成器_ 和 _转化器_。
|
||||
<meta http-equiv="refresh" content="0; url=https://kubectl.docs.kubernetes.io/zh/guides/plugins/" />
|
||||
|
||||
[generator options]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/generatorOptions.md
|
||||
[transformer configs]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs
|
||||
|
||||
通过插件,实现 [generatorOptions] 和 [transformerconfigs] 无法满足的需求。
|
||||
|
||||
[12-factor]: https://12factor.net
|
||||
|
||||
* _generator_ 插件生成 k8s 资源,比如 [helm chart inflator] 是一个 generator 插件,基于少量自由变量生成一个 [12-factor] 应用所包含的全部组件 deployment,service,scaler,ingress 等)也是一个 generator 插件。
|
||||
* _transformer_ 插件转化(修改)k8s 资源,比如可能会执行对特殊容器命令行的编辑,或为其他内置转换器(`namePrefix`、`commonLabels` 等)无法转换的内容提供转换。
|
||||
|
||||
## `kustomization.yaml` 的格式
|
||||
|
||||
从为添加 `generators` 或 `transformers` 字段开始。
|
||||
|
||||
字段内容为一个 string list:
|
||||
|
||||
> ```yaml
|
||||
> generators:
|
||||
> - relative/path/to/some/file.yaml
|
||||
> - relative/path/to/some/kustomization
|
||||
> - /absolute/path/to/some/kustomization
|
||||
> - https://github.com/org/repo/some/kustomization
|
||||
>
|
||||
> transformers:
|
||||
> - {as above}
|
||||
> ```
|
||||
|
||||
格式要求与 `resources` 字段相同,`generators` 或 `transformers` 列表的每一列内容都必须是一个 YAML 文件的相对路径或者指向 [kustomization] 的 URL。
|
||||
|
||||
[kustomization]: /kustomize/zh/api-reference/glossary#kustomization
|
||||
|
||||
从磁盘上读取 YAML 文件,kustomization 的路径或 URL 会触发 kustomization 的运行。由此产生的每个的对象都会被 kustomize 进一步解析为 _plugin configuration_ 对象。
|
||||
|
||||
## 配置
|
||||
|
||||
kustomization 文件可以包含如下内容:
|
||||
|
||||
```yaml
|
||||
generators:
|
||||
- chartInflator.yaml
|
||||
```
|
||||
|
||||
像这样,kustomization 进程将在 [kustomization root](glossary.md#kustomization-root) 下寻找到一个名为 `chartInflator.yaml` 的文件。
|
||||
|
||||
`chartInflator.yaml` 为插件配置文件,该文件包含 YAML 配置对象,内容如下:
|
||||
|
||||
```yaml
|
||||
apiVersion: someteam.example.com/v1
|
||||
kind: ChartInflator
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
chartName: minecraft
|
||||
```
|
||||
|
||||
__`apiVersion` 和 `kind` 字段用于定位插件。__
|
||||
|
||||
[k8s 对象]: /kustomize/zh/api-reference/glossary#Kubernetes-风格的对象
|
||||
|
||||
同时由于 kustomize 插件配置对象也是一个 [k8s 对象],因此这些字段是必要的。
|
||||
|
||||
为了让插件准备好生成或转换,它包含了配置文件的全部内容。
|
||||
|
||||
[NameTransformer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin/prefixsuffixtransformer/PrefixSuffixTransformer_test.go
|
||||
[ChartInflator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
|
||||
[plugins]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin
|
||||
|
||||
更多关于插件配置 YAML 的例子,请浏览根目录下 [plugins] 中的单元测试,例如 [ChartInflator] 或 [NameTransformer]。
|
||||
|
||||
## 植入
|
||||
|
||||
每个插件都有自己的专用目录,名为:
|
||||
|
||||
[`XDG_CONFIG_HOME`]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
|
||||
```bash
|
||||
$XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
```
|
||||
|
||||
The default value of [`XDG_CONFIG_HOME`] is
|
||||
`$HOME/.config`.
|
||||
|
||||
[`XDG_CONFIG_HOME`] 的默认值为 `$HOME/.config`。
|
||||
|
||||
为了便于插件包(源码、测试、插件数据文件等)的共享,要求每个目录存放一个插件。
|
||||
|
||||
在 [Go 插件](#go-插件)中,还可以为单个插件提供一个 `go.mod` 文件,可以缓解包版本依赖性偏移的问题。
|
||||
|
||||
加载时,kustomize 首先会寻找一个 _可执行_ 文件,名为:
|
||||
|
||||
```bash
|
||||
$XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})/${kind}
|
||||
```
|
||||
|
||||
如果没有找到这个文件,或者这个文件不是可执行的,kustomize 会在同一目录下寻找一个名为 `${kind}.so` 的文件,并尝试将其作为 [Go插件](#go-插件) 加载。
|
||||
|
||||
如果这两项检查都失败,则插件加载失败,`kustomize build` 失败。
|
||||
|
||||
## 执行情况
|
||||
|
||||
插件只有在运行 `kustomize build` 命令时使用。
|
||||
|
||||
生成器插件是在处理完 `resources` 字段后运行的(`resources` 字段本身也可以看成是一个简单地从磁盘上读取对象的生成器)。
|
||||
|
||||
之后所有资源将被传递到转换管道中,由其中内置的转换器,如 `namePrefix` 和 `commonLabel` 等先转换应用(如果 kustomization 文件中指定了他们),然后再转换用户指定的 `transformers` 字段。
|
||||
|
||||
由于无法指定转化的顺序,所以需要遵守 `transformers` 字段中指定的顺序。
|
||||
|
||||
#### No Security
|
||||
|
||||
Kustomize 插件不会在任何形式的 kustomize 提供的沙盒中运行。不存在 _"plugin security"_ 的概念。
|
||||
|
||||
`kustomize build` 会尝试使用插件,但如果省略了 `--enable_alpha_plugins`,将导致插件无法加载,并且会有一个关于插件使用的警告。
|
||||
|
||||
使用这个 flag 就是承认使用不稳定的插件 API(alpha)、承认使用缺少出处插件,以及插件不属于 kustomize 的事实。
|
||||
|
||||
简单的说,一些从网上下载的 kustomize 插件可能会奇妙地将 k8s 的配置以理想的方式进行改造,同时也会悄悄地对运行 `kustomize build` 的系统做任何用户可以做的事情。
|
||||
|
||||
## 编写插件
|
||||
|
||||
插件有 [exec](#exec-插件) 和 [Go](#go-插件) 两种.
|
||||
|
||||
### Exec 插件
|
||||
|
||||
_exec 插件_ 是一个可以在命令行中接收参数可执行文件,该参数指向包含 kustomization 配置的 YAML 文件。
|
||||
|
||||
> TODO: 对插件的限制,允许同一个 _exec 插件_ 同时被 `generators` 和 `transformers` 字段所触发。
|
||||
>
|
||||
> - 第一个参数可以是固定的字符串 `generate` 或 `transform`,(配置文件的名称移动到第2个参数)
|
||||
> - 默认情况下,exec plugin 会作为一个转化器,除非提供了标志 `-g`,将 exec 插件切换为生成器。
|
||||
|
||||
[helm chart inflator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/chartinflator
|
||||
[bashed config map]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/bashedconfigmap
|
||||
[sed transformer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/sedtransformer
|
||||
[hashicorp go-getter]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/gogetter
|
||||
|
||||
#### 示例
|
||||
|
||||
* [helm chart inflator] - helm chart inflates 生成器。
|
||||
* [bashed config map] - 使用 bash 生成十分简单的 configMap。
|
||||
* [sed transformer] - 使用插件来定义非结构化的编辑。
|
||||
* [hashicorp go-getter] - 下载 kustomize layes 并通过构建它来生成资源。
|
||||
|
||||
生成器插件无需在 `stdin` 上输入任何东西,就会将生成的资源输出到 `stdout`。
|
||||
|
||||
转化器插件需要在 `stdin` 上输入资源的 YAML,并转化后的资源输出到 `stdout`。
|
||||
|
||||
kustomize 会使用 exec 插件适配器,为 `stdin` 提供的资源,并获取 `stdout` 以进行下一步的处理。
|
||||
|
||||
#### Generator 选项
|
||||
|
||||
生成器 exec 插件可以通过设置以下内部注释中的一个来调整生成器选项。
|
||||
|
||||
> 注意:这些注释只会在本地的 kustomize 中,不会出现在最终输出中。
|
||||
|
||||
**`kustomize.config.k8s.io/needs-hash`**
|
||||
|
||||
通过包含 `needs-hash` 注释,可以将资源标记为需要由内部哈希转换器处理的资源。当设置注释的有效值为 `"true"` 和 `"false"` 时,分别启用或禁用资源的哈希后缀。忽略该注解相当于将值设置为 `"false"`。
|
||||
|
||||
如果此注释被设置在不受哈希转换器支持的资源上,将导致构建将失败。
|
||||
|
||||
示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm-test
|
||||
annotations:
|
||||
kustomize.config.k8s.io/needs-hash: "true"
|
||||
data:
|
||||
foo: bar
|
||||
```
|
||||
|
||||
**`kustomize.config.k8s.io/behavior`**
|
||||
|
||||
`behavior` 注释为当资源发生冲突时插件的处理方式,有效值包括:"create"、"merge "和 "replace",默认为 "create"。
|
||||
|
||||
示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cm-test
|
||||
annotations:
|
||||
kustomize.config.k8s.io/behavior: "merge"
|
||||
data:
|
||||
foo: bar
|
||||
```
|
||||
|
||||
### Go 插件
|
||||
|
||||
请务必阅读 [Go 插件注意事项](goPluginCaveats.md)。
|
||||
|
||||
[Go 插件]: https://golang.org/pkg/plugin/
|
||||
|
||||
如果一个 `.go` 文件声明 `package main`,并附加了有用的功能标志,那么它就可以成为一个 [Go 插件]。
|
||||
|
||||
如果标志被命名为 “KustomizePlugin”,并且附加的函数实现了 `Configurable`、`Generator` 和 `Transformer` 接口,那么它可以进一步作为 _kustomize_ 插件使用。
|
||||
|
||||
kustomize 的一个 Go 插件看起来是这样的:
|
||||
|
||||
> ```go
|
||||
> package main
|
||||
>
|
||||
> import (
|
||||
> "sigs.k8s.io/kustomize/api/ifc"
|
||||
> "sigs.k8s.io/kustomize/api/resmap"
|
||||
> ...
|
||||
> )
|
||||
>
|
||||
> type plugin struct {...}
|
||||
>
|
||||
> var KustomizePlugin plugin
|
||||
>
|
||||
> func (p *plugin) Config(
|
||||
> ldr ifc.Loader,
|
||||
> rf *resmap.Factory,
|
||||
> c []byte) error {...}
|
||||
>
|
||||
> func (p *plugin) Generate() (resmap.ResMap, error) {...}
|
||||
>
|
||||
> func (p *plugin) Transform(m resmap.ResMap) error {...}
|
||||
> ```
|
||||
|
||||
需要使用标识符 `plugin`,`KustomizePlugin` 并且需要实现方法签名 `Config`。
|
||||
|
||||
实现 `Generatoror` 或 `Transformer` 方法允许(分别)将插件的配置文件添加到 kustomization 文件的 `generatorsor` 或 `transformers` 字段中,并根据需要执行。
|
||||
|
||||
[secret generator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/secretsfromdatabase
|
||||
[service generator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/someservicegenerator
|
||||
[string prefixer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/stringprefixer
|
||||
[date prefixer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/dateprefixer
|
||||
[sops encoded secrets]: https://github.com/monopole/sopsencodedsecrets
|
||||
|
||||
#### 示例
|
||||
|
||||
* [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](https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin).
|
||||
用户自制的插件与内置插件是一样的。
|
||||
|
||||
Go 插件既可以是生成器,也可以是转化器。`Generate` 方法将在 `Transform` 方法运行之前与所有其他生成器一起运行。
|
||||
|
||||
如下的构建命令,假设插件源代码位于 kustomize 期望查找 `.so` 文件的目录中:
|
||||
|
||||
```bash
|
||||
d=$XDG_CONFIG_HOME/kustomize/plugin\
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
|
||||
go build -buildmode plugin \
|
||||
-o $d/${kind}.so $d/${kind}.go
|
||||
```
|
||||
Moved to https://github.com/kubernetes-sigs/cli-experimental
|
||||
@@ -7,644 +7,6 @@ description: >
|
||||
内置插件
|
||||
---
|
||||
|
||||
内置插件包括生成器和转化器。
|
||||
<meta http-equiv="refresh" content="0; url=https://kubectl.docs.kubernetes.io/zh/guides/plugins/builtins/" />
|
||||
|
||||
每个插件都可以通过如下两种方式触发:
|
||||
|
||||
* 通过 kustomization 文件的字段隐式触发插件,例如 `AnnotationsTransformer` 就是由 `commonAnnotations` 字段触发的。
|
||||
|
||||
* 通过 `generators` 或 `transformers` 字段显式触发插件(通过指定插件的配置文件)。
|
||||
|
||||
直接使用 `kustomization.yaml` 文件中的字段比如 `commonLables`、`commonAnnotation` 他们可以修改一些默认的字段,如果用户想要添加或减少能被 `commonLabel` 所修改的字段,则不是很容易做到;而使用 `transformers` 的话,用户可以指定哪些字段能被修改,而不受默认值的影响。
|
||||
|
||||
[types.GeneratorOptions]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/generatoroptions.go
|
||||
[types.SecretArgs]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/secretargs.go
|
||||
[types.ConfigMapArgs]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/configmapargs.go
|
||||
[config.FieldSpec]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go
|
||||
[types.ObjectMeta]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/objectmeta.go
|
||||
[types.Selector]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/selector.go
|
||||
[types.Replica]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/replica.go
|
||||
[types.PatchStrategicMerge]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchstrategicmerge.go
|
||||
[types.PatchTarget]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchtarget.go
|
||||
[image.Image]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/image.go
|
||||
|
||||
## _AnnotationTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`commonAnnotations`
|
||||
|
||||
为所有资源添加注释,和标签一样以 key: value 的形式。
|
||||
|
||||
```yaml
|
||||
commonAnnotations:
|
||||
oncallPager: 800-555-1212
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Annotations map\[string\]string
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: AnnotationsTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> annotations:
|
||||
> app: myApp
|
||||
> greeting/morning: a string with blanks
|
||||
> fieldSpecs:
|
||||
> - path: metadata/annotations
|
||||
> create: true
|
||||
> ```
|
||||
|
||||
## _ConfigMapGenerator_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`configMapGenerator`
|
||||
|
||||
列表中的每个条目都将生成一个 ConfigMap (合计可以生成 n 个 ConfigMap)。
|
||||
|
||||
下面的示例会生成 3 个ConfigMap:第一个带有给定文件的名称和内容,第二个将在 data 中添加 key/value,第三个通过 `options` 为单个 ConfigMap 设置注释和标签。
|
||||
|
||||
每个 configMapGenerator 项均接受的参数 `behavior: [create|replace|merge]`,这个参数允许修改或替换父级现有的 configMap。
|
||||
|
||||
此外,每个条目都有一个 `options` 字段,该字段具有与 kustomization 文件的 `generatorOptions` 字段相同的子字段。
|
||||
|
||||
`options` 字段允许用户为生成的实例添加标签和(或)注释,或者分别禁用该实例名称的哈希后缀。此处添加的标签和注释不会被 kustomization 文件 `generatorOptions` 字段关联的全局选项覆盖。但是如果全局 `generatorOptions` 字段指定 `disableNameSuffixHash: true`,其他 `options` 的设置将无法将其覆盖。
|
||||
|
||||
```yaml
|
||||
# These labels are added to all configmaps and secrets.
|
||||
generatorOptions:
|
||||
labels:
|
||||
fruit: apple
|
||||
|
||||
configMapGenerator:
|
||||
- name: my-java-server-props
|
||||
behavior: merge
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
- name: my-java-server-env-vars
|
||||
literals:
|
||||
- JAVA_HOME=/opt/java/jdk
|
||||
- JAVA_TOOL_OPTIONS=-agentlib:hprof
|
||||
options:
|
||||
disableNameSuffixHash: true
|
||||
labels:
|
||||
pet: dog
|
||||
- name: dashboards
|
||||
files:
|
||||
- mydashboard.json
|
||||
options:
|
||||
annotations:
|
||||
dashboard: "1"
|
||||
labels:
|
||||
app.kubernetes.io/name: "app1"
|
||||
```
|
||||
|
||||
这里也可以[定义一个 key](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#define-the-key-to-use-when-creating-a-configmap-from-a-file) 来为文件设置不同名称。
|
||||
|
||||
下面这个示例会创建一个 ConfigMap,并将 `whatever.ini` 重命名为 `myFileName.ini`:
|
||||
|
||||
```yaml
|
||||
configMapGenerator:
|
||||
- name: app-whatever
|
||||
files:
|
||||
- myFileName.ini=whatever.ini
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> [types.ConfigMapArgs]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: ConfigMapGenerator
|
||||
> metadata:
|
||||
> name: mymap
|
||||
> envs:
|
||||
> - devops.env
|
||||
> - uxteam.env
|
||||
> literals:
|
||||
> - FRUIT=apple
|
||||
> - VEGETABLE=carrot
|
||||
> ```
|
||||
|
||||
## _ImageTagTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`images`
|
||||
|
||||
修改镜像的名称、tag 或 image digest ,而无需使用 patches 。例如,对于这种 kubernetes Deployment 片段:
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
- name: mypostgresdb
|
||||
image: postgres:8
|
||||
- name: nginxapp
|
||||
image: nginx:1.7.9
|
||||
- name: myapp
|
||||
image: my-demo-app:latest
|
||||
- name: alpine-app
|
||||
image: alpine:3.7
|
||||
```
|
||||
|
||||
想要将 `image` 做如下更改:
|
||||
|
||||
- 将 `postgres:8` 改为 `my-registry/my-postgres:v1`
|
||||
- 将 nginx tag 从 `1.7.9` 改为 `1.8.0`
|
||||
- 将镜像名称 `my-demo-app` 改为 `my-app`
|
||||
- 将 alpine 的 tag `3.7` 改为 digest 值
|
||||
|
||||
只需在 *kustomization* 中添加以下内容:
|
||||
|
||||
```yaml
|
||||
images:
|
||||
- name: postgres
|
||||
newName: my-registry/my-postgres
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: my-demo-app
|
||||
newName: my-app
|
||||
- name: alpine
|
||||
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> ImageTag [image.Image]
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: ImageTagTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> imageTag:
|
||||
> name: nginx
|
||||
> newTag: v2
|
||||
> ```
|
||||
|
||||
## _LabelTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`commonLabels`
|
||||
|
||||
为所有资源和 selectors 增加标签。
|
||||
|
||||
```yaml
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
owner: alice
|
||||
app: bingo
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Labels map\[string\]string
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: LabelTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> labels:
|
||||
> app: myApp
|
||||
> env: production
|
||||
> fieldSpecs:
|
||||
> - path: metadata/labels
|
||||
> create: true
|
||||
> ```
|
||||
|
||||
## _NamespaceTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`namespace`
|
||||
|
||||
为所有资源添加 namespace。
|
||||
|
||||
```yaml
|
||||
namespace: my-namespace
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> [types.ObjectMeta]
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: NamespaceTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> namespace: test
|
||||
> fieldSpecs:
|
||||
> - path: metadata/namespace
|
||||
> create: true
|
||||
> - path: subjects
|
||||
> kind: RoleBinding
|
||||
> group: rbac.authorization.k8s.io
|
||||
> - path: subjects
|
||||
> kind: ClusterRoleBinding
|
||||
> group: rbac.authorization.k8s.io
|
||||
> ```
|
||||
|
||||
## _PatchesJson6902_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`patchesJson6902`
|
||||
|
||||
patchesJson6902 列表中的每个条目都应可以解析为 kubernetes 对象和将应用于该对象的 [JSON patch](https://tools.ietf.org/html/rfc6902)。
|
||||
|
||||
目标字段指向的 kubernetes 对象的 group、 version、 kind、 name 和 namespace 在同一 kustomization 内 path 字段内容是 JSON patch 文件的相对路径。
|
||||
|
||||
patch 文件中的内容可以如下这种 JSON 格式:
|
||||
|
||||
```json
|
||||
[
|
||||
{"op": "add", "path": "/some/new/path", "value": "value"},
|
||||
{"op": "replace", "path": "/some/existing/path", "value": "new value"}
|
||||
]
|
||||
```
|
||||
|
||||
也可以使用 YAML 格式表示:
|
||||
|
||||
```yaml
|
||||
- op: add
|
||||
path: /some/new/path
|
||||
value: value
|
||||
- op: replace
|
||||
path: /some/existing/path
|
||||
value: new value
|
||||
```
|
||||
|
||||
```yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: my-deployment
|
||||
path: add_init_container.yaml
|
||||
- target:
|
||||
version: v1
|
||||
kind: Service
|
||||
name: my-service
|
||||
path: add_service_annotation.yaml
|
||||
```
|
||||
|
||||
patch 内容也可以是一个inline string:
|
||||
|
||||
```yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: my-deployment
|
||||
patch: |-
|
||||
- op: add
|
||||
path: /some/new/path
|
||||
value: value
|
||||
- op: replace
|
||||
path: /some/existing/path
|
||||
value: "new value"
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Target [types.PatchTarget]
|
||||
>
|
||||
> Path string
|
||||
>
|
||||
> JsonOp string
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: PatchJson6902Transformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> target:
|
||||
> group: apps
|
||||
> version: v1
|
||||
> kind: Deployment
|
||||
> name: my-deploy
|
||||
> path: jsonpatch.json
|
||||
> ```
|
||||
|
||||
## _PatchesStrategicMerge_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`patchesStrategicMerge`
|
||||
|
||||
此列表中的每个条目都应可以解析为 [StrategicMergePatch](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md).
|
||||
|
||||
这些(也可能是部分的)资源文件中的 name 必须与已经通过 `resources` 加载的 name 字段匹配,或者通过 `bases` 中的 name 字段匹配。这些条目将用于 _patch_(修改)已知资源。
|
||||
|
||||
推荐使用小的 patches,例如:修改内存的 request/limit,更改 ConfigMap 中的 env 变量等。小的 patches 易于维护和查看,并且易于在 overlays 中混合使用。
|
||||
|
||||
```yaml
|
||||
patchesStrategicMerge:
|
||||
- service_port_8888.yaml
|
||||
- deployment_increase_replicas.yaml
|
||||
- deployment_increase_memory.yaml
|
||||
```
|
||||
|
||||
patch 内容也可以是一个inline string:
|
||||
|
||||
```yaml
|
||||
patchesStrategicMerge:
|
||||
- |-
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nignx:latest
|
||||
```
|
||||
|
||||
请注意,kustomize 不支持同一个 patch 对象中包含多个 _删除_ 指令。要从一个对象中删除多个字段或切片元素,需要创建一个单独的 patch,以执行所有需要的删除。
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Paths \[\][types.PatchStrategicMerge]
|
||||
>
|
||||
> Patches string
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: PatchStrategicMergeTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> paths:
|
||||
> - patch.yaml
|
||||
> ```
|
||||
|
||||
## _PatchTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`patches`
|
||||
|
||||
这个列表中的每个条目应该解析到一个 Patch 对象,其中包括一个 patch 和一个目标选择器。patch 可以是 Strategic Merge Patch 或 JSON patch,也可以是 patch 文件或 inline string。目标选择器可以通过 group、version、kind、name、namespace、标签选择器和注释选择器来选择资源,选择一个或多个匹配所有指定字段的资源来应用 patch。
|
||||
|
||||
```yaml
|
||||
patches:
|
||||
- path: patch.yaml
|
||||
target:
|
||||
group: apps
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: deploy.*
|
||||
labelSelector: "env=dev"
|
||||
annotationSelector: "zone=west"
|
||||
- patch: |-
|
||||
- op: replace
|
||||
path: /some/existing/path
|
||||
value: new value
|
||||
target:
|
||||
kind: MyKind
|
||||
labelSelector: "env=dev"
|
||||
```
|
||||
|
||||
The `name` and `namespace` fields of the patch target selector are
|
||||
automatically anchored regular expressions. This means that the value `myapp`
|
||||
is equivalent to `^myapp$`。
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Path string
|
||||
>
|
||||
> Patch string
|
||||
>
|
||||
> Target \*[types.Selector]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: PatchTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> patch: '[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "nginx:latest"}]'
|
||||
> target:
|
||||
> name: .*Deploy
|
||||
> kind: Deployment
|
||||
> ```
|
||||
|
||||
## _PrefixSuffixTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`namePrefix`, `nameSuffix`
|
||||
|
||||
为所有资源的名称添加前缀或后缀。
|
||||
|
||||
例如:将 deployment 名称从 `wordpress` 变为 `alices-wordpress` 或 `wordpress-v2` 或 `alices-wordpress-v2`。
|
||||
|
||||
```yaml
|
||||
namePrefix: alices-
|
||||
nameSuffix: -v2
|
||||
```
|
||||
|
||||
如果资源类型是 ConfigMap 或 Secret,则在哈希值之前添加后缀。
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Prefix string
|
||||
>
|
||||
> Suffix string
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: PrefixSuffixTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> prefix: baked-
|
||||
> suffix: -pie
|
||||
> fieldSpecs:
|
||||
> - path: metadata/name
|
||||
> ```
|
||||
|
||||
## _ReplicaCountTransformer_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`replicas`
|
||||
|
||||
修改资源的副本数。
|
||||
|
||||
例如:对于如下 kubernetes Deployment 片段:
|
||||
|
||||
```yaml
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-name
|
||||
spec:
|
||||
replicas: 3
|
||||
```
|
||||
|
||||
在 kustomization 中添加以下内容,将副本数更改为 5:
|
||||
|
||||
```yaml
|
||||
replicas:
|
||||
- name: deployment-name
|
||||
count: 5
|
||||
```
|
||||
|
||||
该字段内容为列表,所以可以同时修改许多资源。
|
||||
|
||||
由于这个声明无法设置 `kind:` 或 `group:`,所以他只能匹配如下资源中的一种:
|
||||
|
||||
- `Deployment`
|
||||
- `ReplicationController`
|
||||
- `ReplicaSet`
|
||||
- `StatefulSet`
|
||||
|
||||
对于更复杂的用例,请使用 patch 。
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> Replica [types.Replica]
|
||||
>
|
||||
> FieldSpecs \[\][config.FieldSpec]
|
||||
|
||||
#### Example
|
||||
>
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: ReplicaCountTransformer
|
||||
> metadata:
|
||||
> name: not-important-to-example
|
||||
> replica:
|
||||
> name: myapp
|
||||
> count: 23
|
||||
> fieldSpecs:
|
||||
> - path: spec/replicas
|
||||
> create: true
|
||||
> kind: Deployment
|
||||
> - path: spec/replicas
|
||||
> create: true
|
||||
> kind: ReplicationController
|
||||
> ```
|
||||
|
||||
## _SecretGenerator_
|
||||
|
||||
### 使用 `kustomization.yaml`
|
||||
|
||||
#### 字段名称:`secretGenerator`
|
||||
|
||||
列表中的每个条目都将生成一个 Secret(合计可以生成 n 个 Secrets)。
|
||||
|
||||
功能与之前描述的 `configMapGenerator` 字段类似。
|
||||
|
||||
```yaml
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
files:
|
||||
- secret/tls.cert
|
||||
- secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: app-tls-namespaced
|
||||
# you can define a namespace to generate
|
||||
# a secret in, defaults to: "default"
|
||||
namespace: apps
|
||||
files:
|
||||
- tls.crt=catsecret/tls.cert
|
||||
- tls.key=secret/tls.key
|
||||
type: "kubernetes.io/tls"
|
||||
- name: env_file_secret
|
||||
envs:
|
||||
- env.txt
|
||||
type: Opaque
|
||||
- name: secret-with-annotation
|
||||
files:
|
||||
- app-config.yaml
|
||||
type: Opaque
|
||||
options:
|
||||
annotations:
|
||||
app_config: "true"
|
||||
labels:
|
||||
app.kubernetes.io/name: "app2"
|
||||
```
|
||||
|
||||
### 使用插件
|
||||
|
||||
#### Arguments
|
||||
|
||||
> [types.ObjectMeta]
|
||||
>
|
||||
> [types.SecretArgs]
|
||||
|
||||
#### Example
|
||||
|
||||
> ```yaml
|
||||
> apiVersion: builtin
|
||||
> kind: SecretGenerator
|
||||
> metadata:
|
||||
> name: my-secret
|
||||
> namespace: whatever
|
||||
> behavior: merge
|
||||
> envs:
|
||||
> - a.env
|
||||
> - b.env
|
||||
> files:
|
||||
> - obscure=longsecret.txt
|
||||
> literals:
|
||||
> - FRUIT=apple
|
||||
> - VEGETABLE=carrot
|
||||
> ```
|
||||
Moved to https://github.com/kubernetes-sigs/cli-experimental
|
||||
@@ -7,206 +7,6 @@ description: >
|
||||
60 秒在 Linux 构建一个 Exec 插件
|
||||
---
|
||||
|
||||
本教程只是一个快速开始的示例,完整的插件文档请看:[kustomize 插件](..)
|
||||
<meta http-equiv="refresh" content="0; url=https://kubectl.docs.kubernetes.io/zh/guides/plugins/execpluginguidedexample/" />
|
||||
|
||||
本示例将使用 bash 编写了一个简单的 _exec_ 插件,用来生成一个 `ConfigMap`。
|
||||
|
||||
尝试本教程不会破坏你的当前设置。
|
||||
|
||||
#### 环境要求
|
||||
|
||||
* `linux`
|
||||
* `git`
|
||||
* `curl`
|
||||
* `Go 1.13`
|
||||
|
||||
## 创建一个工作空间/目录
|
||||
|
||||
```bash
|
||||
DEMO=$(mktemp -d)
|
||||
```
|
||||
|
||||
## 编写 kustomization
|
||||
|
||||
新建一个目录来保存所有的配置:
|
||||
|
||||
```bash
|
||||
MYAPP=$DEMO/myapp
|
||||
mkdir -p $MYAPP
|
||||
```
|
||||
|
||||
编写一个 Deployment 配置:
|
||||
|
||||
```bash
|
||||
cat <<'EOF' >$MYAPP/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 3
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: the-container
|
||||
image: monopole/hello:1
|
||||
command: ["/hello",
|
||||
"--port=8080",
|
||||
"--date=$(THE_DATE)",
|
||||
"--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: THE_DATE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: the-map
|
||||
key: today
|
||||
- name: ALT_GREETING
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: the-map
|
||||
key: altGreeting
|
||||
- name: ENABLE_RISKY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: the-map
|
||||
key: enableRisky
|
||||
EOF
|
||||
```
|
||||
|
||||
编写一个 service 配置:
|
||||
|
||||
```bash
|
||||
cat <<EOF >$MYAPP/service.yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: the-service
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8666
|
||||
targetPort: 8080
|
||||
EOF
|
||||
```
|
||||
|
||||
现在为您要编写的插件创建一个配置文件。
|
||||
|
||||
这个配置文件的内容也是 k8s 资源对象。其中 `apiVersion` 和 `kind` 字段的值用于在文件系统中查找插件代码(稍后会对此进行更多介绍)。
|
||||
|
||||
```bash
|
||||
cat <<'EOF' >$MYAPP/cmGenerator.yaml
|
||||
apiVersion: myDevOpsTeam
|
||||
kind: SillyConfigMapGenerator
|
||||
metadata:
|
||||
name: whatever
|
||||
argsOneLiner: Bienvenue true
|
||||
EOF
|
||||
```
|
||||
|
||||
最后在 kustomization 文件中引用以上所有内容:
|
||||
|
||||
```bash
|
||||
cat <<EOF >$MYAPP/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
generators:
|
||||
- cmGenerator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
检查这些文件
|
||||
|
||||
```bash
|
||||
ls -C1 $MYAPP
|
||||
```
|
||||
|
||||
## 为插件创建目录
|
||||
|
||||
插件必须位于特定的目录,以便 Kustomize 能够找到它们。
|
||||
|
||||
该示例将使用临时目录:
|
||||
|
||||
```bash
|
||||
PLUGIN_ROOT=$DEMO/kustomize/plugin
|
||||
```
|
||||
|
||||
在上面定义的插件配置 `$MYAPP/cmGenerator.yaml` 中指定:
|
||||
|
||||
> ```yaml
|
||||
> apiVersion: myDevOpsTeam
|
||||
> kind: SillyConfigMapGenerator
|
||||
> ```
|
||||
|
||||
这意味着该插件必须位于以下目录中:
|
||||
|
||||
```bash
|
||||
MY_PLUGIN_DIR=$PLUGIN_ROOT/myDevOpsTeam/sillyconfigmapgenerator
|
||||
|
||||
mkdir -p $MY_PLUGIN_DIR
|
||||
```
|
||||
|
||||
插件的目录结构为: `apiVersion 的 value/小写 kind 的 value`。
|
||||
|
||||
插件拥有自己的目录,不但可以保存插件代码,还可以保存测试代码以需要的补充数据文件。
|
||||
|
||||
## 编写插件
|
||||
|
||||
插件有 _exec_ 和 _Go_ 两种.
|
||||
|
||||
编写一个 _exec_ 插件,将其安装到正确的目录,文件名必须与插件的类型匹配(在本例中为 `SillyConfigMapGenerator`):
|
||||
|
||||
```bash
|
||||
cat <<'EOF' >$MY_PLUGIN_DIR/SillyConfigMapGenerator
|
||||
#!/bin/bash
|
||||
# Skip the config file name argument.
|
||||
shift
|
||||
today=`date +%F`
|
||||
echo "
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
today: $today
|
||||
altGreeting: "$1"
|
||||
enableRisky: "$2"
|
||||
"
|
||||
EOF
|
||||
```
|
||||
|
||||
根据定义,_exec_ 插件必须是可执行的:
|
||||
|
||||
```bash
|
||||
chmod a+x $MY_PLUGIN_DIR/SillyConfigMapGenerator
|
||||
```
|
||||
|
||||
## 安装 kustomize
|
||||
|
||||
根据[文档](/kustomize/zh/installation)安装 kustomize:
|
||||
|
||||
```bash
|
||||
curl -s "https://raw.githubusercontent.com/\
|
||||
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
||||
mkdir -p $DEMO/bin
|
||||
mv kustomize $DEMO/bin
|
||||
```
|
||||
|
||||
## 检查目录结构
|
||||
|
||||
```bash
|
||||
tree $DEMO
|
||||
```
|
||||
|
||||
## 使用插件构建 APP
|
||||
|
||||
```bash
|
||||
XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
|
||||
```
|
||||
|
||||
之前如果您已经设置了 `PLUGIN_ROOT=$HOME/.config/kustomize/plugin`,则无需在 _kustomize_ 命令前使用 `XDG_CONFIG_HOME`。
|
||||
Moved to https://github.com/kubernetes-sigs/cli-experimental
|
||||
@@ -7,67 +7,6 @@ description: >
|
||||
Go 插件注意事项
|
||||
---
|
||||
|
||||
[plugin package]: https://golang.org/pkg/plugin
|
||||
[Go modules]: https://github.com/golang/go/wiki/Modules
|
||||
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
[tensorflow plugin]: https://www.tensorflow.org/guide/extend/op
|
||||
<meta http-equiv="refresh" content="0; url=https://kubectl.docs.kubernetes.io/zh/guides/plugins/goplugincaveats/" />
|
||||
|
||||
_Go 插件_ 是一个编译产品/组件,其定义见 [plugin package],需要特殊的构建标志,不能单独运行,必须加载到正在运行的 Go 程序中。
|
||||
|
||||
> 用 Go 编写的普通程序可以作为 _exec 插件_,但是不能作为 _Go 插件_。
|
||||
|
||||
Go 插件允许运行 kustomize 扩展,而无需在每次运行时将资源分配到子流程或从子流程中解封所有资源数据。Go 插件 API 确保一定程度的一致性,以避免混淆下游转换器。
|
||||
|
||||
Go 插件的工作方式与 [plugin package] 中所述的相同,但与 _plugin_ 一词相关的常见概念不同。
|
||||
|
||||
## The skew problem
|
||||
|
||||
Go 插件编译会创建一个 [ELF] 格式的 `.so` 文件,根据定义,该文件不包含有关目标代码来源的信息。
|
||||
|
||||
主程序 ELF 和插件 ELF 的编译条件(软件包依赖项的版本 `GOOS`,`GOARCH`)之间的偏移会导致插件加载失败,并带有无用的错误消息。
|
||||
|
||||
Exec 插件也会缺乏来源,但不会因编译不正确而失败。
|
||||
|
||||
在任何情况下,共享插件的最好方法是使用某种 _捆绑包_(git repo URL、git 存档文件、tar 包等),其中包含可解包至 `$XDG_CONFIG_HOME/kustomize/plugin` 的源代码,测试和相关数据。
|
||||
|
||||
对于 Go 插件,使用共享插件的最终用户 _必须同时编译 kustomize 和 plugin_。
|
||||
|
||||
这意味着一次性运行
|
||||
|
||||
```bash
|
||||
# Or whatever is appropriate at time of reading
|
||||
GOPATH=${whatever} GO111MODULE=on go get sigs.k8s.io/kustomize/api
|
||||
```
|
||||
|
||||
然后使用一个正常的开发周期
|
||||
|
||||
```bash
|
||||
go build -buildmode plugin \
|
||||
-o ${wherever}/${kind}.so ${wherever}/${kind}.go
|
||||
```
|
||||
|
||||
并根据需要调整路径和发行版本标记(例如 `v3.0.0`)。
|
||||
|
||||
为了进行比较,可以参考编写 [tensorflow plugin] 必须做的事情。
|
||||
|
||||
## 为什么支持 Go 插件
|
||||
|
||||
### 安全
|
||||
|
||||
Go 插件开发者可以操作与原生 kustomize 操作相同的 API,可确保某些语义、变量和检查等一致。exec 插件子进程通过 stdin/stdout 来处理这些问题,但对于下游的转化器和使用者来说,会更容易把事情搞砸。
|
||||
|
||||
关键点:如果插件通过 kustomize 提供的文件 `Loader` 接口读取文件,则会受到 kustomize 文件加载限制的约束。当然,除了代码审计之外,没有什么可以阻止 Go 插件导入 io 包并执行其所需的任何操作。
|
||||
|
||||
### Debugging
|
||||
|
||||
Go 插件开发者可以在功能测试中运行插件时,在 _本地_ 调试插件,并在插件内部和其他位置设置断点。
|
||||
|
||||
为了获得两全其美的方式(共享性和安全性),开发人员可以编写一个 `.go` 程序作为 _exec 插件_,同时可以被 `go generate` 程序处理生成 Go 插件(反之亦然)。
|
||||
|
||||
### 贡献单元化
|
||||
|
||||
所有内置的生成器和转换器本身都是 Go 插件。这意味着 kustomize 维护者可以将贡献的插件升级为内置插件,而无需更改代码(超出常规代码审阅要求的范围)。
|
||||
|
||||
### 围绕生态系统发展
|
||||
|
||||
工具可以简化 Go 插件的 _共享_,但是这需要大量的 Go 插件的创作,而这又会导致围绕共享插件的混乱。[Go modules] 一旦被更广泛地采用,将解决共享插件最大的难题:含糊不清的插件 vs 主机依赖性。
|
||||
Moved to https://github.com/kubernetes-sigs/cli-experimental
|
||||
@@ -7,301 +7,6 @@ description: >
|
||||
Go 插件示例
|
||||
---
|
||||
|
||||
[SopsEncodedSecrets repository]: https://github.com/monopole/sopsencodedsecrets
|
||||
[Go plugin]: https://golang.org/pkg/plugin
|
||||
[Go plugin caveats]: ../goplugincaveats
|
||||
<meta http-equiv="refresh" content="0; url=https://kubectl.docs.kubernetes.io/zh/guides/plugins/gopluginguidedexample/" />
|
||||
|
||||
本教程只是一个快速开始的示例,完整的插件文档请看:[kustomize 插件](..)
|
||||
|
||||
请务必阅读 [Go 插件注意事项](../goplugincaveats)。
|
||||
|
||||
该示例使用 Go 插件 `SopsEncodedSecrets`,该插件位于 [sopsencodedsecrets repository]中。这是一个进程内的 Go 插件,而不是恰巧用 Go 编写的 exec 插件(这是 Go 作者的另一种选择)。
|
||||
|
||||
尝试本教程不会破坏你的当前设置。
|
||||
|
||||
#### 环境要求
|
||||
|
||||
* `linux`
|
||||
* `git`
|
||||
* `curl`
|
||||
* `Go 1.13`
|
||||
|
||||
用于加密
|
||||
|
||||
* gpg
|
||||
|
||||
或
|
||||
|
||||
* Google cloud (gcloud) 安装
|
||||
* 具有 KMS 权限的 Google帐户
|
||||
|
||||
## 创建一个工作空间/目录
|
||||
|
||||
```shell
|
||||
# 将这些目录分开,以免造成 DEMO 目录的混乱。
|
||||
DEMO=$(mktemp -d)
|
||||
tmpGoPath=$(mktemp -d)
|
||||
```
|
||||
|
||||
## 安装 kustomize
|
||||
|
||||
需要安装 kustomize v3.0.0,并且必须对其进行 _编译_(而不是从 release 页面下载二进制文件):
|
||||
|
||||
```shell
|
||||
GOPATH=$tmpGoPath go install sigs.k8s.io/kustomize/kustomize
|
||||
```
|
||||
|
||||
## 为插件创建目录
|
||||
|
||||
kustomize 插件完全由其配置文件和源代码确定。
|
||||
|
||||
Kustomize 插件的配置文件的格式与 kubernetes 资源对象相同,这就意味着在配置文件中 `apiVersion`,`kind` 和 `metadata` 都是[必须的字段](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields)。
|
||||
|
||||
因为配置文件名出现在 kustomization 文件的 `generatorsor` 或 `transformers` 字段中,kustomize 会读取配置文件,然后在以下位置找到 Go 插件的目标代码:
|
||||
|
||||
> ```shell
|
||||
> $XDG_CONFIG_HOME/kustomize/plugin/$apiVersion/$lKind/$kind.so
|
||||
> ```
|
||||
|
||||
`lKind` 必须是小写字母的,然后将插件加载并提供其配置,插件的输出将成为整个 `kustomize build` 程序的一部分 。
|
||||
|
||||
同一插件在一个 kustomize 构建中可能会多次使用不同的配置文件。此外,kustomize 可能会先自定义 config 数据,然后再发送给插件。由于这些原因,插件不能自己去读取配置文件,而需要通过 kustomize 来读取配置。
|
||||
|
||||
该示例将在如下临时目录中存放其使用的插件:
|
||||
|
||||
```shell
|
||||
PLUGIN_ROOT=$DEMO/kustomize/plugin
|
||||
```
|
||||
|
||||
并在下面的命令行中临时设置 `XDG_CONFIG_HOME`。
|
||||
|
||||
### 使用什么 apiVersion 和 kind
|
||||
|
||||
在 kustomize 插件的开发时,插件代码不关心也不知道配置文件中的 `apiVersion` 或 `kind`。
|
||||
|
||||
插件会检查这些字段,但是剩下的字段提供了实际的配置数据,在这一点上,成功解析其他字段对于插件很重要。
|
||||
|
||||
本示例使用一个名为 _SopsEncodedSecrets_ 的插件,其位于 [SopsEncodedSecrets repository] 中。
|
||||
|
||||
我们选择安装插件到
|
||||
|
||||
```shell
|
||||
apiVersion=mygenerators
|
||||
kind=SopsEncodedSecrets
|
||||
```
|
||||
|
||||
### 定义插件的主目录
|
||||
|
||||
按照惯例,存放插件代码和补充数据,测试,文档等的目录名称必须是 kind 的小写形式。
|
||||
|
||||
```shell
|
||||
lKind=$(echo $kind | awk '{print tolower($0)}')
|
||||
```
|
||||
|
||||
### 下载 SopsEncodedSecrets 插件
|
||||
|
||||
在这种情况下,存储库名称已经与小写字母的 kind 匹配,因此我们只需克隆存储库并自动获取正确的目录名称即可:
|
||||
|
||||
```shell
|
||||
mkdir -p $PLUGIN_ROOT/${apiVersion}
|
||||
cd $PLUGIN_ROOT/${apiVersion}
|
||||
git clone git@github.com:monopole/sopsencodedsecrets.git
|
||||
```
|
||||
|
||||
记住这个目录:
|
||||
|
||||
```shell
|
||||
MY_PLUGIN_DIR=$PLUGIN_ROOT/${apiVersion}/${lKind}
|
||||
```
|
||||
|
||||
### 尝试测试插件
|
||||
|
||||
插件可能会自己带有测试文件。因此可以通过如下方式:
|
||||
|
||||
```shell
|
||||
cd $MY_PLUGIN_DIR
|
||||
go test SopsEncodedSecrets_test.go
|
||||
```
|
||||
|
||||
构建对象代码以供 kustomize 使用:
|
||||
|
||||
```shell
|
||||
cd $MY_PLUGIN_DIR
|
||||
GOPATH=$tmpGoPath go build -buildmode plugin -o ${kind}.so ${kind}.go
|
||||
```
|
||||
|
||||
此步骤可能会成功,但是由于依赖关系 [skew],kustomize 最终可能无法加载该插件。
|
||||
|
||||
[skew]: /docs/plugins/README.md#caveats
|
||||
|
||||
在加载失败时
|
||||
|
||||
* 确保使用相同版本的Go (_go1.13_),在相同的 `$GOOS`(_linux_)和 `$GOARCH`(_amd64_) 上构建插件,用于构建本演示中使用的 [kustomize](#安装-kustomize)。
|
||||
|
||||
* 修改插件中的依赖文件 `go.mod` 以匹配 kustomize 使用的版本。
|
||||
|
||||
缺乏工具和元数据来实现自动化,就不会有一个完整的 Go 插件生态。
|
||||
|
||||
Kustomize 采用了 Go 插件架构,可以轻松的接受新的生成器和转换器(只需编写一个插件),并确保本机操作(也已作为插件构建和测试)是分段的、可排序的和可重用的,而不是奇怪的插入在整体代码中。
|
||||
|
||||
## 编写 kustomization
|
||||
|
||||
新建一个 kustomization 目录存放你的配置:
|
||||
|
||||
```shell
|
||||
MYAPP=$DEMO/myapp
|
||||
mkdir -p $MYAPP
|
||||
```
|
||||
|
||||
为 SopsEncodedSecrets 插件编写一个配置文件。
|
||||
|
||||
插件可以通过 `apiVersion` 和 `kind` 找到:
|
||||
|
||||
```shell
|
||||
cat <<EOF >$MYAPP/secGenerator.yaml
|
||||
apiVersion: ${apiVersion}
|
||||
kind: ${kind}
|
||||
metadata:
|
||||
name: mySecretGenerator
|
||||
name: forbiddenValues
|
||||
namespace: production
|
||||
file: myEncryptedData.yaml
|
||||
keys:
|
||||
- ROCKET
|
||||
- CAR
|
||||
EOF
|
||||
```
|
||||
|
||||
插件可以在 `myEncryptedData.yaml` 中找到更多的数据。
|
||||
|
||||
编写一个引用插件配置的 kustomization 文件:
|
||||
|
||||
```shell
|
||||
cat <<EOF >$MYAPP/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
generators:
|
||||
- secGenerator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
接下来生成真实的加密数据。
|
||||
|
||||
### 确保您已安装加密工具
|
||||
|
||||
我们将使用 [sops](https://github.com/mozilla/sops) 对文件进行编码。选择 GPG 或 Google Cloud KMS 作为加密提供者以继续。
|
||||
|
||||
#### GPG
|
||||
|
||||
尝试这个命令:
|
||||
|
||||
```shell
|
||||
gpg --list-keys
|
||||
```
|
||||
|
||||
如果返回 list,则您已经成功创建了密钥。如果不是,请尝试从 sops 导入测试密钥。
|
||||
|
||||
```shell
|
||||
curl https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc | gpg --import
|
||||
SOPS_PGP_FP="1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A"
|
||||
```
|
||||
|
||||
#### Google Cloude KMS
|
||||
|
||||
尝试这个命令:
|
||||
|
||||
```shell
|
||||
gcloud kms keys list --location global --keyring sops
|
||||
```
|
||||
|
||||
如果成功了,想必你已经创建了密钥,并将其放置在一个名为 sops 的钥匙圈中。如果没有,那就这样做:
|
||||
|
||||
```shell
|
||||
gcloud kms keyrings create sops --location global
|
||||
gcloud kms keys create sops-key --location global \
|
||||
--keyring sops --purpose encryption
|
||||
```
|
||||
|
||||
通过如下方法,获取你的 keyLocation:
|
||||
|
||||
```shell
|
||||
keyLocation=$(\
|
||||
gcloud kms keys list --location global --keyring sops |\
|
||||
grep GOOGLE | cut -d " " -f1)
|
||||
echo $keyLocation
|
||||
```
|
||||
|
||||
### 安装 `sops`
|
||||
|
||||
```shell
|
||||
GOPATH=$tmpGoPath go install go.mozilla.org/sops/cmd/sops
|
||||
```
|
||||
|
||||
### 用你的私钥创建加密数据
|
||||
|
||||
创建需要加密的原始数据:
|
||||
|
||||
```shell
|
||||
cat <<EOF >$MYAPP/myClearData.yaml
|
||||
VEGETABLE: carrot
|
||||
ROCKET: saturn-v
|
||||
FRUIT: apple
|
||||
CAR: dymaxion
|
||||
EOF
|
||||
```
|
||||
|
||||
将数据加密插入到插件要读取的文件中:
|
||||
|
||||
使用 PGP
|
||||
|
||||
```shell
|
||||
$tmpGoPath/bin/sops --encrypt \
|
||||
--pgp $SOPS_PGP_FP \
|
||||
$MYAPP/myClearData.yaml >$MYAPP/myEncryptedData.yaml
|
||||
```
|
||||
|
||||
或者使用 GCP KMS
|
||||
|
||||
```shell
|
||||
$tmpGoPath/bin/sops --encrypt \
|
||||
--gcp-kms $keyLocation \
|
||||
$MYAPP/myClearData.yaml >$MYAPP/myEncryptedData.yaml
|
||||
```
|
||||
|
||||
查看文件
|
||||
|
||||
```shell
|
||||
tree $DEMO
|
||||
```
|
||||
|
||||
结果如下:
|
||||
|
||||
> ```shell
|
||||
> /tmp/tmp.0kIE9VclPt
|
||||
> ├── kustomize
|
||||
> │ └── plugin
|
||||
> │ └── mygenerators
|
||||
> │ └── sopsencodedsecrets
|
||||
> │ ├── go.mod
|
||||
> │ ├── go.sum
|
||||
> │ ├── LICENSE
|
||||
> │ ├── README.md
|
||||
> │ ├── SopsEncodedSecrets.go
|
||||
> │ ├── SopsEncodedSecrets.so
|
||||
> │ └── SopsEncodedSecrets_test.go
|
||||
> └── myapp
|
||||
> ├── kustomization.yaml
|
||||
> ├── myClearData.yaml
|
||||
> ├── myEncryptedData.yaml
|
||||
> └── secGenerator.yaml
|
||||
> ```
|
||||
|
||||
## 使用插件构建您的应用
|
||||
|
||||
```shell
|
||||
XDG_CONFIG_HOME=$DEMO $tmpGoPath/bin/kustomize build --enable_alpha_plugins $MYAPP
|
||||
```
|
||||
|
||||
这将生成一个 kubernetes secret,并对名称 `ROCKET` 和 `CAR` 的数据进行加密。
|
||||
|
||||
之前如果您已经设置了 `PLUGIN_ROOT=$HOME/.config/kustomize/plugin`,则无需在 _kustomize_ 命令前使用 `XDG_CONFIG_HOME`。
|
||||
Moved to https://github.com/kubernetes-sigs/cli-experimental
|
||||
Reference in New Issue
Block a user