Kubernetes webhook原理介绍及执行演示
什么是准入控制?
1 什么是准入控制
准入控制(Admission Controller)是 K8S API Server 用于拦截请求的一种手段。Admission 可以做到对请求的资源对象进行校验,修改。
K8S内置了很多准入控制插件,比如:
ServiceAccount插件自动为Pod注入serviceAccountName字段
NamespaceLifecycle插件禁止在一个正在被删除的 Namespace 中创建新对象
什么是准入webhook
准入 Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制。
在K8S1.9之前,用户想要自定义准入控制插件,需要重新编译kube-apiserver,为了提供更灵活的扩展方式,K8S在1.9版本之后提供了两种webhook类型的准入控制插件,即 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。用户可以独立开发自己的准入webhook,kube-apiserver会通过HTTP调用准入webhook程序。
MutatingAdmissionWebhook会先被调用。它可以对发送到kube-apiserver的对象执行修改操作。在完成了所有对象修改并且 API 服务器也验证了所传入的对象之后, ValidatingAdmissionWebhook会被调用,并通过拒绝请求的方式来强制实施自定义的策略。
注意:如果准入 Webhook 希望保证自己对资源对象做的修改为最终状态,则应使用ValidatingAdmissionWebhook对资源状态进行校验,因为资源对象被修改性质 Webhook 看到之后仍然可能被其他webhook修改。
webhook组成
完整的准入webhook包含:
- 准入webhook程序:接受准入请求后的实际处理程序,可以实现添加/修改Pod标签、注解或者注入sidercar等功能
- MutatingWebhookConfiguration/ValidatingWebhookConfiguration(CRD):将准入webhook注册到Apiserver,包含准入webhook的访问方式,ca证书和拦截规则
- 证书:apiserver通过https访问准入webhook,准入webhook启动时需要服务端证书
上图为单向认证示例,webhook支持与apiserver进行双向认证,需要配置AdmissionConfiguration资源
webhook执行过程
当通过kubectl或者api创建一个deployment资源时,kube-apiserver与webhook程序调用详情
-
kube-apiserver收到请求,先通过认证鉴权判断操作是否允许
-
kube-apiserver通过CRD(MutatingWebhookConfiguration)资源获取到准入webhook列表,然后依次通过HTTPS调用准入webhook程序
请求体如下:{ "apiVersion": "admission.k8s.io/v1", "kind": "AdmissionReview", "request": { # 唯一标识此准入回调的随机 uid "uid": "705ab4f5-6393-11e8-b7cc-42010a800002", # 正在提交的对象的完整类型 "kind": {"group":“apps","version":"v1","kind":"Deployment"}, # 正在请求的完全合格的资源 "resource": {"group":"apps","version":"v1","resource":"deployments"}, # 被修改资源的名称 "name": "my-deployment", "namespace": "my-namespace", # 操作可以是 CREATE、UPDATE、DELETE 或 CONNECT "operation": “CREATE", "userInfo": { "username": "admin", "uid": "014fbff9a07c", "groups": ["system:authenticated","my-admin-group"], }, # 资源对象。 "object": {"apiVersion":“apps/v1","kind":" Deployment ",...}, } }
-
准入webhook收到请求后执行相应修改逻辑,将资源对象的修改结果返回给kube-apiserver
响应体如下:{ "kind": "AdmissionReview", "apiVersion": "admission.k8s.io/v1", "response": { "uid": "705ab4f5-6393-11e8-b7cc-42010a800002", "allowed": true, "status": { "metadata": {}, "code": 200 }, "patch": "W3sib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9zcGVjL3JlcGxpY2FzIiwidmFsdWUiOjJ9XQ==", "patchType": "JSONPatch" } }
patch字段为base64编码后的值,解码后的内容为
[ { "op": "replace", "path": "/spec/replicas", "value": 2 } ]
-
在完成了所有对象修改并且 apiserver也验证通过后,apiserver会并发调用所有ValidatingWebhook
-
ValidatingWebhook在收到请求后,校验请求资源对象并将验证结果返回给apiserver
响应体如下:{ "apiVersion": "admission.k8s.io/v1", "kind": "AdmissionReview", "response": { "uid": "<value from request.uid>", "allowed": false, #false表示校验失败,true表示校验通过 "status": { "code": 403, "message": "" #校验失败原因 } }
-
apiserver收到webhook返回的校验结果后,若校验通过则写入ETCD,否则资源创建失败
- 点赞
- 收藏
- 关注作者
评论(0)