mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-24 15:57:00 +00:00
Merge pull request #1246 from monopole/pluginDocGetsOwnDir
Add another detailed plugin example.
This commit is contained in:
@@ -12,7 +12,7 @@ English | [简体中文](zh/README.md)
|
||||
* [Kustomize Fields](fields.md) - explanations of the fields
|
||||
in a [kustomization](glossary.md#kustomization) file.
|
||||
|
||||
* [Plugins](plugins.md) - extending kustomize with
|
||||
* [Plugins](plugins) - extending kustomize with
|
||||
custom generators and transformers.
|
||||
|
||||
* [Workflows](workflows.md) - steps one might take in
|
||||
@@ -23,6 +23,8 @@ English | [简体中文](zh/README.md)
|
||||
|
||||
## Release notes
|
||||
|
||||
* [3.0](v3.0.0.md) - Late June 2019. Plugin developer release.
|
||||
|
||||
* [2.1](v2.1.0.md) - 18 June 2019. Plugins, ordered resources, etc.
|
||||
|
||||
* [2.0](v2.0.0.md) - Mar 2019.
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
# Exec plugin on linux in 30 seconds
|
||||
|
||||
Full plugin docs [here](plugins.md).
|
||||
|
||||
This demo writes and uses a somewhat ridiculous
|
||||
_exec_ plugin (written in bash) that generates a
|
||||
`ConfigMap`.
|
||||
|
||||
|
||||
## Make a place to work
|
||||
|
||||
```
|
||||
DEMO=$(mktemp -d)
|
||||
```
|
||||
|
||||
## Create a kustomization
|
||||
|
||||
Make a kustomization directory to
|
||||
hold all your config:
|
||||
|
||||
```
|
||||
MYAPP=$DEMO/myapp
|
||||
mkdir -p $MYAPP
|
||||
```
|
||||
|
||||
Make a deployment config:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Make a service config:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/service.yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: the-service
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8666
|
||||
targetPort: 8080
|
||||
EOF
|
||||
```
|
||||
|
||||
Now make a config file for the plugin
|
||||
you're about to write.
|
||||
|
||||
This config file is just another k8s resource
|
||||
object. The values of its `apiVersion` and `kind`
|
||||
fields are used to _find_ the plugin code on your
|
||||
filesystem (more on this later).
|
||||
|
||||
```
|
||||
cat <<'EOF' >$MYAPP/cmGenerator.yaml
|
||||
apiVersion: myDevOpsTeam
|
||||
kind: SillyConfigMapGenerator
|
||||
metadata:
|
||||
name: whatever
|
||||
argsOneLiner: Bienvenue true
|
||||
EOF
|
||||
```
|
||||
|
||||
Finally, make a kustomization file
|
||||
referencing all of the above:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
generators:
|
||||
- cmGenerator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Review the files
|
||||
```
|
||||
ls -C1 $MYAPP
|
||||
```
|
||||
|
||||
|
||||
## Make a home for plugins
|
||||
|
||||
Plugins must live in a particular place for
|
||||
kustomize to find them.
|
||||
|
||||
This demo will use the ephemeral directory:
|
||||
|
||||
```
|
||||
PLUGIN_ROOT=$DEMO/kustomize/plugin
|
||||
```
|
||||
|
||||
The plugin config defined above in
|
||||
`$MYAPP/cmGenerator.yaml` specifies:
|
||||
|
||||
> ```
|
||||
> apiVersion: myDevOpsTeam
|
||||
> kind: SillyConfigMapGenerator
|
||||
> ```
|
||||
|
||||
This means the plugin must live in a directory
|
||||
named:
|
||||
|
||||
```
|
||||
MY_PLUGIN_DIR=$PLUGIN_ROOT/myDevOpsTeam/sillyconfigmapgenerator
|
||||
|
||||
mkdir -p $MY_PLUGIN_DIR
|
||||
```
|
||||
|
||||
The directory name is the plugin config's
|
||||
_apiVersion_ followed by its lower-cased _kind_.
|
||||
|
||||
A plugin gets its own directory to hold itself,
|
||||
its tests and any supplemental data files it
|
||||
might need.
|
||||
|
||||
## Create the plugin
|
||||
|
||||
There are two kinds of plugins, _exec_ and _Go_.
|
||||
|
||||
Make an _exec_ plugin, installing it to the
|
||||
correct directory and file name. The file name
|
||||
must match the plugin's _kind_ (in this case,
|
||||
`SillyConfigMapGenerator`):
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
By definition, an _exec_ plugin must be executable:
|
||||
|
||||
```
|
||||
chmod a+x $MY_PLUGIN_DIR/SillyConfigMapGenerator
|
||||
```
|
||||
|
||||
|
||||
## Download kustomize 2.1.0
|
||||
|
||||
```
|
||||
mkdir -p $DEMO/bin
|
||||
gh=https://github.com/kubernetes-sigs/kustomize/releases/download
|
||||
url=$gh/v2.1.0/kustomize_2.1.0_linux_amd64
|
||||
curl -o $DEMO/bin/kustomize -L $url
|
||||
chmod u+x $DEMO/bin/kustomize
|
||||
```
|
||||
|
||||
## Review the layout
|
||||
|
||||
```
|
||||
tree $DEMO
|
||||
```
|
||||
|
||||
## Build your app, using the plugin:
|
||||
|
||||
```
|
||||
XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
|
||||
```
|
||||
|
||||
Above, if you had set
|
||||
|
||||
> ```
|
||||
> PLUGIN_ROOT=$HOME/.config/kustomize/plugin
|
||||
> ```
|
||||
|
||||
there would be no need to use `XDG_CONFIG_HOME` in the
|
||||
_kustomize_ command above.
|
||||
|
||||
1
docs/execPluginIn30sec.md
Symbolic link
1
docs/execPluginIn30sec.md
Symbolic link
@@ -0,0 +1 @@
|
||||
plugins/execPluginGuidedExample.md
|
||||
@@ -21,7 +21,7 @@ What things should be created (and optionally subsequently customized)?
|
||||
|[configMapGenerator](#configmapgenerator)| list |Each entry in this list results in the creation of one ConfigMap resource (it's a generator of n maps).|
|
||||
|[secretGenerator](#secretgenerator)| list |Each entry in this list results in the creation of one Secret resource (it's a generator of n secrets)|
|
||||
|[generatorOptions](#generatoroptions)|string|generatorOptions modify behavior of all ConfigMap and Secret generators|
|
||||
|[generators](#generators)|list|[plugin](plugins.md) configuration files|
|
||||
|[generators](#generators)|list|[plugin](plugins) configuration files|
|
||||
|
||||
|
||||
## Transformers
|
||||
@@ -40,7 +40,7 @@ What transformations (customizations) should be applied?
|
||||
| [replicas](#replicas) | list | Replicas modifies the number of replicas of a resource. |
|
||||
|[patchesStrategicMerge](#patchesstrategicmerge)| list |Each entry in this list should resolve to a partial or complete resource definition file.|
|
||||
|[patchesJson6902](#patchesjson6902)| list |Each entry in this list should resolve to a kubernetes object and a JSON patch that will be applied to the object.|
|
||||
|[transformers](#transformers)|list|[plugin](plugins.md) configuration files|
|
||||
|[transformers](#transformers)|list|[plugin](plugins) configuration files|
|
||||
|
||||
|
||||
## Meta
|
||||
@@ -173,7 +173,7 @@ generatorOptions:
|
||||
|
||||
### generators
|
||||
|
||||
A list of generator [plugin](plugins.md) configuration files.
|
||||
A list of generator [plugin](plugins) configuration files.
|
||||
|
||||
```
|
||||
generators:
|
||||
|
||||
@@ -405,7 +405,7 @@ A chunk of code used by kustomize, but not necessarily
|
||||
compiled into kustomize, to generate and/or transform a
|
||||
kubernetes resource as part of a kustomization.
|
||||
|
||||
Details [here](plugins.md).
|
||||
Details [here](plugins).
|
||||
|
||||
## resource
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
# kustomize plugins
|
||||
|
||||
See also: [linux exec plugin in 30 sec](execPluginIn30sec.md)
|
||||
Quick guides:
|
||||
|
||||
* [linux exec plugin in 60 sec](execPluginGuidedExample.md)
|
||||
* [linux Go plugin in 60 sec](goPluginGuidedExample.md)
|
||||
|
||||
Kustomize offers a plugin framework allowing
|
||||
people to write their own resource _generators_
|
||||
and _transformers_.
|
||||
|
||||
[generator options]: ../examples/generatorOptions.md
|
||||
[transformer configs]: ../examples/transformerconfigs
|
||||
[generator options]: ../../examples/generatorOptions.md
|
||||
[transformer configs]: ../../examples/transformerconfigs
|
||||
|
||||
Write a plugin when changing [generator options]
|
||||
or [transformer configs] doesn't meet your needs.
|
||||
@@ -53,7 +56,7 @@ The value of each entry in a `resources`,
|
||||
relative path to a YAML file, or a path or URL
|
||||
to a [kustomization].
|
||||
|
||||
[kustomization]: glossary.md#kustomization
|
||||
[kustomization]: ../glossary.md#kustomization
|
||||
|
||||
In the former case the YAML is read from disk directly,
|
||||
and in the latter case a kustomization is performed,
|
||||
@@ -76,7 +79,7 @@ generators:
|
||||
|
||||
Given this, the kustomization process would expect to
|
||||
find a file called `chartInflator.yaml` in the
|
||||
kustomization [root](glossary.md#kustomization-root).
|
||||
kustomization [root](../glossary.md#kustomization-root).
|
||||
|
||||
This is the _plugin's configuration file_.
|
||||
|
||||
@@ -93,7 +96,7 @@ chartName: minecraft
|
||||
__The `apiVersion` and `kind` fields are
|
||||
used to locate the plugin.__
|
||||
|
||||
[k8s object]: glossary.md#kubernetes-style-object
|
||||
[k8s object]: ../glossary.md#kubernetes-style-object
|
||||
|
||||
> Thus, these fields are required. They are also
|
||||
> required because a kustomize plugin
|
||||
@@ -103,9 +106,9 @@ To get the plugin ready to generator or transform,
|
||||
it is given the entire contents of the
|
||||
configuration file.
|
||||
|
||||
[NameTransformer]: ../plugin/builtin/prefixsuffixtransformer/PrefixSuffixTransformer_test.go
|
||||
[ChartInflator]: ../plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
|
||||
[plugins]: ../plugin/builtin
|
||||
[NameTransformer]: ../../plugin/builtin/prefixsuffixtransformer/PrefixSuffixTransformer_test.go
|
||||
[ChartInflator]: ../../plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
|
||||
[plugins]: ../../plugin/builtin
|
||||
|
||||
For more examples of plugin configuration YAML,
|
||||
browse the unit tests below the [plugins] root,
|
||||
@@ -209,9 +212,9 @@ provided in the kustomization file).
|
||||
> 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
|
||||
[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
|
||||
|
||||
@@ -271,10 +274,10 @@ file to be added to the `generators` or
|
||||
`transformers` field in the kustomization file.
|
||||
Do one or the other or both as desired.
|
||||
|
||||
[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
|
||||
[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
|
||||
@@ -287,7 +290,7 @@ Do one or the other or both as desired.
|
||||
`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).
|
||||
* All the builtin plugins [here](../../plugin/builtin).
|
||||
User authored plugins are
|
||||
on the same footing as builtin operations.
|
||||
|
||||
229
docs/plugins/execPluginGuidedExample.md
Normal file
229
docs/plugins/execPluginGuidedExample.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Exec plugin on linux in 60 seconds
|
||||
|
||||
This is a (no reading) 60 second copy/paste guided
|
||||
example. Full plugin docs [here](README.md).
|
||||
|
||||
This demo writes and uses a somewhat ridiculous
|
||||
_exec_ plugin (written in bash) that generates a
|
||||
`ConfigMap`.
|
||||
|
||||
This is a guide to try it without damaging your
|
||||
current setup.
|
||||
|
||||
#### requirements
|
||||
|
||||
* linux, git, curl, Go 1.12
|
||||
|
||||
|
||||
## Make a place to work
|
||||
|
||||
```
|
||||
DEMO=$(mktemp -d)
|
||||
```
|
||||
|
||||
## Create a kustomization
|
||||
|
||||
Make a kustomization directory to
|
||||
hold all your config:
|
||||
|
||||
```
|
||||
MYAPP=$DEMO/myapp
|
||||
mkdir -p $MYAPP
|
||||
```
|
||||
|
||||
Make a deployment config:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Make a service config:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/service.yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: the-service
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8666
|
||||
targetPort: 8080
|
||||
EOF
|
||||
```
|
||||
|
||||
Now make a config file for the plugin
|
||||
you're about to write.
|
||||
|
||||
This config file is just another k8s resource
|
||||
object. The values of its `apiVersion` and `kind`
|
||||
fields are used to _find_ the plugin code on your
|
||||
filesystem (more on this later).
|
||||
|
||||
```
|
||||
cat <<'EOF' >$MYAPP/cmGenerator.yaml
|
||||
apiVersion: myDevOpsTeam
|
||||
kind: SillyConfigMapGenerator
|
||||
metadata:
|
||||
name: whatever
|
||||
argsOneLiner: Bienvenue true
|
||||
EOF
|
||||
```
|
||||
|
||||
Finally, make a kustomization file
|
||||
referencing all of the above:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
generators:
|
||||
- cmGenerator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Review the files
|
||||
```
|
||||
ls -C1 $MYAPP
|
||||
```
|
||||
|
||||
|
||||
## Make a home for plugins
|
||||
|
||||
Plugins must live in a particular place for
|
||||
kustomize to find them.
|
||||
|
||||
This demo will use the ephemeral directory:
|
||||
|
||||
```
|
||||
PLUGIN_ROOT=$DEMO/kustomize/plugin
|
||||
```
|
||||
|
||||
The plugin config defined above in
|
||||
`$MYAPP/cmGenerator.yaml` specifies:
|
||||
|
||||
> ```
|
||||
> apiVersion: myDevOpsTeam
|
||||
> kind: SillyConfigMapGenerator
|
||||
> ```
|
||||
|
||||
This means the plugin must live in a directory
|
||||
named:
|
||||
|
||||
```
|
||||
MY_PLUGIN_DIR=$PLUGIN_ROOT/myDevOpsTeam/sillyconfigmapgenerator
|
||||
|
||||
mkdir -p $MY_PLUGIN_DIR
|
||||
```
|
||||
|
||||
The directory name is the plugin config's
|
||||
_apiVersion_ followed by its lower-cased _kind_.
|
||||
|
||||
A plugin gets its own directory to hold itself,
|
||||
its tests and any supplemental data files it
|
||||
might need.
|
||||
|
||||
## Create the plugin
|
||||
|
||||
There are two kinds of plugins, _exec_ and _Go_.
|
||||
|
||||
Make an _exec_ plugin, installing it to the
|
||||
correct directory and file name. The file name
|
||||
must match the plugin's _kind_ (in this case,
|
||||
`SillyConfigMapGenerator`):
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
By definition, an _exec_ plugin must be executable:
|
||||
|
||||
```
|
||||
chmod a+x $MY_PLUGIN_DIR/SillyConfigMapGenerator
|
||||
```
|
||||
|
||||
## Download kustomize 3.0.0
|
||||
|
||||
```
|
||||
mkdir -p $DEMO/bin
|
||||
gh=https://github.com/kubernetes-sigs/kustomize/releases/download
|
||||
url=$gh/v3.0.0-pre/kustomize_3.0.0-pre_linux_amd64
|
||||
curl -o $DEMO/bin/kustomize -L $url
|
||||
chmod u+x $DEMO/bin/kustomize
|
||||
```
|
||||
|
||||
## Review the layout
|
||||
|
||||
```
|
||||
tree $DEMO
|
||||
```
|
||||
|
||||
## Build your app, using the plugin:
|
||||
|
||||
```
|
||||
XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
|
||||
```
|
||||
|
||||
Above, if you had set
|
||||
|
||||
> ```
|
||||
> PLUGIN_ROOT=$HOME/.config/kustomize/plugin
|
||||
> ```
|
||||
|
||||
there would be no need to use `XDG_CONFIG_HOME` in the
|
||||
_kustomize_ command above.
|
||||
|
||||
308
docs/plugins/goPluginGuidedExample.md
Normal file
308
docs/plugins/goPluginGuidedExample.md
Normal file
@@ -0,0 +1,308 @@
|
||||
# Go Plugin Guided Example for Linux
|
||||
|
||||
This is a (no reading) 60 second copy/paste guided
|
||||
example. Full plugin docs [here](README.md).
|
||||
|
||||
[SopsEncodedSecrets repository]: https://github.com/monopole/sopsencodedsecrets
|
||||
[Go plugin]: https://golang.org/pkg/plugin
|
||||
|
||||
This demo uses a Go plugin, `SopsEncodedSecrets`,
|
||||
that lives in the [sopsencodedsecrets repository].
|
||||
This is an inprocess [Go plugin], not an
|
||||
sub-process exec plugin that happens to be written
|
||||
in Go (which is another option for Go authors).
|
||||
|
||||
This is a guide to try it without damaging your
|
||||
current setup.
|
||||
|
||||
#### requirements
|
||||
|
||||
* linux, git, curl, Go 1.12
|
||||
* Google cloud (gcloud) install
|
||||
* a Google account (will use Google kms -
|
||||
volunteers needed to convert to a GPG example).
|
||||
|
||||
## Make a place to work
|
||||
|
||||
```
|
||||
DEMO=$(mktemp -d)
|
||||
```
|
||||
|
||||
## Install kustomize
|
||||
|
||||
Need v3.0.0 for what follows:
|
||||
|
||||
```
|
||||
GOBIN=$DEMO/bin go get sigs.k8s.io/kustomize/v3/cmd/kustomize@v3.0.0-pre
|
||||
```
|
||||
|
||||
## Make a home for plugins
|
||||
|
||||
A kustomize plugin is fully determined by
|
||||
its configuration file and source code.
|
||||
|
||||
[required fields]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
|
||||
|
||||
Kustomize plugin configuration files are formatted
|
||||
as kubernetes resource objects, meaning
|
||||
`apiVersion`, `kind` and `metadata` are [required
|
||||
fields] in these config files.
|
||||
|
||||
The kustomize program reads the config file
|
||||
(because the config file name appears in the
|
||||
`generators` or `transformers` field in the
|
||||
kustomization file), then locates the Go plugin's
|
||||
object code at the following location:
|
||||
|
||||
> ```
|
||||
> $XGD_CONFIG_HOME/kustomize/plugin/$apiVersion/$lKind/$kind.so
|
||||
> ```
|
||||
|
||||
where `lKind` holds the lowercased kind. The
|
||||
plugin is then loaded and fed its config, and the
|
||||
plugin's output becomes part of the overall
|
||||
`kustomize build` process.
|
||||
|
||||
The same plugin might be used multiple times in
|
||||
one kustomize build, but with different config
|
||||
files. Also, kustomize might customize config
|
||||
data before sending it to the plugin, for whatever
|
||||
reason. For these reasons, kustomize owns the
|
||||
mapping between plugins and config data; it's not
|
||||
left to plugins to find their own config.
|
||||
|
||||
This demo will house the plugin it uses at the
|
||||
ephemeral directory
|
||||
|
||||
```
|
||||
PLUGIN_ROOT=$DEMO/kustomize/plugin
|
||||
```
|
||||
|
||||
and ephemerally set `XGD_CONFIG_HOME` on a command
|
||||
line below.
|
||||
|
||||
### What apiVersion and kind?
|
||||
|
||||
At this stage in the development of kustomize
|
||||
plugins, plugin code doesn't know or care what
|
||||
`apiVersion` or `kind` appears in the config file
|
||||
sent to it.
|
||||
|
||||
The plugin could check these fields, but it's the
|
||||
remaining fields that provide actual configuration
|
||||
data, and at this point the successful parsing of
|
||||
these other fields are the only thing that matters
|
||||
to a plugin.
|
||||
|
||||
This demo uses a plugin called _SopsEncodedSecrets_,
|
||||
and it lives in the [SopsEncodedSecrets repository].
|
||||
|
||||
Somewhat arbitrarily, we'll chose to install
|
||||
this plugin with
|
||||
|
||||
```
|
||||
apiVersion=mygenerators
|
||||
kind=SopsEncodedSecrets
|
||||
```
|
||||
|
||||
### Define the plugin's home dir
|
||||
|
||||
By convention, the ultimate home of the plugin
|
||||
code and supplemental data, tests, documentation,
|
||||
etc. is the lowercase form of its kind.
|
||||
|
||||
```
|
||||
lKind=$(echo $kind | awk '{print tolower($0)}')
|
||||
```
|
||||
|
||||
### Download the SopsEncodedSecrets plugin
|
||||
|
||||
In this case, the repo name matches the lowercase
|
||||
kind already, so we just clone the repo and get
|
||||
the proper directory name automatically:
|
||||
|
||||
```
|
||||
mkdir -p $PLUGIN_ROOT/${apiVersion}
|
||||
cd $PLUGIN_ROOT/${apiVersion}
|
||||
git clone git@github.com:monopole/sopsencodedsecrets.git
|
||||
```
|
||||
|
||||
Remember this directory:
|
||||
|
||||
```
|
||||
MY_PLUGIN_DIR=$PLUGIN_ROOT/${apiVersion}/${lKind}
|
||||
```
|
||||
|
||||
### Try the plugin's own test
|
||||
|
||||
Plugins may come with their own tests.
|
||||
This one does, and it hopefully passes:
|
||||
|
||||
```
|
||||
cd $MY_PLUGIN_DIR
|
||||
go test SopsEncodedSecrets_test.go
|
||||
```
|
||||
|
||||
Build the object code for use by kustomize:
|
||||
|
||||
```
|
||||
cd $MY_PLUGIN_DIR
|
||||
go build -buildmode plugin -o ${kind}.so ${kind}.go
|
||||
```
|
||||
|
||||
This step may succeed, but kustomize might
|
||||
ultimately fail to load the plugin because of
|
||||
dependency [skew].
|
||||
|
||||
[skew]: https://github.com/kubernetes-sigs/kustomize/blob/master/docs/plugins.md#caveats
|
||||
[used in this demo]: #install-kustomize
|
||||
|
||||
On load failure
|
||||
|
||||
* be sure to build the plugin with the same
|
||||
version of Go (`go1.12`) on the same `$GOOS`
|
||||
(`linux`) and `$GOARCH` (`amd64`) used to build
|
||||
the kustomize being [used in this demo].
|
||||
|
||||
* change the plugin's dependencies in `go.mod` to
|
||||
match those used to build kustomize (check the
|
||||
`go.mod` used in the tagged commit).
|
||||
|
||||
Lacking tools and metadata to allow this to be
|
||||
automated, there won't be a Go plugin ecosystem.
|
||||
|
||||
Kustomize has adopted a Go plugin architecture as
|
||||
to ease accept new generators and transformers
|
||||
(just write a plugin), and to be sure that native
|
||||
operations (also constructed and tested as
|
||||
plugins) are compartmentalized, orderable and
|
||||
reusable instead of bizarrely woven throughout the
|
||||
code as a individual special cases.
|
||||
|
||||
## Create a kustomization
|
||||
|
||||
Make a kustomization directory to
|
||||
hold all your config:
|
||||
|
||||
```
|
||||
MYAPP=$DEMO/myapp
|
||||
mkdir -p $MYAPP
|
||||
```
|
||||
|
||||
Make a config file for the SopsEncodedSecrets plugin.
|
||||
|
||||
Its `apiVersion` and `kind` allow the plugin to be
|
||||
found:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/secGenerator.yaml
|
||||
apiVersion: ${apiVersion}
|
||||
kind: ${kind}
|
||||
metadata:
|
||||
name: forbiddenValues
|
||||
namespace: production
|
||||
file: myEncryptedData.yaml
|
||||
keys:
|
||||
- ROCKET
|
||||
- CAR
|
||||
EOF
|
||||
```
|
||||
|
||||
This plugin expects to find more data in
|
||||
`myEncryptedData.yaml`; we'll get to that shortly.
|
||||
|
||||
Make a kustomization file referencing the plugin
|
||||
config:
|
||||
|
||||
```
|
||||
cat <<EOF >$MYAPP/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
generators:
|
||||
- secGenerator.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Now for the hard part. Generate the real encrypted data.
|
||||
|
||||
|
||||
### Assure you have a Google Cloud sops key ring.
|
||||
|
||||
We're going to use [sops](https://github.com/mozilla/sops) to encode a file.
|
||||
|
||||
Try this:
|
||||
|
||||
```
|
||||
gcloud kms keys list --location global --keyring sops
|
||||
```
|
||||
|
||||
If it succeeds, presumably you've already
|
||||
created keys and placed them in a keyring called `sops`.
|
||||
If not, do this:
|
||||
|
||||
```
|
||||
gcloud kms keyrings create sops --location global
|
||||
gcloud kms keys create sops-key --location global \
|
||||
--keyring sops --purpose encryption
|
||||
```
|
||||
|
||||
Extract your keyLocation for use below:
|
||||
```
|
||||
keyLocation=$(\
|
||||
gcloud kms keys list --location global --keyring sops |\
|
||||
grep GOOGLE | cut -d " " -f1)
|
||||
echo $keyLocation
|
||||
```
|
||||
|
||||
### Install `sops`
|
||||
|
||||
```
|
||||
GOBIN=$DEMO/bin go install go.mozilla.org/sops/cmd/sops
|
||||
```
|
||||
|
||||
### Create data encrypted with your Google Cloud key
|
||||
|
||||
Create raw data to encrypt:
|
||||
```
|
||||
cat <<EOF >$MYAPP/myClearData.yaml
|
||||
VEGETABLE: carrot
|
||||
ROCKET: saturn-v
|
||||
FRUIT: apple
|
||||
CAR: dymaxion
|
||||
EOF
|
||||
|
||||
```
|
||||
|
||||
Encrypt the data into file the plugin wants to read:
|
||||
|
||||
```
|
||||
$DEMO/bin/sops --encrypt \
|
||||
--gcp-kms $keyLocation \
|
||||
$MYAPP/myClearData.yaml >$MYAPP/myEncryptedData.yaml
|
||||
```
|
||||
|
||||
|
||||
Review the files
|
||||
```
|
||||
tree $DEMO
|
||||
```
|
||||
|
||||
|
||||
## Build your app, using the plugin:
|
||||
|
||||
```
|
||||
XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
|
||||
```
|
||||
|
||||
This should emit a kubernetes secret, with
|
||||
encrypted data for the names `ROCKET` and `CAR`.
|
||||
|
||||
Above, if you had set
|
||||
|
||||
> ```
|
||||
> PLUGIN_ROOT=$HOME/.config/kustomize/plugin
|
||||
> ```
|
||||
|
||||
there would be no need to use `XDG_CONFIG_HOME` in the
|
||||
_kustomize_ command above.
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
[bases]: glossary.md#base
|
||||
[_base_]: glossary.md#base
|
||||
[kustomize inventory object documentation]: inventory_object.md
|
||||
[kustomize plugin documentation]: plugins.md
|
||||
[kustomize plugin documentation]: plugins
|
||||
[root]: glossary.md#kustomization-root
|
||||
[transformer configs]: ../examples/transformerconfigs
|
||||
[v1.0.9]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v1.0.9
|
||||
|
||||
51
docs/v3.0.0.md
Normal file
51
docs/v3.0.0.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# kustomize 3.0.0
|
||||
|
||||
This release is [v2.1.0](v2.1.0.md), with some
|
||||
post v2.1.0 bugs fixed and a `v3` in Go package
|
||||
paths.
|
||||
|
||||
The `v3` puts plugin developers (both _Go_ plugin
|
||||
authors and _exec_ plugin authors who happen to
|
||||
use Go) on a solid footing.
|
||||
|
||||
|
||||
### Go Module implications
|
||||
|
||||
[doc]: https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher
|
||||
|
||||
Per the Go modules [doc], a release that's already
|
||||
tagged v2 or higher should increment the major
|
||||
version when performing their first Go
|
||||
module-based release.
|
||||
|
||||
This advice applies to kustomize, since it was
|
||||
already at major version 2 when switching to Go
|
||||
modules.
|
||||
|
||||
[versioning policy]: versioningPolicy.md
|
||||
|
||||
The other reason for `v3` is that the `go` tool
|
||||
assumes Go modules obey semantic versioning, which
|
||||
means packages used in v2.1 should have the same
|
||||
API as packages in v2.0.
|
||||
|
||||
This is not the case in kustomize. Historically,
|
||||
kustomize's [versioning policy] has only addressed
|
||||
the command line tool's behavior and the fields in
|
||||
a kustomization file. The underlying packages
|
||||
were an implementation detail, avaiable for use at
|
||||
the author's risk.
|
||||
|
||||
With the introduction of plugins, the packages -
|
||||
in particular `loader` and `resmap` - become part
|
||||
of an API formally exposed to plugin authors, so
|
||||
the API changes must be respected.
|
||||
|
||||
Over time, _informed by package use_, the API
|
||||
surface should shrink, but such shrinkage will
|
||||
require a major version increment.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* [kustomization.yaml](kustomization.yaml) - 包含
|
||||
[kustomization](../glossary.md#kustomization) 所有字段的示例文件。
|
||||
|
||||
* [插件](../plugins.md) - 使用自定义的资源生成器和资源转换器来拓展 kustomize 功能。
|
||||
* [插件](../plugins) - 使用自定义的资源生成器和资源转换器来拓展 kustomize 功能。
|
||||
|
||||
* [工作流](workflows.md) - 使用定制及使用现成配置使用的一些步骤。
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[stable chart]: https://github.com/helm/charts/tree/master/stable
|
||||
[Helm charts]: https://github.com/helm/charts
|
||||
[_minecraft_]: https://github.com/helm/charts/tree/master/stable/minecraft
|
||||
[plugin]: ../docs/plugins.md
|
||||
[plugin]: ../docs/plugins
|
||||
|
||||
[Helm charts] aren't natively read by kustomize, but
|
||||
kustomize has a [plugin] system that allows one to
|
||||
|
||||
@@ -126,7 +126,7 @@ them, etc.
|
||||
## Secret values from anywhere
|
||||
|
||||
A general alternative is to enshrine secret
|
||||
value generation in a [plugin](../docs/plugins.md).
|
||||
value generation in a [plugin](../docs/plugins).
|
||||
|
||||
The values can then come in via, say, an
|
||||
authenticated and authorized RPC to a password
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[kubeval]: https://github.com/instrumenta/kubeval
|
||||
[plugin]: ../../docs/plugins.md
|
||||
[plugin]: ../../docs/plugins
|
||||
|
||||
kustomize doesn't validate either its input or
|
||||
output beyond the validation provided by the
|
||||
|
||||
Reference in New Issue
Block a user