# Admission Controllers
## What are they?
An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized.
Theis logic is called after an API request is authenticated and right before persistence of the object.

## Why do we need them?
Admission controllers provide for a way to introduce custom logic in the Kubernetes API request lifecycle. Cluster administrators may want the certain resources to conform to a specificpolicy, for example, image pull policy, resource limits for containers.
## Kinds
### By functionality
1. Mutating
They can mutate the object.
2. Validating
They only validate the object.
### By the way they are defined

## Builtin Plugins
### Generic Admission Plugins
There are three generic admission plugins defined in https://git.k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/plugin:
1. [NamespaceLifecycle](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#namespacelifecycle)
Ensures that resources are not created in terminating/non-existing namespaces. Also, prevents reserved namespaces from being deleted.
2. [MutatingAdmissionWebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)
3. [ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook)
The remaining two are what powers the Dynamic Admission Control landscape. They are responsible for acting on rules you define in `{Mutating,Validating}WebhookConfiguration` objects.
### Other builtin plugins
They can be found in https://git.k8s.io/kubernetes/plugin/pkg/admission
```
plugin/pkg/admission
├── admit
├── alwayspullimages
├── antiaffinity
├── certificates
├── defaulttolerationseconds
├── deny
├── eventratelimit
├── extendedresourcetoleration
├── gc
├── imagepolicy
├── limitranger
├── namespace
├── network
├── noderestriction
├── nodetaint
├── podnodeselector
├── podtolerationrestriction
├── priority
├── resourcequota
├── runtimeclass
├── security
├── securitycontext
├── serviceaccount
└── storage
24 directories, 1 file
```
## What makes a Go struct behave like a Admission Control Plugin?
They should satisfy either `MutatingInterface` or `ValidatingInterface` or both depending on the nature of the plugin.
Ref: https://git.k8s.io/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/admission/interfaces.go#L129-L144
## Configuring builtin admission controllers
`kube-apiserver` accepts the following flags to allow modification of admission control behavior:
```
--admission-control-config-file string
File with admission control configuration.
--disable-admission-plugins strings
admission plugins that should be disabled although they are in the default enabled plugins list (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.
--enable-admission-plugins strings
admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, DenyServiceExternalIPs, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.
```
Points to be noted:
1. `{Validating/Mutating}AdmissionWebhook` can also be disabled if the user wants. Although, in that case, the `{Validating,Mutating}WebhookConfiguration` objects in the admissionregistration.k8s.io/v1 group/version need to be disabled via the `--runtime-config` flag.
2. The admission control plugins can be configured by passing an YAML manifest with an object of the kind `AdmissionConfiguration` to `--admission-control=config-file`. Following is an example of the same.
```
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
configuration:
imagePolicy:
kubeConfigFile: <path-to-kubeconfig-file>
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: true
```
## Configuring Dynamic Admission Controllers
They are configured using `{Mutating,Validating}WebhookConfiguration` objects. These objects are then read by the respective builtin admission control plugins and acted upon.
```
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "pod-policy.example.com"
webhooks:
- name: "pod-policy.example.com"
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
scope: "Namespaced"
clientConfig:
service:
namespace: "example-namespace"
name: "example-service"
caBundle: "Ci0tLS0tQk...<`caBundle` is a PEM encoded CA bundle which will be used to validate the webhook's server certificate.>...tLS0K"
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
timeoutSeconds: 5
```
## References
- https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
- https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/
- https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/
- https://ahmet.im/blog/initializers/