Kubernetes: Admission Control (1.8)

## はじめに

> **Admission Controlとは**
> 
> Admission ControlとはKubernetesのAPI Serverのリクエスト制御の機能です。APIリクエストに対して認証、認可を行ったあとのフェーズで、別途そのリクエストを受け入れるか制御を行います。また場合によって、リクエストの変更や別の操作を行います。
> 
> プラグイン形式で複数の制御の方法が用意されており、APIの起動オプション--admission-controlで有効にしたいものをカンマ区切りで指定します。

- [Kubernetes: Admission Controlとは何か](https://qiita.com/tkusumi/items/f71882f47e2d87701223)

上記エントリは 1.2 時点でのプラグインを紹介していますが、ここでは 1.2 から 1.8 までに新たに追加されたプラグインについて記載します。

## プラグイン一覧

- [DefaultStorageClass](#defaultstorageclass)
- [DefaultTolerationSeconds](#defaulttolerationseconds)
- [EventRateLimit (alpha)](#eventratelimit-alpha)
- [GenericAdmissionWebhook (alpha)](#genericadmissionwebhook-alpha)
- [ImagePolicyWebhook](#imagepolicywebhook)
- [Initializers (alpha)](#initializers-alpha)
- [LimitPodHardAntiAffinity](#limitpodhardantiaffinity)
- [NamespaceAutoProvision](#namespaceautoprovision)
- [NamespaceExists](#namespaceexists)
- [NodeRestriction](#noderestriction)
- [OwnerReferencesPermissionEnforcement](#ownerreferencespermissionenforcement)
- [PersistentVolumeLabel (DEPRECATED)](#persistentvolumelabel-deprecated)
- [PodNodeSelector](#podnodeselector)
- [PersistentVolumeClaimResize](#persistentvolumeclaimresize)
- [PodPreset](#podpreset)
- [PodSecurityPolicy](#podsecuritypolicy)
- [PodTolerationRestriction](#podtolerationrestriction)
- [Priority](#priority)

### DefaultStorageClass

PersistentVolumeClaim `.spec.storageClassName` が `""` に設定されている場合に、デフォルトで使われる StorageClass を設定するためのプラグイン。デフォルトの StorageClass を指定するためには対象の StorageClass オブジェクトの `storageclass.kubernetes.io/is-default-class` アノテーションを `true` に設定する必要がある。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/storageclass/setdefault/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#defaultstorageclass

### DefaultTolerationSeconds

taints `notready:NoExecute` と `unreachable:NoExecute` を許容する時間のデフォルトを5分に設定する。effect `NoExecute` がノードに追加されると、Pod はただちに eviction されるが、`NoExecute` を許容する Pod の場合、`tolerationSeconds` に設定された秒数待ってから eviction される。設定されている秒数内に taint が取り除かれたら eviction は実行されない。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/defaulttolerationseconds/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#defaulttolerationseconds
- [Taints and Tolerations \| Kubernetes](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/)

### EventRateLimit (alpha)

apiserver がイベントリクエストにより高負荷になることを抑制するプラグイン。`Server` (全てのイベントリクエスト)、`Namespace`, `User`, `SourceAndObject` 単位で予算を設定することができる。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/eventratelimit/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#eventratelimit-alpha

### GenericAdmissionWebhook (alpha)

任意のサーバへの Webhook の結果によりリクエストを受け入れるか制御するプラグイン。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/webhook/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#genericadmissionwebhook-alpha
- [Dynamic Admission Control \| Kubernetes](https://kubernetes.io/docs/admin/extensible-admission-controllers/)

リクエスト内容を操作する必要が有る場合は、[Initialziers]() を利用する必要がある。

### ImagePolicyWebhook

Pod に含まれるコンテナイメージにポリシーを適応するプラグイン。任意のサーバへの Webhook により決定される。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/imagepolicy/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#imagepolicywebhook

### Initializers (alpha)

動的にリクエストの内容を操作するためのプラグイン。サイドカーを自動的に Pod に挿入するなどの利用用途がある。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/initialization/initialization.go
- https://kubernetes.io/docs/admin/admission-controllers/#initializers-alpha

リクエストの内容を操作する必要がない場合は、[GenericAdmissionWebhook]() の利用を推奨する。

### LimitPodHardAntiAffinity

`requiredDuringSchedulingRequiredDuringExecution` で `kubernetes.io/hostname` 以外のキーで `AntiAffinity` が定義されている Pod を拒否するプラグイン。

| AFFINITY SELECTOR                                 | REQUIREMENTS MET | REQUIREMENTS NOT MET | REQUIREMENTS LOST |
|---------------------------------------------------|------------------|----------------------|-------------------|
| `requiredDuringSchedulingIgnoredDuringExecution`  | Run              | Fails                | Keeps Running     |
| `preferredDuringSchedulingIgnoredDuringExecution` | Run              | Runs                 | Keeps Running     |
| `requiredDuringSchedulingRequiredDuringExecution` | Run              | Fails                | Fails             |

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/antiaffinity/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#limitpodhardantiaffinity
- https://coreos.com/fleet/docs/latest/affinity.html#affinity

### NamespaceAutoProvision

名前空間に属するリソースが作成される際に、名前空間が既に存在しなければ作成するプラグイン。通常は名前空間が存在しなければリソースの作成に失敗する。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/namespace/autoprovision/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#namespaceautoprovision

### NamespaceExists

名前空間に属するリソースが作成される際に、名前空間が既に存在しなければリクエストを拒否するプラグイン。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/namespace/exists/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#namespaceexists

### NodeRestriction

kubelet が操作できる `Node` と `Pod` オブジェクトを制限するプラグイン。kubelet は自身が動作しているノード以外のオブジェクトも操作できていたが、本来は自身のノードに属するオブジェクトのみを操作できれば十分だった。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/noderestriction/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#noderestriction

### OwnerReferencesPermissionEnforcement

削除権限を持つユーザの操作以外でオブジェクトの `metadata.ownerReferences` を変更できないように制御するプラグイン。`metadata.ownerReferences` は、対象のオブジェクトを作成した親オブジェクトを記録するために利用される。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/gc/gc_admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#ownerreferencespermissionenforcement

### PersistentVolumeLabel (DEPRECATED)

GCE と AWS などにおいて cloud provider により定義される PersistentVolume に region または zone ラベルを自動的に付与するプラグインだったが、廃止されている。代わりに PersistentVolumeLabelController がこの機能を代替している。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/persistentvolume/label/admission.go
- https://github.com/kubernetes/kubernetes/blob/v1.8.4/pkg/controller/cloud/pvlcontroller.go#L48-L60
- https://kubernetes.io/docs/admin/admission-controllers/#persistentvolumelabel

### PodNodeSelector

クラスタワイドまたは Namespace レベルで利用できる node selectors を制限するプラグイン。クラスタワイドで制限する場合は、kube-apiserver `--admission-control-config-file` で設定する。Namespace レベルで制限する場合は、annotation `scheduler.alpha.kubernetes.io/node-selector` で設定する。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/podnodeselector/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#podnodeselector

### PersistentVolumeClaimResize

PersistemtVolumeClaim のリサイズ要求を検証するプラグイン。PersistentVolumeClaim のリサイズは 1.8 時点で alpha であり、FeatureGates で明示的に有効にする必要がある。この機能を利用する場合は、このプラグインをあわせて利用することが推奨されている。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/persistentvolume/resize/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#persistentvolumeclaimresize

### PodPreset

一致する PodPreset の特定のフィールドを Pod に挿入するプラグイン。PodPreset を利用する場合、合わせてこのプラグインを利用する必要がある。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/podpreset/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#podpreset

### PodSecurityPolicy

Pod の作成と変更に際し、要求される SecurityContext と有効な PodSecurityPolicy をもとにリクエストを許可するかどうか決定するプラグイン。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/security/podsecuritypolicy/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#podpreset
- https://kubernetes.io/docs/concepts/policy/pod-security-policy/

### PodTolerationRestriction

最初に Pod の tolerations とその Namespace の tolerations とで衝突しているかを検証し、衝突している場合 Pod のリクエストを拒否する。その後、Namespace の tolerations に Pod の tolerations をマージし、その結果を Namespace の tolerations ホワイトリストと照らし合わせて、もし失敗したら Pod のリクエストを拒否する。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/podtolerationrestriction/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#podtolerationrestriction

### Priority

Pod `.spec.priorityClass` フィールドに設定されている名前からプライオリティの数値を設定するプラグイン。もし設定されている PriorityClass が見つからなければ、その Pod は拒否される。

- https://github.com/kubernetes/kubernetes/blob/v1.8.4/plugin/pkg/admission/priority/admission.go
- https://kubernetes.io/docs/admin/admission-controllers/#priority