amp
is a Kubernetes Dynamic Admission Control mutating webhook proxy for Pods.
The amp
project focuses on simplifying the process of modifying Kubernetes Pods on creation through custom endpoints, adding, removing, and modifying init containers, volumes, environment variables, or any other component of the Pod specification. The amp
project originally stemmed from the need to add custom volumes and environment variables to Pods created by JupyterHub; however, amp
is useful for extending any system that creates Pods that should be interrogated and mutated with external resources and values. In the JupyterHub use case, JupyterHub spawns a Pod for a user into a Namespace, Kubernetes notifies amp
and amp
send the Pod specification to a custom endpoint. The custom endpoint retrieves a username from a Pod annotation and sends patch operations back to amp
, modifying the Pod with user-specific environment variables and volume mounts.
amp
receives Kubernetes Admission Review requests for Pod creation events from any Namespace labeled amp.txn2.com/enabled=true
and forwards the Pod definition as a JSON POST to a custom HTTP endpoint defined through the value of the Namespace annotation amp.txn2.com/ep
. The custom HTTP endpoint receives a Pod definition for evaluation and returns an array of JSONPatch operations to amp
(see example).
The following depiction illustrates a high-level view of an example endpoint named some-app-b
mutating a Pod:
-
Kubernetes receives a Pod creation event.
-
Kubernetes MutatingWebhookConfiguration for
amp
matches any Namespace labeledamp.txn2.com/enabled: true
. -
Kubernetes sends an
AdmissionReview
object toamp
. -
amp
extracts thecorev1.Pod
object from theAdmissionReview
, looks up the custom endpoint annotated in the Pod's Namespace and sends an HTTP POST of thecorev1.Pod
as JSON to the endpoint. -
amp
receives a JSON encoded array of PatchOperations for thecorev1.Pod
. -
amp
responds to Kubernetes AdmissionReview with the received PatchOperations as a response. -
Kubernetes creates the new mutated Pod.
po := []PatchOperation{
// add initContainer
{
Op: "add",
Path: "/spec/initContainers/-",
Value: corev1.Container{
Name: "new-init-container",
Image: "alpine:3.12.0",
},
},
// add environment variable to container 0 first-existing-container
{
Op: "add",
Path: "/spec/containers/0/env/-",
Value: corev1.EnvVar{
Name: "ADDED_VAR",
Value: "something important",
},
},
}
Refer to the example implementation at txn2/amp-wh-example.
see k8s/README.md
goreleaser --skip-publish --rm-dist --skip-validate
GITHUB_TOKEN=$GITHUB_TOKEN goreleaser --rm-dist