Admission Webhook是kubernetes中的准入控制器,用于在apiserver中,对API Request进行拦截,然后对API Request进行特定的处理,处理操作包括:
- Mutating: 修改API Request中的对象;
- Validating: 校验API Request中的对象,若校验非法,则直接返回client,不再继续;
apiserver提供了Admission Webhook的扩展机制,允许用户自定义webhook,然后注册到apiserver上就可以发挥作用了。
一.Admission Webhook的架构
API Request在apiserver中的处理过程:
- 认证:通常是client端提供证书;
- 鉴权:校验client是否有操作相应资源的权限,使用rbac实现;
MutatingAdmission:
- 对传入的资源对象进行修改;
- 用户可以注册自定义的webhook;
- Schema Validation: 对传入对象的schema进行校验;
ValiatingAdmission:
- 对传入的资源对象进行校验,若校验失败,则直接返回client;
- 用户可以注册自定义的webhook;
- 最后,将对象存入etcd;
用户自定义的webhook通常使用deploy部署,同时部署对应的service,在将webhook注册到apiserver时,提供service的名称以及访问的url path,这样apiserver就可以使用自定义webhook的功能逻辑了。
apiserver与webhook之间的通信接口为/api/admission/v1/AdmissionReview结构。
二.AdmissionReview的结构
apiserver与自定义webhook之间通过http通信,其Request和Response均是/api/admission/v1/AdmissionReview结构,也就是说:
- 自定义webhook在处理http请求时,需要将requestBody反序列化为AdmissionReview结构;
- 自定义webhook在发送http响应后,需要构造AdmissionReview结构,将其序列化后发送出去;
AdmissionReview结构既包含Request,也包含Response:
// AdmissionReview describes an admission review request/response.
type AdmissionReview struct {
metav1.TypeMeta `json:",inline"`
// Request describes the attributes for the admission request.
// +optional
Request *AdmissionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"`
// Response describes the attributes for the admission response.
// +optional
Response *AdmissionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"`
}
1. 请求:AdmissionRequest
AdmissionRequest中封装了发送给apiserver的请求信息,包含我们创建、更新、删除的Deploy/Service/Pod等信息,比如:
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"request": {
# Random uid uniquely identifying this admission call
"uid": <random uid>,
...
"object": {"apiVersion":"v1","kind":"Pod",...},
...
}
}
2. 响应:AdmissionResponse
AdmissionResponse封装了准入控制的结果:
- 对于Mutating: 需要返回修改对象的Patch;
- 对于Validating: 需要返回对象的校验结果,若校验失败,还要带上errMsg;
比如,Mutating的AdmissionResponse:
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "<value from request.uid>",
"allowed": true/false,
"status": {
"code": <optional http status code, ex: 200/403>,
"message": "optional message"
},
"patchType": "JSONPatch",
"patch": <base64 encoded JSON patch>
}
}
比如,Validating的AdmissionResponse:
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "<value from request.uid>",
"allowed": true/false,
"status": {
"code": <optional http status code, ex: 200/403>,
"message": "optional message"
}
}
}
三.注册webhook到apiserver
webhook要注册到apiserver后才能生效。
webhook注册到apiserver时,需要告诉apiserver:
- webhook的svc名称、命名空间;
- webhook的URL Path;
- webhook作用的目标对象的筛选规则;
- webhook操作的目标对象及操作;
对于Mutating,注册由MutatingWebhookConfiguration资源类型描述,创建该资源对象即意味着注册,比如:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutating-webhook-example-cfg
labels:
app: admission-webhook-example
webhooks:
- name: mutating-example.com
clientConfig:
service: // webhook的svc
name: admission-webhook-example-svc
namespace: default
path: "/mutate" // webhook的url path
caBundle: ${CA_BUNDLE}
rules: // 操作的资源
- operations: [ "CREATE" ]
apiGroups: ["apps", ""]
apiVersions: ["v1"]
resources: ["deployments","services"]
namespaceSelector: // 目标对象的筛选规则
matchLabels:
admission-webhook-example: enabled
对于Validating,注册由ValidatingWebhookConfiguration资源类型描述,创建该资源对象即意味着注册:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: validation-webhook-example-cfg
labels:
app: admission-webhook-example
webhooks:
- name: validating-example.com
clientConfig:
service: // webhook的svc
name: admission-webhook-example-svc
namespace: default
path: "/validate" // webhook的url path
caBundle: ${CA_BUNDLE}
rules: // 操作的资源
- operations: [ "CREATE" ]
apiGroups: ["apps", ""]
apiVersions: ["v1"]
resources: ["deployments","services"]
namespaceSelector: // 目标对象的筛选规则
matchLabels:
admission-webhook-example: enabled
参考:
1.https://www.qikqiak.com/post/k8s-admission-webhook/
2.AdmissionReview的结构:https://github.com/kubernetes/api/blob/master/admission/v1/types.go
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。