02 - Admission Controllers

Admission Controllers

🌐 Admission Controllers 是什麼?

Admission Controllers 是 Kubernetes API Server 中的一個 請求攔截點(intercept point),當使用者送出請求(例如 `kubectl apply -f xxx.yaml`)時,在這個請求被持久化到 etcd 前,Admission Controller 會進行額外的驗證、修改或拒絕。

Admission Controllers 位於 API Server 處理流程中的
驗證(Authentication)與授權(Authorization)之後,物件寫入 etcd 之前。

Note: the `Namespace Auto Provision` and `Namespace Exists` at admission controllers are deprecated and is now replaced by the `Namespace Lifecycle` Admission Controller.

The `namespace lifecycle` admission controller will make sure that requests to a non-existent namespace is rejected and that the default namespace, such as default kube-system and kube-public cannot be deleted.


✨ 分類:Mutating vs Validating


🔧 常見內建 Admission Controllers

  • NamespaceLifecycle 禁止在 Terminating 的 Namespace 中創建新資源
  • LimitRanger 根據 Namespace 設定限制 Pod 的資源使用
  • ServiceAccount 自動注入預設的 ServiceAccount 到 Pod
  • ResourceQuota 強制資源配額
  • NodeRestriction 限制 kubelet 操作非自身的 Node 資源


🌐 Webhook 型 Admission Controller

若內建的控制器不夠用,你可以自訂 Webhook 服務,透過:
  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook

實現你自己的邏輯(例如:防止 Pod 使用 :latest tag 的 image、必須帶有特定 label 等)。
Webhook 是獨立的 HTTP 服務,API Server 會把請求內容送過去,讓你決定是否接受並修改資源。


📦 啟用方式

$ kube-apiserver -h | grep enable-admission-plugins                    

Admission Controllers 在 kube-apiserver 中透過 --enable-admission-plugins--disable-admission-plugins 啟用或停用。

$ kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,MutatingAdmissionWebhook,ValidatingAdmissionWebhook --disable-admission-plugins=AlwaysAdmit,AlwaysDeny         


🛠 使用場景舉例

  • 強制所有 Pod 使用特定 namespace
  • 自動為資源補 label / annotation
  • 阻止某些使用者部署未經驗證的 image
  • 強制資源命名規則或版本策略


Q: What is not a function of admission controller?

Ans: authenticate user


The functions of an Admission Controller are:

  • validate configuration
  • perform additional operations before the pod gets created
  • help us implement better security measures


Q: Which admission controller is not enabled by default?

Ans: NamespaceAutoProvision 


Enabled by default:

  • NamespaceLifecycle
  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook


$ kubectl exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep 'enable-admission-plugins'          

Default 已啟用的 Admission Plugins:

admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, PodSecurity, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, RuntimeClass, CertificateApproval, CertificateSigning, ClusterTrustBundleAttest, CertificateSubjectRestriction, DefaultIngressClass, MutatingAdmissionPolicy, MutatingAdmissionWebhook, ValidatingAdmissionPolicy, ValidatingAdmissionWebhook, ResourceQuota).


Q: Which admission controller is enabled in this cluster which is normally disabled?

Ans: --enable-admission-plugins=NodeRestriction

$ grep enable-admission-plugins /etc/kubernetes/manifests/kube-apiserver.yaml      


連續題組

Try to create nginx pod in the blue namespace. 
The blue namespace does not already exist.

$ kubectl run nginx --image nginx -n blue                           
Error msg: Error from server (NotFound): namespaces "blue" not found

Q: The previous step failed because kubernetes have `NamespaceExists` admission controller enabled which rejects requests to namespaces that do not exist. So, to create a namespace that does not exist automatically, we could enable the `NamespaceAutoProvision` admission controller

  • Enable the `NamespaceAutoProvision` admission controller
  • Note: Once you update `kube-apiserver yaml` file, please wait for a few minutes for the `kube-apiserver` to restart completely.


$ vim /etc/kubernetes/manifests/kube-apiserver.yaml                    

```
# ...
spec:
  containers:
  - command:
    - kube-apiserver
    # ...
    - --enable-admission-plugins=NodeRestriction,NamespaceAutoProvision
```


如何檢查設定是否正確?

$ kubectl run nginx --image nginx -n blue                  

若跑 `nginx` pod 成功,則設定正確。


連續題組

Note that the `NamespaceExists` and `NamespaceAutoProvision` admission controllers are deprecated and now replaced by `NamespaceLifecycle` admission controller.

The `NamespaceLifecycle` admission controller will make sure that requests

to a non-existent namespace is rejected and that the default namespaces such as

`default`, `kube-system` and `kube-public` cannot be deleted.



Q: Disable `DefaultStorageClass` admission controller

  • This admission controller observes creation of `PersistentVolumeClaim` objects that do not request any specific storage class and automatically adds a default storage class to them. This way, users that do not request any special storage class do not need to care about them at all and they will get the default one.
  • Note: Once you update `kube-apiserver yaml` file then please wait few mins for the `kube-apiserver` to restart completely.


$ vim /etc/kubernetes/manifests/kube-apiserver.yaml              

```
# ...
spec:
  containers:
  - command:
    - kube-apiserver
    # ...
    - --disable-admission-plugins=DefaultStorageClass
```



Since the `kube-apiserver` is running as pod you can check the process to see enabled and disabled plugins.

$ ps -ef | grep kube-apiserver | grep admission-plugins              


留言