Set Up LocaL Development Envrionment
Overview¶
You have a kubernetes cluster, and you want to develop a mutating webhook.
You can develop the code locally and deploy it into the cluster to test and debug the codes in the container.
However, if any bugs are found, you need to:
- edit the codes
- rebuild the image
- deploy it into the cluster
- and test again.
Quite annoying.🤬🤬
Instead of that, a better choice would be:
- run a server (flask or fastapi) locally on your computer
- the kubernetes sends the admission review requests to this server.
Then you can test, debug and update codes totally in your local environment😍.
There are two ways to achieve this:
- Set up the service and endpoint to point to external ip. External Service↩️
Warning
Webhooks are required to support TLS. You need setup the certificates all yourself!
- Another way would be the approach in this tutorial.
We setup all the kubernetes resources just as if we are really deploying a production-ready webhook and the certificates are automatically managed by the cert-manager.
Just one difference, instead of deploying the webhook container with a webhook image, we use an nginx image instead as a reverse proxy and pass the requests to our server in the local envrionment.
The benefit of this is: after you have developed and tested the webhook codes, you can build the image and simply replace the nginx deployment, the webhook will work in no time. And you can switch back to local development at anytime you want.
Prepare YAMLs¶
Let's look at the YAMLs
apiVersion: v1
kind: Namespace
metadata:
name: webhook-test
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: webhook-cert
namespace: webhook-test
spec:
commonName: webhook-service.webhook-test.svc
dnsNames:
- webhook-service.webhook-test.svc
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: webhook-service-cert
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: webhook-test
spec:
selfSigned: {}
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
annotations:
cert-manager.io/inject-ca-from: webhook-test/webhook-cert
name: webhook-test
webhooks:
- admissionReviewVersions:
- v1beta1
clientConfig:
caBundle: Cg==
service:
name: webhook-service
namespace: webhook-test
path: /mutate-pods
failurePolicy: Fail
name: webhook-service.pod.mutator
objectSelector:
matchLabels:
mutate: "true"
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- pods
sideEffects: None
apiVersion: v1
kind: Service
metadata:
name: webhook-service
namespace: webhook-test
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
selector:
app: webhook-test
❗️❗️❗️Replace the IP with your own computer's.
apiVersion: v1
kind: ConfigMap
metadata:
namespace: webhook-test
name: nginx-conf
data:
nginx.conf: |
user nginx;
worker_processes 3;
events {
worker_connections 10240;
}
http {
ssl_certificate /etc/ssl/tls.crt;
ssl_certificate_key /etc/ssl/tls.key;
ssl_protocols TLSv1.2 TLSv1.3;
server {
listen 443 ssl;
location / {
proxy_pass http://192.168.10.10:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
}
}
}
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: webhook-test
name: webhook-reverse-proxy
labels:
app: webhook-test
spec:
replicas: 1
selector:
matchLabels:
app: webhook-test
template:
metadata:
labels:
app: webhook-test
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 443
volumeMounts:
- mountPath: /etc/ssl
name: cert
readOnly: true
- name: nginx-conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
terminationGracePeriodSeconds: 5
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-service-cert
- name: nginx-conf
configMap:
name: nginx-conf
items:
- key: nginx.conf
path: nginx.conf
Save all the YAMLs in a directory webhook
.
Install¶
$ kubectl apply -f webhook.yaml
namespace/webhook-test created
certificate.cert-manager.io/webhook-cert created
issuer.cert-manager.io/selfsigned-issuer created
mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook-test created
service/webhook-service created
configmap/nginx-conf created
deployment.apps/webhook-reverse-proxy created
Uninstall¶
$ kubectl delete -f webhook/
namespace "webhook-test" deleted
certificate.cert-manager.io "webhook-cert" deleted
issuer.cert-manager.io "selfsigned-issuer" deleted
mutatingwebhookconfiguration.admissionregistration.k8s.io "webhook-test" deleted
service "webhook-service" deleted
configmap "nginx-conf" deleted
deployment.apps "webhook-reverse-proxy" deleted