Cloud Native 11 min read

Understanding and Implementing Kubernetes Admission Controllers with a Sidecar Injection Example

This article explains the purpose and phases of Kubernetes Admission Controllers, outlines their security, governance, and configuration management benefits, and provides a step‑by‑step guide—including TLS certificate creation, a Go HTTPS webhook server, and MutatingWebhookConfiguration YAML—to inject a sidecar container into pods.

System Architect Go
System Architect Go
System Architect Go
Understanding and Implementing Kubernetes Admission Controllers with a Sidecar Injection Example

Kubernetes Admission Controllers are webhook mechanisms that allow users to modify or validate resource objects before they are persisted to etcd, enabling custom security, governance, and configuration management policies.

The two types of admission webhooks are:

Mutation admission webhook : modifies resource objects.

Validation admission webhook : validates resource objects.

To use an Admission Controller you must ensure the API server has admission plugins enabled, provide TLS/SSL certificates (self‑signed is acceptable), build an HTTPS server that implements the webhook logic, and configure either a MutatingWebhookConfiguration or ValidatingWebhookConfiguration to tell Kubernetes how to communicate with your server.

Sidecar Injection Example

1. Verify admission plugins are enabled

Run the following command to list admission resources:

kubectl api-resources | grep admission

Typical output shows mutatingwebhookconfigurations and validatingwebhookconfigurations , confirming support. Ensure the API server is started with the flag:

--enable-admission-plugins=MutatingAdmissionWebhook,ValidatingAdmissionWebhook

2. Create TLS/SSL certificates

Generate a root CA and a server certificate in a directory such as ~/certs :

Create the root CA: openssl genrsa -des3 -out rootCA.key 4096 openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Create the server certificate signing request and key: openssl genrsa -out mylocal.com.key 2048 openssl req -new -key mylocal.com.key -out mylocal.com.csr

Sign the server certificate with the root CA, specifying the internal IP address: echo subjectAltName = IP:192.168.100.22 > extfile.cnf openssl x509 -req -in mylocal.com.csr \ -CA rootCA.crt -CAkey rootCA.key \ -CAcreateserial -out mylocal.com.crt \ -days 500 -extfile extfile.cnf

After these steps you will have the following files:

rootCA.key : root CA private key

rootCA.crt : root CA certificate

rootCA.srl : serial number file

mylocal.com.key : server private key

mylocal.com.csr : certificate signing request

mylocal.com.crt : server certificate

3. Build a simple HTTPS server in Go

The webhook receives an AdmissionReview request and must return an AdmissionResponse . The example below adds a sidecar container (busybox) to the pod's spec.containers array using a JSONPatch.

package main

import (
    "encoding/json"
    "log"
    "net/http"

    v1 "k8s.io/api/admission/v1"
    corev1 "k8s.io/api/core/v1"
)

// patchOperation is an operation of a JSON patch, see https://tools.ietf.org/html/rfc6902 .
type patchOperation struct {
    Op    string      `json:"op"`
    Path  string      `json:"path"`
    Value interface{} `json:"value,omitempty"`
}

var (
    certFile = "/Users/wy/certs/mylocal.com.crt"
    keyFile  = "/Users/wy/certs/mylocal.com.key"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        defer req.Body.Close()
        var admissionReview v1.AdmissionReview
        err := json.NewDecoder(req.Body).Decode(&admissionReview)
        if err != nil {
            log.Fatal(err)
        }

        var patches []patchOperation
        patches = append(patches, patchOperation{
            Op:   "add",
            Path: "/spec/containers/-",
            Value: &corev1.Container{
                Image: "busybox",
                Name:  "sidecar",
            },
        })
        patchBytes, err := json.Marshal(patches)
        if err != nil {
            log.Fatal(err)
        }

        var PatchTypeJSONPatch v1.PatchType = "JSONPatch"
        admissionReview.Response = &v1.AdmissionResponse{
            UID:       admissionReview.Request.UID,
            Allowed:   true,
            Patch:     patchBytes,
            PatchType: &PatchTypeJSONPatch,
        }
        // Return the AdmissionReview with a response as JSON.
        bytes, err := json.Marshal(&admissionReview)
        if err != nil {
            log.Fatal(err)
        }
        w.Write(bytes)
    })

    log.Printf("About to listen on 8443. Go to https://127.0.0.1:8443/")
    err := http.ListenAndServeTLS(":8443", certFile, keyFile, nil)
    log.Fatal(err)
}

4. Configure MutatingWebhookConfiguration

Create a MutatingWebhookConfiguration that points to the HTTPS server and defines the rules for triggering the webhook (e.g., on pod creation with specific labels).

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: test-sidecar-injector
webhooks:
- name: sidecar-injector.mytest.io
  admissionReviewVersions:
  - v1  # must match the server version
  sideEffects: "NoneOnDryRun"
  reinvocationPolicy: "Never"
  timeoutSeconds: 30
  objectSelector:
    matchExpressions:
    - key: run
      operator: In
      values:
      - "nginx"
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:
    - CREATE
    resources:
    - pods
    scope: "*"
  clientConfig:
    caBundle: ${CA_PEM_B64}
    url: https://192.168.100.22:8443/  # point to the local server

Replace ${CA_PEM_B64} with the base64‑encoded content of rootCA.crt (obtainable via openssl base64 -A -in rootCA.crt ).

Finally, test the setup by creating a pod:

kubectl run nginx --image=nginx

Inspect the created pod and you will see the injected sidecar container alongside the original container.

Conclusion

After reading this guide you should understand the basic workflow of Kubernetes Admission Controllers and how they are leveraged by many open‑source projects such as Istio.

KubernetesGoTLSwebhookAdmissionControllerSidecarInjection
System Architect Go
Written by

System Architect Go

Programming, architecture, application development, message queues, middleware, databases, containerization, big data, image processing, machine learning, AI, personal growth.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.