Admission Controllerが何をしているのか調べたので、メモ。
TOC
Admission Controllerとは?
Admissionを日本語訳すると入場、入会となります。Admission Controllerは、KubernetesのAPIリクエストを途中で受け取り、リクエスト内容を確認したり、改変を行います。
Admission Controllerには大きく2つのタイプのコントローラが存在し、コントローラはこれらのタイプのどちらか、もしくは、両方のタイプを持ったコントローラとなります。
- Validating(検証)
- Mutating(変異)
ここで重要な点が2つあります。
- コントローラの一つがリクエスト内容を拒否した場合には、そのリクエストがエラーとなる
- Mutatingによるリクエストの変更には、サイド・エフェクトを伴う
という点です。これらを念頭において、実際に有効化されるAdmission Controllerについて見ていきます。
デフォルトで有効化されているAdmission Controller
公式にあるとおり、下記のコマンドでどのプラグインがデフォルトで有効化されるか確認できます。
kube-apiserver -h | grep enable-admission-plugins
kube-apiserverがpodとして動いているならば、下記のようなコマンドで確認できるはずです。
kubectl -n kube-system exec -it $(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}') -- kube-apiserver -h | grep enable-admission-plugins
手元のv1.20.1だと、出力結果は以下のとおりです。
--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, DenyEscalatingExec, DenyExecOnPrivileged, 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.
つまり、下記のプラグインが有効化されています。
- NamespaceLifecycle
- LimitRanger
- ServiceAccount
- TaintNodesByCondition
- Priority
- DefaultTolerationSeconds
- DefaultStorageClass
- StorageObjectInUseProtection
- PersistentVolumeClaimResize
- RuntimeClass
- CertificateApproval
- CertificateSigning
- CertificateSubjectRestriction
- DefaultIngressClass
- MutatingAdmissionWebhook
- ValidatingAdmissionWebhook
- ResourceQuota
17個のプラグインがデフォルトでOnです。kube-apiserverのログを見ると、実際にMutatingとValidatingでどのように有効化されているか確認できます。
I0615 04:23:12.988574 1 plugins.go:158] Loaded 12 mutating admission controller(s) successfully in the following order: NamespaceLifecycle,LimitRanger,ServiceAccount,NodeRestriction,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,RuntimeClass,DefaultIngressClass,MutatingAdmissionWebhook.
I0615 04:23:12.988585 1 plugins.go:161] Loaded 10 validating admission controller(s) successfully in the following order: LimitRanger,ServiceAccount,Priority,PersistentVolumeClaimResize,RuntimeClass,CertificateApproval,CertificateSigning,CertificateSubjectRestriction,ValidatingAdmissionWebhook,ResourceQuota.
このログによると、Mutatingに12個、Validatingに10個のプラグインが登録されていますので、それぞれ見ていきます。
ちなみに、手元の環境では別途NodeRestriction
が有効化されていました。
- --enable-admission-plugins=NodeRestriction
NamespaceLifecycle
- 削除中のNamespaceにリソースを作るリクエストを拒否
- 存在しないNamespaceにリソースを作るのを拒否
- システムで利用される
default
、kube-system
、kube-public
を削除しないようにする
LimitRanger
- Namespace内のLimitRangeオブジェクトに列挙されている内容に違反しているものを拒否
ServiceAccount
- serviceAccountに関する自動化を行うため、serviceAccountを利用する際には強く推奨される
NodeRestriction
- Nodeのkubeletが
system:node:<nodeName>
という認証情報を使用する場合に、Nodeが自身のNodeリソースとそのNodeに動くPodのみ変更できるように制限する - もう少し詳しくはここ
TaintNodesByCondition
- Nodeの実際の状況が反映されるまでにPodが作成されるなどの状況を防ぐため、新規に作成されたNodeを
NotReady
、NoSchedule
とする
Priority
- Podに使われるPriorityClassNameからpriorityを割り当てます。このPriorityは他のPodとの優先度をきめるもの。
DefaultTolerationSeconds
notready:NoExecute
とunreachable:NoExecute
のテイントに対して、Podがデフォルトで5分間許容するという動きをさせます。これは、ノードに問題があって、Podが他のノードで再度作成されるまでの時間を表しています。
DefaultStorageClass
- PersistentVolumeClaimの作成を監視しており、StorageClassが指定されていない場合には、デフォルトのStorageClassを割り当てる動きをします。デフォルトのStorageClassが作られていることが前提です。
StorageObjectInUseProtection
- PersistentVolumeClaimやPersistentVolumeが使用中で他のリソースに紐付いている場合には削除されないようにする保護機能があり、その機能を提供しています。
RuntimeClass
- Podに設定されたRuntimeClassに基づいて、
.spec.overhead
を設定する。作成時点で、.spec.overhead
が設定されていた場合には拒否する。
DefaultIngressClass
- Ingressの作成を監視し、IngressClassが指定されていない場合には、デフォルトのIngressClassを割り当てる。デフォルトのIngressClassが前提となる。
MutatingAdmissionWebhook
- MutatingAdmissionWebhook コントローラはリクエストに該当するMutating Webhookを呼び出します。
kubectl get MutatingWebhookConfiguration
で確認できる
PersistentVolumeClaimResize
- StorageClassでボリュームの拡張を許可していない場合に、サイズの拡張をしようとするPersistentVolumeClaimに対するリクエストを拒否します。
ExpandPersistentVolumes
の機能が有効化されている場合に、使用が推奨されています。
CertificateApproval
- CSRをApproveするリクエストを監視しており、Approveするユーザが許可を持っているか確認します。
CertificateSigning
- CSRの
.status.certificate
に対する更新を監視し、ユーザが許可を持っている確認します。
CertificateSubjectRestriction
spec.signerName
を持つCSRの作成を監視し、system:masters
を指定していた場合には拒否します。
ValidatingAdmissionWebhook
- リクエストにマッチした
ValidatingAdmissionWebhook
を呼び出します。 - 設定されている
ValidatingAdmissionWebhook
はkubectl get ValidatingWebhookConfiguration
で確認できる
ResourceQuota
- リクエストがNamespaceに作成されたResourceQuotaに違反しないか確認します。