mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-10 08:20:59 +00:00
Remove kv plugins from docs.
This commit is contained in:
295
docs/plugins.md
295
docs/plugins.md
@@ -1,20 +1,36 @@
|
||||
# kustomize plugins
|
||||
|
||||
Kustomize offers a plugin framework for people to
|
||||
write their own resource _generators_ (e.g. a helm
|
||||
chart processor, a generator that automatically
|
||||
attaches a Service and Ingress object to each
|
||||
Deployment) and their own resource _transformers_
|
||||
(e.g. a transformer that does some highly
|
||||
customized processing of the container command
|
||||
line).
|
||||
Kustomize offers a plugin framework allowing
|
||||
people to write their own resource _generators_
|
||||
and _transformers_.
|
||||
|
||||
[generator options]: ../examples/generatorOptions.md
|
||||
[transformer configs]: ../examples/transformerconfigs
|
||||
|
||||
Write a plugin when changing [generator options]
|
||||
or [transformer configs] doesn't meet your needs.
|
||||
|
||||
[12-factor]: https://12factor.net
|
||||
|
||||
* A _generator_ plugin could be a helm chart
|
||||
inflator, or a plugin that emits all the
|
||||
components (deployment, service, scaler,
|
||||
ingress, etc.) needed by someone's [12-factor]
|
||||
application, based on a smaller number of free
|
||||
variables.
|
||||
|
||||
* A _transformer_ plugin might perform special
|
||||
container command line edits, or any other
|
||||
transformation that exceeds the power of the
|
||||
builtin transformations (`namePrefix`,
|
||||
`commonLabels`, etc.).
|
||||
|
||||
## Specification in `kustomization.yaml`
|
||||
|
||||
Start by adding a `generators` and/or `transformers`
|
||||
field to your kustomization.
|
||||
|
||||
Each field is a string array:
|
||||
Each field accepts a string list:
|
||||
|
||||
> ```
|
||||
> generators:
|
||||
@@ -27,11 +43,13 @@ Each field is a string array:
|
||||
> - {as above}
|
||||
> ```
|
||||
|
||||
This is exactly like the syntax of the `resources` field.
|
||||
This is exactly like the syntax of the `resources`
|
||||
field.
|
||||
|
||||
The value of each entry in a `resources`, `generators`
|
||||
or `transformers` array must be a relative path to a
|
||||
YAML file, or a path or URL to a [kustomization].
|
||||
The value of each entry in a `resources`,
|
||||
`generators` or `transformers` list must be a
|
||||
relative path to a YAML file, or a path or URL
|
||||
to a [kustomization].
|
||||
|
||||
[kustomization]: glossary.md#kustomization
|
||||
|
||||
@@ -39,9 +57,9 @@ In the former case the YAML is read from disk directly,
|
||||
and in the latter case a kustomization is performed,
|
||||
and its YAML output is merged with the YAML read
|
||||
directly from files. The net result in all three cases
|
||||
is an array of YAML objects.
|
||||
is a set of YAML objects.
|
||||
|
||||
_Each_ object resulting from a `generators` or
|
||||
Each object resulting from a `generators` or
|
||||
`transformers` field is now further interpreted by
|
||||
kustomize as a _plugin configuration_ object.
|
||||
|
||||
@@ -58,6 +76,8 @@ Given this, the kustomization process would expect to
|
||||
find a file called `chartInflator.yaml` in the
|
||||
kustomization [root](glossary.md#kustomization-root).
|
||||
|
||||
This is the _plugin's configuration file_.
|
||||
|
||||
The file `chartInflator.yaml` could contain:
|
||||
|
||||
```
|
||||
@@ -68,50 +88,51 @@ metadata:
|
||||
chartName: minecraft
|
||||
```
|
||||
|
||||
The `apiVersion` and `kind` fields of the configuration
|
||||
objects are used to _locate_ the plugin.
|
||||
__The `apiVersion` and `kind` fields are
|
||||
used to locate the plugin.__
|
||||
|
||||
The rest of the file (actually the entire file) is
|
||||
sent to the plugin as configuration - i.e. as the
|
||||
plugin's construction arguments.
|
||||
[k8s object]: glossary.md#kubernetes-style-object
|
||||
|
||||
A kustomization file could include multiple
|
||||
instantiations of the same plugin, with different
|
||||
arguments (e.g. to inflate two different helm
|
||||
charts or two instances of the same chart but with
|
||||
different values files).
|
||||
> Thus, these fields are required. They are also
|
||||
> required because a kustomize plugin
|
||||
> configuration object is also a [k8s object].
|
||||
|
||||
The value order in the `generators` field doesn't
|
||||
matter, because generated objects are just added
|
||||
to a sea of objects that kustomize transforms and
|
||||
emits.
|
||||
To get the plugin ready to generator or transform,
|
||||
it is given the entire contents of the
|
||||
configuration file.
|
||||
|
||||
The specified order of transformers in the
|
||||
`transformers` field should be respected, as
|
||||
transformers cannot be expected to be commutative.
|
||||
[NameTransformer]: ../plugin/builtin/nametransformer/NameTransformer_test.go
|
||||
[ChartInflator]: ../plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
|
||||
[plugins]: ../plugin/builtin
|
||||
|
||||
## Execution
|
||||
|
||||
Plugins are only used during a run of the
|
||||
`kustomize build` command.
|
||||
|
||||
Generator plugins are run after processing the
|
||||
`resources` field (which _reads_ resources), to
|
||||
_create_ additional resources.
|
||||
|
||||
The full set of resources is then passed into the
|
||||
transformation pipeline, where native (legacy)
|
||||
transformations like `namePrefix` and
|
||||
`commonLabel` are applied, followed by all the
|
||||
transformers run in the order specified.
|
||||
For more examples of plugin configuration YAML,
|
||||
browse the unit tests below the [plugins] root,
|
||||
e.g. the tests for [ChartInflator] or
|
||||
[NameTransformer].
|
||||
|
||||
|
||||
## Placement
|
||||
|
||||
[k8s object]: glossary.md#kubernetes-style-object
|
||||
Each plugin gets its own dedicated directory named
|
||||
|
||||
Given a plugin configuration object (it looks like any
|
||||
other [k8s object]), kustomize will first look for an
|
||||
```
|
||||
$XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
```
|
||||
|
||||
The default value of `XDG_CONFIG_HOME` is
|
||||
`$HOME/.config`.
|
||||
|
||||
The one-plugin-per-directory requirement eases
|
||||
creation of a plugin tarball (source, test, plugin
|
||||
data files, etc.) for sharing.
|
||||
|
||||
In the case of a [Go plugin](#go-plugins), it also
|
||||
allows one to provide a `go.mod` file for the
|
||||
single plugin, easing resolution of package
|
||||
version dependency skew.
|
||||
|
||||
When loading, kustomize will first look for an
|
||||
_executable_ file called
|
||||
|
||||
```
|
||||
@@ -119,24 +140,45 @@ $XDG_CONFIG_HOME/kustomize/plugin
|
||||
/${apiVersion}/LOWERCASE(${kind})/${kind}
|
||||
```
|
||||
|
||||
The default value of `XDG_CONFIG_HOME` is `$HOME/.config`.
|
||||
|
||||
If this file is not found or is not executable,
|
||||
kustomize will look for a file called `${kind}.so`
|
||||
in the same directory and attempt to load it as a
|
||||
[Go plugin](#go-plugins).
|
||||
|
||||
If both checks fails, the plugin load fails the overall
|
||||
kustomize build.
|
||||
If both checks fail, the plugin load fails the overall
|
||||
`kustomize build`.
|
||||
|
||||
A `kustomize build` attempt with plugins that
|
||||
## Execution
|
||||
|
||||
Plugins are only used during a run of the
|
||||
`kustomize build` command.
|
||||
|
||||
Generator plugins are run after processing the
|
||||
`resources` field (which itself is in some sense a
|
||||
generator in that it emits resources for further
|
||||
processing).
|
||||
|
||||
The full set of resources is then passed into the
|
||||
transformation pipeline, wherein builtin
|
||||
transformations like `namePrefix` and
|
||||
`commonLabel` are applied (if they were specified
|
||||
in the kustomization file), followed by the
|
||||
user-specified transformers in the `transformers`
|
||||
field.
|
||||
|
||||
The specified order of transformers in the
|
||||
`transformers` field should be respected, as
|
||||
transformers cannot be expected to be commutative.
|
||||
|
||||
A `kustomize build` that tries to use plugins but
|
||||
omits the flag
|
||||
|
||||
_TODO: Change flag_
|
||||
|
||||
> `--enable_alpha_goplugins_accept_panic_risk`
|
||||
|
||||
will fail with a warning about plugin use.
|
||||
|
||||
_TODO: Change flag_
|
||||
|
||||
Flag use is an opt-in acknowledging the absence of
|
||||
plugin provenance. It's meant to give pause to
|
||||
@@ -147,34 +189,44 @@ code in plugin form. The plugin would have to be
|
||||
installed already, but nevertheless the flag is a
|
||||
reminder.
|
||||
|
||||
|
||||
## Writing plugins
|
||||
|
||||
### Exec plugins
|
||||
|
||||
[chartinflator]: ../plugin/someteam.example.com/v1/chartinflator/ChartInflator
|
||||
|
||||
See this example [helm chart inflator][chartInflator].
|
||||
|
||||
A exec plugin is any executable that accepts a
|
||||
A _exec plugin_ is any executable that accepts a
|
||||
single argument on its command line - the name of
|
||||
a YAML file containing its configuration.
|
||||
a YAML file containing its configuration (the file name
|
||||
provided in the kustomization file).
|
||||
|
||||
> TODO: more restrictions on plugin to allow the same exec
|
||||
> plugin to be specified in a config under both the
|
||||
> `generators` and `transformers` fields.
|
||||
> - first arg could be the fixed string
|
||||
> `generate` or `transform`,
|
||||
> (the name of the configuration file moves to
|
||||
> (the name of the configuration file moves to
|
||||
> the 2nd arg), or
|
||||
> - by default an exec plugin behaves as a tranformer
|
||||
> unless a flag `-g` is provided, switching the
|
||||
> exec plugin to behave as a generator.
|
||||
|
||||
[helm chart inflator]: ../plugin/someteam.example.com/v1/chartinflator
|
||||
[bashed config map]: ../plugin/someteam.example.com/v1/bashedconfigmap
|
||||
[sed transformer]: ../plugin/someteam.example.com/v1/sedtransformer
|
||||
|
||||
#### Examples
|
||||
|
||||
* [helm chart inflator] - A generator that inflates a helm chart.
|
||||
* [bashed config map] - Super simple configMap generation from bash.
|
||||
* [sed transformer] - Define your unstructured edits using a
|
||||
plugin like this one.
|
||||
|
||||
|
||||
A generator plugin accepts nothing on `stdin`, but emits
|
||||
generated resources to `stdout`.
|
||||
|
||||
A transformer plugin accepts resource YAML on `stdin`,
|
||||
and emits those resources, possibly transformed, to
|
||||
and emits those resources, presumably transformed, to
|
||||
`stdout`.
|
||||
|
||||
kustomize uses an exec plugin adapter to provide
|
||||
@@ -184,9 +236,6 @@ marshalled resources on `stdin` and capture
|
||||
### Go plugins
|
||||
|
||||
[Go plugin]: https://golang.org/pkg/plugin/
|
||||
[servicegenerator]: ../plugin/someteam.example.com/v1/someservicegenerator/SomeServiceGenerator.go
|
||||
|
||||
See this example [service generator][serviceGenerator].
|
||||
|
||||
A [Go plugin] for kustomize looks like this:
|
||||
|
||||
@@ -213,60 +262,90 @@ A [Go plugin] for kustomize looks like this:
|
||||
> func (p *plugin) Transform(m resmap.ResMap) error {...}
|
||||
> ```
|
||||
|
||||
The use of the identifiers `plugin`,
|
||||
`KustomizePlugin` and the three method signatures
|
||||
`Configurable`, `Generator`, `Transformer` as
|
||||
shown is _required_.
|
||||
Use of the identifiers `plugin`, `KustomizePlugin`
|
||||
and implementation of the method signature
|
||||
`Config` is required.
|
||||
|
||||
The plugin author will change the
|
||||
contents of the `plugin` struct, and the three
|
||||
method bodies, and add imports as desired.
|
||||
Implementing the `Generator` or `Transformer`
|
||||
method allows (respectively) the plugin's config
|
||||
file to be added to the `generators` or
|
||||
`transformers` field in the kustomization file.
|
||||
Do one or the other or both as desired.
|
||||
|
||||
Here's a build command, which assumes the plugin
|
||||
source code is sitting right next to where the
|
||||
shared object (`.so`) files are expected to be:
|
||||
[secret generator]: ../plugin/someteam.example.com/v1/secretsfromdatabase
|
||||
[service generator]: ../plugin/someteam.example.com/v1/someservicegenerator
|
||||
[string prefixer]: ../plugin/someteam.example.com/v1/stringprefixer
|
||||
[date prefixer]: ../plugin/someteam.example.com/v1/dateprefixer
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
* [secret generator] - Generate secrets from a database.
|
||||
* [service generator] - Generate a service from a name and port argument.
|
||||
* [string prefixer] - uses the value in `metadata/name` as the prefix.
|
||||
This particular example exists to show how a plugin can
|
||||
transform the behavior of a plugin. See the
|
||||
`TestTransformedTransformers` test in the `target` package.
|
||||
* [date prefixer] - prefix the current date to resource names, a simple
|
||||
example used to modify the string prefixer plugin just mentioned.
|
||||
* All the builtin plugins [here](../plugin/builtin).
|
||||
User authored plugins are
|
||||
on the same footing as builtin operations.
|
||||
|
||||
A plugin can be both a generator and a
|
||||
transformer. The `Generate` method will run along
|
||||
with all the other generators before the
|
||||
`Transform` method runs.
|
||||
|
||||
Here's a build command that sensibly assumes the
|
||||
plugin source code sits in the directory where
|
||||
kustomize expects to find `.so` files:
|
||||
|
||||
```
|
||||
d=$XDG_CONFIG_HOME/kustomize/plugin/${apiVersion}/LOWERCASE(${kind})
|
||||
go build -buildmode plugin -o $d/${kind}.so $d/${kind}.go
|
||||
d=$XDG_CONFIG_HOME/kustomize/plugin\
|
||||
/${apiVersion}/LOWERCASE(${kind})
|
||||
|
||||
go build -buildmode plugin \
|
||||
-o $d/${kind}.so $d/${kind}.go
|
||||
```
|
||||
|
||||
#### Caveats
|
||||
|
||||
Go plugins allow kustomize extensions that
|
||||
|
||||
* can be tested with the same framework kustomize
|
||||
uses to test its _builtin_ generators and
|
||||
transformers,
|
||||
|
||||
* run without the performance cost of firing up a
|
||||
subprocess and marshalling/unmarshalling all
|
||||
resource data for each plugin run.
|
||||
Go plugins allow kustomize extensions that run
|
||||
without the cost marshalling/unmarshalling all
|
||||
resource data to/from a subprocess for each plugin
|
||||
run.
|
||||
|
||||
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
|
||||
|
||||
Go plugins work as [defined][Go plugin], but fall
|
||||
short of what many people think of when they hear
|
||||
the word _plugin_. Go plugin compilation creates
|
||||
an [ELF] formatted `.so` file, which by definition
|
||||
has no information about the _provenance_ of the
|
||||
file.
|
||||
short of common notions associated with the word
|
||||
_plugin_. Go plugin compilation creates an [ELF]
|
||||
formatted `.so` file, which by definition has no
|
||||
information about the provenance of the object
|
||||
code. Skew between the compilation conditions
|
||||
(versions of package dependencies, `GOOS`,
|
||||
`GOARCH`) of the main program ELF and the plugin
|
||||
ELF will cause plugin load failure.
|
||||
|
||||
One cannot know which version of Go was used,
|
||||
which packages were imported (and their version),
|
||||
what value of `GOOS` and `GOARCH` were used,
|
||||
etc. Skew between the compilation conditions of
|
||||
the main program ELF and the plugin ELF will cause
|
||||
a failure at load time.
|
||||
Exec plugins also lack provenance, but won't
|
||||
complain about compilation skew.
|
||||
|
||||
Exec plugins also lack provenance, but don't
|
||||
suffer from the skew problem.
|
||||
In either case, a sensible way to share a plugin
|
||||
is as a tar file of source code, tests and
|
||||
associated data, unpackable under
|
||||
`$XDG_CONFIG_HOME/kustomize/plugin` (exactly where
|
||||
one would develop a plugin).
|
||||
|
||||
In either case, at the time of writing the proper
|
||||
way to share a plugin is as a tar file of source code
|
||||
and associated data, developed and unpacked under
|
||||
`kustomize/plugin`. In the case of a Go plugin, the
|
||||
end user must compile it (described above), and may
|
||||
need to compile kustomize as well. If people use
|
||||
Go plugins, more tooling will be built to make
|
||||
plugin sharing easier.
|
||||
[Go modules]: https://github.com/golang/go/wiki/Modules
|
||||
|
||||
In the case of a Go plugin, an end user accepting
|
||||
a shared plugin must compile both kustomize and
|
||||
the plugin. Tooling could be built to make Go
|
||||
_plugin sharing_ easier, but this requires some
|
||||
critical mass of _plugin authoring_, which in turn
|
||||
is hampered by confusion around sharing.
|
||||
[Go modules], once they are more widely adopted,
|
||||
will solve one of the biggest plugin sharing
|
||||
difficulties - ambiguous plugin vs host
|
||||
dependencies.
|
||||
|
||||
Reference in New Issue
Block a user