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