(Proudly powered by QKQ)
Kubernetes中的Admission Controller是做什么的呢?有什么用呢?怎么自己定义一个呢?
Q: 什么是Admission Controller?
A: 官方定义:
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.
我理解的:
- Admission Controller是一个拦截器
- 拦截发送给Kuberenetes API Server的请求
- 什么时候拦截?在请求通过认证之后,请求被存储起来之前
所以顺理成章,由于拦截的是发送给API Server的请求,所以Admission Controller存在于API Server内部,即compiled into the kube-apiserver binary(被编译进API Server的可执行文件里)。
kubernetes将AC分为三种:
- validating,验证型。用于验证k8s的资源定义是否符合规则
- mutating,修改型。用于修改k8s的资源定义,比如加个label什么的
- 二者皆是,即同一个AC,既是验证型又是修改型
多个Admission Controller会形成一个Admission Chain(链条),修改型的在前面先执行,验证型的在后面后执行,这样验证型的才能去验证修改的对不对。
K: interceptor, validating, mutating, Admission Chain
Q: Admission Controller有什么用?
A: API Server内置了一些AC,有各种各样的作用[1]。比如:
- EventRateLimit,用于限制事件的频率
- LimitRanger,验证所有的请求都没有超出namespace中定义的LimitRange
还有很多其他AC,具体请参考Kubernetes文档。
这些AC中,有两个对用户来说比较有用:
- MutatingAdmissionWebhook,这是一个webhook,即网络钩子,也就是说该AC会去请求服务端,并执行相应的逻辑
- ValidatingAdmissionWebhook,也是一个webhook,只是用于验证
Q: 怎么查看哪些AC是打开了的?
A: 文档上写的用:kube-apiserver -h | grep enable-admission-plugins
。但是由于本地是minikube,进入虚拟机之后并没有发现kube-apiserver命令。
后来发现api-server是以pod的形式运行的:
kubectl get pods -n kube-system
于是,使用kubectl exec登入pod,然后调用上述的指令,其结果为:
/ # kube-apiserver -h | grep enable-admission-plugins
--admission-control strings Admission is divided into two phases. In the first phase, only mutating admission plugins run. In the second phase, only validating admission plugins run. The names in the below list may represent a validating plugin, a mutating plugin, or both. The order of plugins in which they are passed to this flag does not matter. Comma-delimited list of: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, Initializers, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, ValidatingAdmissionWebhook. (DEPRECATED: Use --enable-admission-plugins or --disable-admission-plugins instead. Will be removed in a future version.)
--enable-admission-plugins strings admission plugins that should be enabled in addition to default enabled ones (NamespaceLifecycle, LimitRanger, ServiceAccount, Priority, DefaultTolerationSeconds, DefaultStorageClass, PersistentVolumeClaimResize, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, ResourceQuota). Comma-delimited list of admission plugins: AlwaysAdmit, AlwaysDeny, AlwaysPullImages, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, Initializers, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, ValidatingAdmissionWebhook. The order of plugins in this flag does not matter.
Q: Admission webhook是啥?
A: 官方定义:
Admission webhooks are HTTP callbacks that receive admission requests and do something with them.
简单来说webhook就是一个HTTP回调,接收admission请求,处理并返回。
用户可以定义两种webhook:
- validating admission webhook
- mutating admission webhook
一个用于验证,另一个用于修改。
webhook回调,接收API Server发送的admissionReview请求,并返回 admissionResponse。
K: 回调,admissionReview请求,admissionResponse返回。
Q: 如何配置和查看WebhookConfiguration?
A: 以Validating为例,查看:
kubectl get ValidatingWebhookConfiguration
ValidatingWebhookConfiguration的资源定义:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name:
webhooks:
- name:
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
clientConfig:
service:
namespace:
name:
caBundle:
其中rules定义了匹配规则,当发给API Server的请求满足该规则的时候,API Server就会给clientConfig中配置的service发送Admission请求。
使用webhook有什么要求?
A: 几点:
- kubernetes版本最低是v1.9
- api server使能(enable)了MutatingAdmissionWebhook和ValidatingAdmissionWebhook
- admissionregistration.k8s.io/v1beta1 API处于enable状态,即使用
kubectl api-versions | grep admissionregistration.k8s.io/v1beta1
Q: 如何自己写一个webhook?
A: 需要完成几个事情:
- 创建TLS Certificate,即证书
- 编写服务端代码,服务端代码需要使用证书
- 根据证书创建k8s sercret
- 创建k8s Deployment和Service
- 创建k8s WebhookConfiguration,其中需要使用之前创建的证书
具体代码和流程参见[3][4]
参考文献:
[1] https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
[2] https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks
[3] https://banzaicloud.com/blog/k8s-admission-webhooks/
[4] https://github.com/morvencao/kube-mutating-webhook-tutorial
[5] https://github.com/banzaicloud/admission-webhook-example