k8s-label-rules-webhook
k8s-label-rules-webhook copied to clipboard
A validating admission webhook to ensure compliant labels in your k8s cluster
k8s-label-rules-webhook
Enforce standards for labels of resources being created in your k8s cluster
Table of Contents
-
Usage
-
Docker
-
Volume mount your
rules.yaml
file - Build your own docker image
-
Volume mount your
-
Kubernetes
- Deploy webhook application
- Deploy webhook application (TLS)
- Deploy admission webhook
-
Docker
-
Features
- Hot reloading of ruleset
- Rule validation
- Easily view loaded ruleset
- Prometheus Metrics
- Configuration
-
Development
- Build
- Run
- Test
- Changelog
- Troubleshooting
Usage
Start by creating a rules.yaml
file containing rules for labels you require for your cluster resources to have along with a regex pattern for the values of the labels.
Any rules specified in the rulseset will be required on resources to which you configure the admission webhook to fire on. View the kubernetes deployment section.
rules:
- name: require-phone-number
key: phone-number
value:
regex: "[0-9]{3}-[0-9]{3}-[0-9]{4}" # 555-555-5555
- name: require-owner
key: owner
value:
regex: ".*" # Any pattern matches, Just ensure a label of "owner" is set
IMPORTANT NOTE: Invalid regex for a given rule will make the rule default to .* which will allow any label value, but will still require the label to be present
Once you have your ruleset, you can deploy the webhook several different ways.
Docker
Volume mount your rules.yaml
file
docker run -d --name k8s-label-rules-webhook \
-p 8080:8080 \
-v $PWD/rules.yaml:/rules.yaml \
circa10a/k8s-label-rules-webhook
Build your own docker image
FROM circa10a/k8s-label-rules-webhook
COPY rules.yaml /
Kubernetes
Deploy webhook application
Kubernetes admission webhooks require https
apiVersion: apps/v1
kind: Deployment
metadata:
name: label-rules-webhook
labels:
app: label-rules-webhook
spec:
replicas: 1
selector:
matchLabels:
app: label-rules-webhook
template:
metadata:
labels:
app: label-rules-webhook
spec:
containers:
- name: label-rules-webhook
image: circa10a/k8s-label-rules-webhook
volumeMounts:
- name: label-rules
mountPath: /rules.yaml
subPath: rules.yaml
readinessProbe:
httpGet:
path: /rules
port: gin-port
initialDelaySeconds: 5
periodSeconds: 15
livenessProbe:
httpGet:
path: /rules
port: gin-port
initialDelaySeconds: 5
periodSeconds: 15
ports:
- name: gin-port
containerPort: 8080
volumes:
- name: label-rules
configMap:
name: label-rules
---
apiVersion: v1
kind: ConfigMap
metadata:
name: label-rules
data:
rules.yaml: |
rules:
- name: require-phone-number
key: phone-number
value:
regex: "[0-9]{3}-[0-9]{3}-[0-9]{4}"
- name: require-number
key: number
value:
regex: "[0-1]{1}"
---
apiVersion: v1
kind: Service
metadata:
name: label-rules-webhook-service
spec:
selector:
app: label-rules-webhook
ports:
- protocol: TCP
port: 8080
targetPort: gin-port
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: label-rules-webhook-ingress
spec:
backend:
serviceName: label-rules-webhook-service
servicePort: 8080
Deploy webhook application (TLS)
To have the web server listen on https, you need to supply a certificate and a key in conjunction with the appropriate configuration options.
Here's an example deployment which supplies a cert, key and enables TLS in the application.
Note: The TLS example only works in the
default
namespace. The subject alt name in the certificate is label-rules-webhook-service.default.svc Note: The default https port is8443
Deploy admission webhook
More info on kubernetes admission webhooks
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: label-rules-webhook
webhooks:
- name: my.application.domain
clientConfig:
clientConfig:
caBundle: <base64 encoded cert bundle>
service:
namespace: "default"
name: "label-rules-webhook-service"
port: 8443
rules:
- operations:
- "CREATE"
- "UPDATE"
apiGroups:
- "apps"
apiVersions:
- "v1"
- "v1beta1"
resources:
- "deployments"
- "replicasets"
failurePolicy: Fail # Ignore, Fail
Features
Checkout the swagger api docs at /swagger/index.html
Hot reloading of ruleset
Update the rules.yaml
file used by your deployed instance then send a POST
request to /reload
to reload the rules into memory without downtime.
Rule validation
The regex supplied to each rule is compiled when the application starts and any problems are logged.
You can access the /validate
endpoint via GET
request to view any issues with the current ruleset that is loaded.
Easily view loaded ruleset
Access the /rules
endpoint via GET
request to see the current rules loaded.
Prometheus Metrics
Prometheus metrics are enabled by default and are available at the /metrics
endpoint. Simply unset the METRICS
environment variable to disable.
Configuration
Name | Description | Environment Variable | Command Line Argument | Required | Default |
Gin mode | Runs web server in production or debug mode | GIN_MODE |
None | false |
release |
Port | Port for web server to listen on | PORT |
None | false |
8080 |
Metrics | Enables prometheus metrics on /metrics (unset for false) |
METRICS |
--metrics |
false |
true |
Rules | File containing user defined ruleset(default looks to ./rules.yaml ) |
None | --file |
true |
./rules.yaml |
TLS | Start web server listening on HTTPS | TLS_ENABLED |
--tls |
false |
false |
TLS Cert | TLS Certificate file path | TLS_CERT |
--tls-cert |
false |
None |
TLS Key | TLS key file path | TLS_KEY |
--tls-key |
false |
None |
TLS Port | TLS listening port | None | --tls-port |
false |
8443 |
Development
Build
make build
Run
make run
Access via http://localhost:8080
Test
make test
Changelog
Automated under releases
Troubleshooting
Debug web server
Try setting the debug environment variable for the gin web server which is GIN_MODE=debug
.
Rule validation problems
Ensure there are no regex compilation errors by accessing the /validate
endpoint.