3 min read | by Jordi Prats
Using a webhook we can mutate Kubernetes objects when they are inserted to the cluster. But using a mutating operator can save us the trouble of having to actually code how the object needs to be patched
One of the options is using KubeMod, using a CRD we can configure the mutations we want to happen.
First we need to specify how to identify the object we want to mutate. On this example it will select all the Deployments with the label app=website
apiVersion: api.kubemod.io/v1beta1
kind: ModRule
metadata:
name: website-deployment-mutations
spec:
type: Patch
match:
- select: '$.kind'
matchValue: Deployment
- select: '$.metadata.labels.app'
matchValue: 'website'
patch:
- op: add
path: /metadata/labels/test
value: kubemod
And then what we want to patch, for example, we can add a label as follows:
apiVersion: api.kubemod.io/v1beta1
kind: ModRule
metadata:
name: website-label
spec:
type: Patch
match:
- select: '$.kind'
matchValue: Deployment
- select: '$.metadata.labels.app'
matchValue: 'website'
patch:
- op: add
path: /metadata/labels/test
value: kubemod
Once it is in place, we can now apply the yaml file to create this object. After this if we describe it we will be able to see how KubeMod have added the label automatically:
$ kubectl describe deploy ampa-website
Name: ampa-website
Namespace: pet2cattle
CreationTimestamp: Fri, 02 Jul 2021 13:16:22 +0200
Labels: app=website
app.kubernetes.io/managed-by=halyard
app.kubernetes.io/name=ampa
app.kubernetes.io/part-of=pet2cattle
app.kubernetes.io/version=1.20.8
test=kubemod
This mutating operator can be usefull to modify object that we don't have control over them. We could, for example, inject a sidecar
apiVersion: api.kubemod.io/v1beta1
kind: ModRule
metadata:
name: website-sidecar
spec:
type: Patch
match:
- select: '$.kind'
matchValue: Deployment
- select: '$.metadata.labels.app'
matchValue: 'website'
- select: '$.metadata.labels["app.kubernetes.io/name"]'
matchValue: 'ampa'
- select: '$.metadata.labels["kubemod.sidecar"]'
matchValue: gitsync
negate: true
patch:
- op: add
path: /metadata/labels/kubemod.sidecar
value: gitsync
- op: add
path: '/spec/template/spec/containers/-1'
value: |-
name: gitpull-daemon
image: ampa/website:latest
env:
- name: 'GIT_SSH_COMMAND'
value: 'ssh -i /var/website/keys/ssh.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
command:
- sh
- '-xc'
- 'cd /var/website; while true; do git pull; sleep 2m; done'
Set the resource limits:
apiVersion: api.kubemod.io/v1beta1
kind: ModRule
metadata:
name: website-limits
spec:
type: Patch
match:
- select: '$.kind'
matchValue: Deployment
- select: '$.metadata.labels.app'
matchValue: 'website'
- select: '$.metadata.labels["app.kubernetes.io/name"]'
matchValues:
- website
- adminsite
patch:
- op: replace
select: '$.spec.template.spec.containers[*].resources'
path: '/spec/template/spec/containers/#0/resources'
value: |-
limits:
cpu: "2"
memory: 6000Mi
requests:
cpu: 500m
memory: 5000Mi
Or update any setting, such a environment variable:
apiVersion: api.kubemod.io/v1beta1
kind: ModRule
metadata:
name: website-jmx
spec:
type: Patch
match:
- select: '$.kind'
matchValue: Deployment
- select: '$.metadata.labels.app'
matchValue: 'website'
- select: '$.metadata.labels["app.kubernetes.io/name"]'
matchValues:
- website
- adminsite
- select: '$.spec.template.spec.containers[*].env[*].value'
matchValue: '-XX:MaxRAMPercentage=50.0'
patch:
- op: replace
select: '$.spec.template.spec.containers[*].env[? @.name =~ "JAVA_OPTS"].value'
path: '/spec/template/spec/containers/#0/env/#1/value'
value: '-Xms15G -Xmx15G'
Posted on 27/09/2021