什么是admission webhook
Kubernetes Admission Webhook
是一种HTTP
回调机制,它允许Kubernetes
调用外部Web
服务,以便在某些事件发生时执行自定义代码。
Admission Webhook
是Kubernetes
提供的一种扩展机制,用于在资源被持久化到etcd
之前,对资源进行验证或修改。Admission Webhook
可以分为两种类型:Validation Webhook
和Mutating Webhook
。
Validation Webhook
用于验证资源是否符合预期的规则,如果资源不符合规则,则会拒绝资源被持久化到etcd
。
Mutating Webhook
则可以对资源进行修改,在资源被持久化到etcd
之前,将资源修改为期望的状态。允许对请求进行更改,例如对Pod
进行注入,以添加一些特定于应用程序的设置,如日志记录、密钥管理、监视等。
Webhook
机制使得用户可以根据自己的需求编写和部署自己的代码,以扩展和定制Kubernetes
平台的行为。
Webhook
何时调用,
图片来源于网络
如何编写一个webhook
Webhook请求与响应
1 | // 结构体定义了请求和响应的字段 |
- 请求:
Webhook
发送POST
请求时,请设置Content-Type: application/json
并对admission.k8s.io
API
组中的AdmissionReview
对象进行序列化,将所得到的JSON
作为请求的主体。 - 响应:
Webhook
使用HTTP 200
状态码、Content-Type: application/json
和一个包含AdmissionReview
对象的JSON
序列化格式来发送响应。该AdmissionReview
对象与发送的版本相同,且其中包含的response
字段已被有效填充。
响应示例:1
2
3
4
5
6
7
8{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "<value from request.uid>",
"allowed": true
}
}
开始编写Webhook
配置
ValidatingAdmissionWebhook
,此准入控制器调用与请求匹配的所有验证性 Webhook。 匹配的 Webhook 将被并行调用。如果其中任何一个拒绝请求,则整个请求将失败。 该准入控制器仅在验证(Validating)阶段运行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-webhook
webhooks:
- name: pod.webhook.hysyeah.com
# 定义访问的服务,如果是外部服务则指定对应的URL
clientConfig:
service:
name: pod-webhook
namespace: default
path: "/configmaps"
caBundle: "update <>"
# 匹配规则,如果传入请求与rules的指定operations,groups,version,resources匹配
# 则该请求将发送到webhook
rules:
- operations: [ "CREATE", "UPDATE", "DELETE"]
apiGroups: ["apps", ""]
apiVersions: ["v1"]
resources: ["configmaps"]
failurePolicy: Ignore
sideEffects: None
admissionReviewVersions:
- v1配置
MutatingWebhookConfiguration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: pod-webhook
webhooks:
- name: pod.webhook.hysyeah.com
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- pods
failurePolicy: Ignore
sideEffects: None
admissionReviewVersions:
- v1
clientConfig:
# base64 -w 0 ca.crt
caBundle: "update <>"
service:
name: pod-webhook
namespace: default
path: "/add-label"构建镜像
nerdctl build -t hysyeah/pod-webhook:v3 .
1 | FROM golang:1.18-alpine |
- 编写对应的
deployment
1 | apiVersion: apps/v1 |
部署
webhook
执行kubectl apply -f deployment.yaml
验证
webhook
新建一个pod,发现pod添加了label:
added-label=yes
1
2NAME READY STATUS RESTARTS AGE LABELS
my-curl 1/1 Running 0 170m added-label=yes,app=my-curl新建一个
configmap
,包含webhook-e2e-test: webhook-disallow
结果如下:1
Error from server (the configmap contains unwanted key and value): error when creating "configmap.yaml": admission webhook "pod.webhook.hysyeah.com" denied the request: the configmap contains unwanted key and value
完整的代码可查看完整代码
注意事项
- 确保启用
MutatingAdmissionWebhook
和ValidatingAdmissionWebhook
控制器 - 确保启用了
admissionregistration.k8s.io/v1
API - 确保您的代码不会影响Kubernetes集群的稳定性和安全性
- 当用户尝试创建的对象与返回的对象不同时,用户可能会感到困惑。
- 与覆盖原始请求中设置的字段相比,使用原始请求未设置的字段会引起问题的可能性较小。 应尽量避免覆盖原始请求中的字段设置
REF:
1.https://github.com/jpeeler/podpreset-crd/tree/master/webhook
2.https://github.com/kubernetes/kubernetes/tree/release-1.21/test/images/agnhost/webhook
3.https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/
4.https://banzaicloud.com/blog/k8s-admission-webhooks/