Skip to content

Latest commit

 

History

History
333 lines (283 loc) · 7.59 KB

configureBuiltinPlugin.md

File metadata and controls

333 lines (283 loc) · 7.59 KB

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:

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:

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
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:

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:

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:

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.

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
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:

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.