{"id":18679871,"url":"https://github.com/bsctl/admission-controller-demo","last_synced_at":"2025-06-15T10:35:28.640Z","repository":{"id":148233751,"uuid":"207145854","full_name":"bsctl/admission-controller-demo","owner":"bsctl","description":"A demo web-hook for kubernetes admission control","archived":false,"fork":false,"pushed_at":"2023-02-24T23:56:08.000Z","size":29,"stargazers_count":0,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-27T21:44:46.233Z","etag":null,"topics":["admission-controllers","kubern","node-selectors"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bsctl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-08T17:09:19.000Z","updated_at":"2021-05-24T07:15:49.000Z","dependencies_parsed_at":"2023-05-19T12:15:18.973Z","dependency_job_id":null,"html_url":"https://github.com/bsctl/admission-controller-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bsctl%2Fadmission-controller-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bsctl%2Fadmission-controller-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bsctl%2Fadmission-controller-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bsctl%2Fadmission-controller-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bsctl","download_url":"https://codeload.github.com/bsctl/admission-controller-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239533068,"owners_count":19654617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admission-controllers","kubern","node-selectors"],"created_at":"2024-11-07T09:46:07.495Z","updated_at":"2025-02-18T19:13:59.218Z","avatar_url":"https://github.com/bsctl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kubernetes Admission Controller Demo\nThis repo contains a demo server which implements a [Mutating Admission Controller](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) for Kubernetes.\n\nThe Mutating Admission Controller demo is inspired by the embedded [Pod Node Selector](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#podnodeselector) admission controller which control what node selectors may be used within a given namespace.\n\nFor example, we may want all pods deployed in the production namespace to have specific node selector(s). The node selector(s) are then used by the default scheduler to assign the pods to a dedicated set of nodes reserved for production.\n\nUnlike the embedded Pod Node Selector controller, this custom admission controller does not requires the APIs server to be reloaded in case of changes in the configuration.\n\nPlease, see the [A guide to Kubernetes policy controllers](doc/guide-kubernetes-policy-controllers.md) for the rationale behind this demo.\n\n## Prerequisites\nTo run this demo, please, ensure that:\n\n * the Kubernetes cluster is at least as new as v1.14\n * the admissionregistration.k8s.io/v1beta1 API is enabled:\n    \n        $ kubectl api-versions | grep admissionregistration.k8s.io/v1beta1\n        admissionregistration.k8s.io/v1beta1\n \n * the ``MutatingAdmissionWebhook`` and the ``ValidatingAdmissionWebhook`` admission controllers are enabled in the APIs Server configuration:\n \n        --enable-admission-plugins=MutatingAdmissionWebhook,ValidatingAdmissionWebhook, ...\n \n  See Kubernetes documentation for how to enable Admission Controllers and for a recommended set of controllers to be enabled.\n\n## Build the image\nClone this repo on a local machine where ``kubectl`` is configured against the target Kubernetes cluster. The image is built from the provided [Dockerfile](Dockerfile):\n\n    docker build -t webhook:v0.0.1 .\n\nOnce the image is built, push it on your preferred repository.\n\n## Deploy\nA deployment [script](deployment/deploy.sh) is provided. The script uses the Kubernetes Certificate Signing Request (CSR) to a generate a certificate and key signed by the Kubernetes CA itself. This certificate and key are required to secure the communication between the webhook server and the APIs server. Make sure you have the permissions to create and approve CSR in your Kubernetes cluster.\n\nAlso, before to attempt the script, please update all relevant parameters according to your environment and permissions:\n\n    service=\"webhook-server\"\n    namespace=\"default\"\n    repository=\"\"\n    image=\"webhook\"\n    version=\"v0.0.1\"\n\nRun the script. The script ends with a bounch of manifest files and apply them to Kubernetes:\n\n\n    $ cd deployment\n    $ ./deploy.sh\n    creating certs in tmpdir /tmp/tmp.iYxAX9oyU8 \n    Generating RSA private key, 2048 bit long modulus\n    ...\n    certificatesigningrequest.certificates.k8s.io/webhook-server created\n    certificatesigningrequest.certificates.k8s.io/webhook-server approved\n    mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook-server created\n    certificatesigningrequest.certificates.k8s.io/webhook-server configured\n    deployment.extensions/webhook-server created\n    configmap/webhook-server created\n    service/webhook-server created\n    secret/webhook-server created\n\n\nVerify the webhook server pod in the selected namespace is running:\n\n    $ kubectl get pods -n default\n\n    NAME                             READY   STATUS    RESTARTS   AGE\n    webhook-server-bd7998fdb-mfwjw   1/1     Running   0          16m\n\n## Operate\nThe business logic of webhook is controlled by the ``rules.json`` configuration file passed to the webhook as Config Map. By default, the configuration file looks like:\n\n```json\n{\n    \"defaultselector\": \"fruit=banana\",\n    \"rules\": {\n    \"development\":  \"env=development\",\n    \"production\":   \"env=production\"\n    }\n}\n```\n\nIt defines a set of rules: each rule contains a namespace and the list of label(s) to be assigned as node selector(s) to the pods.\n\nIn the default configuration, all the pods deployed into ``production`` namespace will use the label ``env=production`` as node selector and all the pods deployed into ``development`` namespace will use the label ``env=development``.\n\nIn addition, a default selector ``fruit=banana`` is specified for all the other namespaces not listed above.\n\n### Create the namespaces\nTo check the webook, let's to create first the namespaces\n\n    $ kubectl create ns development\n    $ kubectl create ns production\n\n### Deploy pods\nDeploy pods into namespaces:\n\n    $ kubectl run dev \\\n        --image=nginx:latest \\\n        --port=80 \\\n        --generator=run-pod/v1 \\\n        --namespace=development\n\n    $ kubectl run prod \\\n        --image=nginx:latest \\\n        --port=80 \\\n        --generator=run-pod/v1 \\\n        --namespace=production\n\nInspect the pod just created:\n\n    $ kubectl get pods -n development\n    NAME   READY   STATUS    RESTARTS   AGE\n    dev    0/1     Pending   0          3m32s   \n\n    $ kubectl get pods -n production\n    NAME   READY   STATUS    RESTARTS   AGE\n    prod   0/1     Pending   0          4m51s\n\nA closer look to the pods will show us the reason for failing.\n\n    $ kubectl describe pod dev -n development\n\n    ...\n    Events:\n    Type     Reason            Age                 From               Message\n    ----     ------            ----                ----               -------\n    Warning  FailedScheduling  30s (x10 over 3m)   default-scheduler  0/1 nodes are available: 1 node(s) didn't match node selector.\n\nSo there are no nodes matching the applyed node selectors:\n\n    $ kubectl get pod dev -o json -n development\n        ...\n        \"nodeSelector\": {\n            \"env\": \"development\"\n        },\n\n    $ kubectl get pod prod -o json -n production\n        ...\n        \"nodeSelector\": {\n            \"env\": \"production\"\n        },\n\n### Label the nodes\nIn order to get those pods running on the assigned nodes, we need to label nodes according to the rules above\n\n    $ kubectl get nodes\n    NAME     STATUS   ROLES    AGE    VERSION\n    cmp      Ready    master   12d    v1.14.1\n    worker01 Ready    worker   12d    v1.14.1\n    worker02 Ready    worker   12d    v1.14.1\n    worker03 Ready    worker   12d    v1.14.1\n\n    $ kubectl label node worker01 -l env=development\n    $ kubectl label node worker02 -l env=production\n    $ kubectl label node worker03 -l env=production\n\nAnd check the pods again\n\n    $ kubectl get pods -o wide -n development\n    NAME   READY   STATUS    RESTARTS   AGE   IP            NODE\n    dev    1/1     Running   0          19m   10.38.1.123   worker01  \n\n    $ kubectl get pods -o wide -n production\n    NAME   READY   STATUS    RESTARTS   AGE   IP            NODE\n    prod   1/1     Running   0          19m   10.38.2.141   worker02  \n\nNow all pods are running on nodes according to their namespaces.\n\n\n### Update the webhook rules\nWe can specify multiple labels as node selector. Modify the configuration rules by editing the Config Map\n\n    $ kubectl -n default edit cm\n\nso that the ``rules.json`` configuration file looks like the following:\n\n```json\n{\n    \"defaultselector\": \"fruit=banana\",\n    \"rules\": {\n    \"development\":  \"env=development\",\n    \"production\":   \"env=production\",\n    \"staging\":      \"env=staging\"\n    }\n}\n```\n\nTo have the configuration reloaded, kill the webhook pod and wait a new one is created by the deployment controller\n\n    $ kubectl -n default get pods\n    NAME                             READY   STATUS    RESTARTS   AGE\n    webhook-server-bd7998fdb-7z2lh   1/1     Running   0          10m\n\n    $ kubectl -n default delete pod webhook-server-bd7998fdb-7z2lh \n\n    $ kubectl -n default get pods\n    NAME                             READY   STATUS    RESTARTS   AGE\n    webhook-server-bd7998fdb-7z2lh   1/1     Running   0          13s\n\nLabel one of the nodes with the new label\n\n    $ kubectl label node worker03 -l env=staging\n\nCreate the new ``staging`` namespace\n\n    $ kubectl create namespace staging\n\nand let's to deploy a new pod into the namespace\n\n    $ kubectl run stage \\\n        --image=nginx:latest \\\n        --port=80 \\\n        --generator=run-pod/v1 \\\n        --namespace=staging\n\nThe new pod in the ``staging`` namespace will use the label ``env=staging`` as node selector\n\n    $ kubectl get pod stage -o json -n staging\n        ...\n        \"nodeSelector\": {\n            \"env\": \"staging\"\n        },\n\nand it will be running on the node ``worker03`` we just labeled before\n\n    $ kubectl get pods -o wide -n staging\n    NAME   READY   STATUS    RESTARTS   AGE   IP           NODE\n    stage  1/1     Running   0          12s   10.38.3.4    worker03\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbsctl%2Fadmission-controller-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbsctl%2Fadmission-controller-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbsctl%2Fadmission-controller-demo/lists"}