mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-16 17:33:14 +00:00
Example of configuring builtin plugin.
This commit is contained in:
333
examples/configureBuiltinPlugin.md
Normal file
333
examples/configureBuiltinPlugin.md
Normal file
@@ -0,0 +1,333 @@
|
||||
[builtin operations]: ../docs/plugins/builtins.md
|
||||
[builtin plugins]: ../docs/plugins/builtins.md
|
||||
[plugins]: ../docs/plugins
|
||||
[plugin]: ../docs/plugins
|
||||
[fields]: ../docs/fields.md
|
||||
[fields in a kustomization file]: ../docs/fields.md
|
||||
[TransformerConfig]: ../pkg/transformers/config/transformerconfig.go
|
||||
[kustomization]: ../docs/glossary.md#kustomization
|
||||
|
||||
# Customizing kustomize
|
||||
|
||||
The [fields in a kustomization file] allow the user to
|
||||
specify which resource files to use as input, how to
|
||||
_generate_ new resources, and how to _transform_ those
|
||||
resources - add labels, patch them, etc.
|
||||
|
||||
These fields are simple (low argument count) directives.
|
||||
For example, the `commonAnnotations` field demands only a
|
||||
list of _name:value_ pairs.
|
||||
|
||||
If using a field triggers behavior that pleases the user,
|
||||
everyone's happy.
|
||||
|
||||
If not, the user can ask for new behavior to be implemented
|
||||
in kustomize proper (and wait), or the user can write a
|
||||
transformer or generator [plugin]. This latter option
|
||||
generally means writing code; a Go plugin, a Go binary,
|
||||
a C++ binary, a `bash` script - something.
|
||||
|
||||
There's a third option. If one merely wants to tweak
|
||||
behavior that already exists in kustomize, one may be able
|
||||
to do so by just writing some YAML.
|
||||
|
||||
## Configure the builtin plugins
|
||||
|
||||
All of kustomize's [builtin operations] are implemented
|
||||
and usable as plugins.
|
||||
|
||||
Using the fields is convenient and brief, but necessarily
|
||||
specifies only part of the entire plugin specification. The
|
||||
unspecified part is defaulted to what are hopefully
|
||||
generally appealing values.
|
||||
|
||||
If, instead, one invokes the plugins directly using the
|
||||
`transformers` or `generators` field, one can (indeed
|
||||
_must_) specify the entire plugin configuration.
|
||||
|
||||
## Example: field vs plugin
|
||||
|
||||
Define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @testAgainstLatestRelease -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Using the `commonLabels` and `commonAnnotations` fields
|
||||
|
||||
In this simple example, we'll use just two resources: a deployment and a service.
|
||||
|
||||
Define them:
|
||||
|
||||
<!-- @makeRes1 @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment
|
||||
spec:
|
||||
replicas: 10
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: the-container
|
||||
image: monopole/hello:1
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @makeRes2 @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8666
|
||||
targetPort: 8080
|
||||
EOF
|
||||
```
|
||||
|
||||
Now make a kustomization file that causes them
|
||||
to be read and transformed:
|
||||
|
||||
<!-- @makeKustomization @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
|
||||
namePrefix: hello-
|
||||
commonLabels:
|
||||
app: hello
|
||||
commonAnnotations:
|
||||
area: "51"
|
||||
greeting: Take me to your leader
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
And run kustomize:
|
||||
|
||||
<!-- @checkLabel @testAgainstLatestRelease -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
The output will be something like
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> kind: Service
|
||||
> metadata:
|
||||
> annotations:
|
||||
> area: "51"
|
||||
> greeting: Take me to your leader
|
||||
> labels:
|
||||
> app: hello
|
||||
> name: hello-service
|
||||
> spec:
|
||||
> ports:
|
||||
> - port: 8666
|
||||
> protocol: TCP
|
||||
> targetPort: 8080
|
||||
> selector:
|
||||
> app: hello
|
||||
> type: LoadBalancer
|
||||
> ---
|
||||
> apiVersion: apps/v1
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> annotations:
|
||||
> area: "51"
|
||||
> greeting: Take me to your leader
|
||||
> labels:
|
||||
> app: hello
|
||||
> name: hello-deployment
|
||||
> spec:
|
||||
> replicas: 10
|
||||
> selector:
|
||||
> matchLabels:
|
||||
> app: hello
|
||||
> template:
|
||||
> metadata:
|
||||
> annotations:
|
||||
> area: "51"
|
||||
> greeting: Take me to your leader
|
||||
> labels:
|
||||
> app: hello
|
||||
> spec:
|
||||
> containers:
|
||||
> - image: monopole/hello:1
|
||||
> name: the-container
|
||||
> ```
|
||||
|
||||
Let's say we are unhappy with this result.
|
||||
|
||||
We only want the annotations
|
||||
to be applied down in the pod templates,
|
||||
and don't want to see them in the metadata
|
||||
for Service or Deployment.
|
||||
|
||||
We like that the label _app: hello_ ended up in
|
||||
|
||||
- Service `spec.selector`
|
||||
- Deployment `spec.selector.matchLabels`
|
||||
- Deployment `spec.template.metadata.labels`
|
||||
|
||||
as this binds the Service (load balancer) to the pods,
|
||||
and the Deployment itself to its own pods -
|
||||
but we again don't care to see these labels in
|
||||
the metadata for the Service and the Deployment.
|
||||
|
||||
|
||||
### Configuring the builtin plugins instead
|
||||
|
||||
To fine tune this, invoke the same transformations
|
||||
using the plugin approach.
|
||||
|
||||
Change the kustomization file:
|
||||
|
||||
<!-- @makeKustomization @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
|
||||
namePrefix: hello-
|
||||
transformers:
|
||||
- myAnnotator.yaml
|
||||
- myLabeller.yaml
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Then make the two plugin configuration files
|
||||
(`myAnnotator.yaml`, `myLabeller.yaml`)
|
||||
referred to by the `transformers` field above.
|
||||
For details about the fields to specify, see
|
||||
the documentation for the [builtin plugins].
|
||||
|
||||
<!-- @makeAnnotatorPluginConfig @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/myAnnotator.yaml
|
||||
apiVersion: builtin
|
||||
kind: AnnotationsTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
annotations:
|
||||
area: 51
|
||||
greeting: take me to your leader
|
||||
fieldSpecs:
|
||||
- kind: Deployment
|
||||
path: spec/template/metadata/annotations
|
||||
create: true
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @makeLabelPluginConfig @testAgainstLatestRelease -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/myLabeller.yaml
|
||||
apiVersion: builtin
|
||||
kind: LabelTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
labels:
|
||||
app: hello
|
||||
fieldSpecs:
|
||||
- kind: Service
|
||||
path: spec/selector
|
||||
create: true
|
||||
- kind: Deployment
|
||||
path: spec/selector/matchLabels
|
||||
create: true
|
||||
- kind: Deployment
|
||||
path: spec/template/metadata/labels
|
||||
create: true
|
||||
EOF
|
||||
```
|
||||
|
||||
Finally, run kustomize again:
|
||||
|
||||
<!-- @checkLabel @testAgainstLatestRelease -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
The output should resemble the following,
|
||||
with fewer labels and annotations.
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> kind: Service
|
||||
> metadata:
|
||||
> name: hello-service
|
||||
> spec:
|
||||
> ports:
|
||||
> - port: 8666
|
||||
> protocol: TCP
|
||||
> targetPort: 8080
|
||||
> selector:
|
||||
> app: hello
|
||||
> type: LoadBalancer
|
||||
> ---
|
||||
> apiVersion: apps/v1
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: hello-deployment
|
||||
> spec:
|
||||
> replicas: 10
|
||||
> selector:
|
||||
> matchLabels:
|
||||
> app: hello
|
||||
> template:
|
||||
> metadata:
|
||||
> annotations:
|
||||
> area: "51"
|
||||
> greeting: take me to your leader
|
||||
> labels:
|
||||
> app: hello
|
||||
> spec:
|
||||
> containers:
|
||||
> - image: monopole/hello:1
|
||||
> name: the-container
|
||||
> ```
|
||||
|
||||
|
||||
## The old way to do this
|
||||
|
||||
The original (and still functional) way to customize
|
||||
kustomize is to specify a `configurations` field in the
|
||||
kustomization file.
|
||||
|
||||
This field, normally omitted because it overrides hardcoded
|
||||
data, accepts a list of file path arguments. The files, in
|
||||
turn, specify which fields in which k8s objects should be
|
||||
affected by particular builtin transformations. It's a
|
||||
global configuration cutting across transformations, and
|
||||
doesn't effect generators at all.
|
||||
|
||||
At `build` time, the configuration files are unmarshalled
|
||||
into one instance of [TransformerConfig]. This
|
||||
object, _plus_ the field values for `namePrefix`, etc. are
|
||||
fed into the transformation code to build the output.
|
||||
|
||||
The best way to write these custom configuration files is to
|
||||
generate the files from the hardcoded values built into
|
||||
kustomize via these commands:
|
||||
|
||||
> ```
|
||||
> mkdir /tmp/junk
|
||||
> kustomize config save -d /tmp/junk
|
||||
> ```
|
||||
|
||||
One can then edit those file or files, and specify the
|
||||
resulting edited files in a `configurations:`
|
||||
field in a kustomization file used in a `build`.
|
||||
|
||||
Using plugins _completely ignores_ both hard coded
|
||||
tranformer configuration, and any configuration loaded by
|
||||
the `configuration` field.
|
||||
Reference in New Issue
Block a user