Slide 1

Slide 1 text

Kubernetes Webhooks Terin Stock @terinjokes

Slide 2

Slide 2 text

Extending Kubernetes 1. Controllers 2. Webhooks 3. Aggregation Layer

Slide 3

Slide 3 text

Learn more about extending Kubernetes Friday 14:45 - 15:20 in Room C1-M0

Slide 4

Slide 4 text

What are Webhooks? ● Allows for dynamic adminission control without plugins ● Configurable at runtime, without restarting control plane ● Implemented with an HTTP API ● Beta, and on by default in ≥1.9

Slide 5

Slide 5 text

Types of Webhooks 1. Mutating Webhook a. Allows for mutating resources on admission b. Runs serially, each webhook can mutate 2. Validating Webhook a. Only allows for validating resources b. Runs in parallel; if any reject, the request fails

Slide 6

Slide 6 text

Example ● We have different types of namespaces ○ Production namespaces, running critical production tasks ○ Development namespaces, running work-in-progress services ● Quality of Service between the namespaces are different: ○ Production namespaces should be Guaranteed or Burstable ○ Development namespaces should be Best Effort ● Production services should be deployable in development namespaces without changing resource requests.

Slide 7

Slide 7 text

Quality of Service QoS of a Pod depends on the resource limits and requests in the Pod spec containers: - name: example resources: limits: memory: "200Mi" cpu: "700m" requests: memory: "200Mi" cpu: "700m"

Slide 8

Slide 8 text

Creating a Webhook apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: resource-quotas webhooks: - name: resource-quotas clientConfig: caBundle: ${PEM_ENCODED_BUNDLE} service: namespace: default name: resource-quotas-wh path: "/pods" rules: - operations: [ "CREATE" ] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] namespaceSelector: matchLabels: type: development

Slide 9

Slide 9 text

Woah, What? Break it down We’re creating a Mutating Webhook apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration The configuration for a Validating Webhook is largely the same

Slide 10

Slide 10 text

Example Webhook: ClientConfig Defines what service Kubernetes will send webhooks requests to clientConfig: caBundle: ${PEM_ENCODED_BUNDLE} service: namespace: default name: resource-quotas-wh path: "/pods" The service must listen on port 443, and use an HTTPS certificate matching the caBundle

Slide 11

Slide 11 text

Example Webhook: Rules Rules defines when Kubernetes will reach out to the Webhook rules: - operations: [ "CREATE" ] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"]

Slide 12

Slide 12 text

Example Webhook: Namespaces Finally, namespaceSelector restricts the rules to namespaces that match the labels namespaceSelector: matchLabels: type: development

Slide 13

Slide 13 text

Example Webhook http.HandleFunc("/pods", func(rw http.ResponseWriter, r *http.Request) { // decode request as v1beta1.AdmissionReview var review v1beta1.AdmissionReview json.NewDecoder(r.Body).Decode(&review) […] })

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Example Webhook […] // investigate review.Request var pod v1.Pod json.Unmarshal(review.Request.Object.Raw, &pod) // remove each resources from each containers for i, c := range pod.Spec.Containers { c.Resources = v1.ResourceRequirements{} pod.Spec.Containers[i] = c } […]

Slide 16

Slide 16 text

Example Webhook […] // marshal back into JSON resp, _ := json.Marshal(pod) […]

Slide 17

Slide 17 text

JSONPatch Kubernetes uses JSONPatch, defined by RFC6902, to describe webhook mutations [ { "op": "remove", "path": "/a/b/c" }, { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }, { "op": "move", "from": "/a/b/c", "path": "/a/b/d" }, { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" } ] The github.com/mattbaird/jsonpatch package works well for simple cases

Slide 18

Slide 18 text

Example Webhook […] // create the JSONPatch patch, _ := jsonpatch.CreatePatch(review.Request.Object.Raw, resp) p, _ := json.Marshal(patch) pt := v1beta1.PatchTypeJSONPatch response := &v1beta1.AdmissionResponse{ UID: review.Request.UID, Allowed: true, Patch: p, PatchType: &pt, } […]

Slide 19

Slide 19 text

Example Webhook […] res, _ := json.Marshal(&v1beta1.AdmissionReview{ Response: response, }) rw.Header().Set("Content-Type", "application/json") rw.Write(res) })

Slide 20

Slide 20 text

Other Webhooks ● Add "sidecar" containers to new pods ○ Conduit sidecar ○ Jaeger agent ○ Prometheus exporter ● Deployment templating

Slide 21

Slide 21 text

Kubernetes Webhooks ● Extending Kubernetes Admission Control ○ without being a plugin ○ deployable and configurable at runtime ● Simple HTTP API ● Extremely powerful

Slide 22

Slide 22 text

Learn more about extending Kubernetes Friday 14:45 - 15:20 in Room C1-M0