背景
在请求经过身份验证和授权之后,对象持久化之前,对Kubernetes API 服务器的请求进行拦截。
准入控制器可能执行validating或者mutating或两者兼而有之。Mutating 控制器可以修改他们的处理的资源对象,Validating 控制器不会,如果任何一个阶段中的任何控制器拒绝了请求,则会立即拒绝整个请求,并将错误返回给最终的用户。
1 |
|
在 apiserver 内部,有两个特殊的 controllers:MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook,通过它们提供的协议,用户能够将自定义 webhook 集成到 admission controller 控制流中。
顾名思义,mutating admission webhook 可以拦截并修改请求资源,validating admission webhook 只能拦截并校验请求资源,但不能修改它们。分成两类的一个好处是,后者可以被 apiserver 并发执行,只要任一失败,即可快速结束请求。
向集群发出POST请求,会序列化成AdmissionReview
1 |
|
修改,校验 request.object 中的反序列后内容(需要我们提供https自定义服务完成),最后将结果返回给 apiserver。
1 |
|
开启校验 for Mac
Docker for mac 修改kube-apiserver参数(How to enable admission-pulgins in kubernetes of docker-desktop)
1 |
|
- Getting a Shell in the Docker Desktop Mac VM
- How to enable admission-pulgins in kubernetes of docker-desktop
证书准备
既然是提供https服务,自然需要提供证书,Kubernetes 证书有效期为 1 年,复杂的生产环境可以考虑certmanager,它有自动更新、自动注入等一系列生命周期管理功能。
mac上面调试访问本机服务使用
host.docker.internal
域名
k8s Certificate Signing Requests
- 使用openssl,通过配置,生产key和csr文件。
- 使用 Kubernetes CertificateSigningRequest 和 kubectl approve 签名服务证书
- 将服务私钥和证书,存储到 Kubernetes Secret 中
- 如果采用集群外部署,注意在 csr.conf 中指定好域名或 IP 地址
1 |
|
CertManager
-
安装cert-manager(kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml)或者helm chart
-
apply Issuer CR 和Certificate CR,引用 Issuer 签发证书
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
27
28
29
30
31
32
33
34
35
36
37
38apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: customwebhook-selfsigned-issuer namespace: default spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: customwebhook-tls-secret spec: duration: 8760h renewBefore: 8000h commonName: customwebhook.default isCA: false privateKey: algorithm: RSA encoding: PKCS1 size: 2048 usages: - digital signature - key encipherment - server auth dnsNames: - customwebhook - customwebhook.default - customwebhook.default.svc # 给集群内调用 - host.docker.internal # 给集群外面用 方便调试 # ipAddresses: # - 192.168.1.10 # change it to your IP addresses issuerRef: kind: Issuer name: customwebhook-selfsigned-issuer secretName: customwebhook-tls-secret # 生产的secretName
-
查看secretName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21# 查看 kubectl describe secret customwebhook-tls-secret Name: customwebhook-tls-secret Namespace: default Labels: <none> Annotations: cert-manager.io/alt-names: .... Type: kubernetes.io/tls Data ==== ca.crt: 1237 bytes tls.crt: 1237 bytes tls.key: 1675 bytes # 获取方便调试 kubectl get secrets/customwebhook-tls-secret -o jsonpath="{.data['tls\.key']}" | base64 -d > tls.key kubectl get secrets/customwebhook-tls-secret -o jsonpath="{.data['tls\.crt']}" | base64 -d > tls.crt
向 apiserver 注册 admission webhook
获取caBundle , cert-manager 自动注入 不需要caBundle
1 |
|
官方文档 解析入参出参 WebhookConfiguration 配置,按需要配置ValidatingWebhookConfiguration,MutatingWebhookConfiguration,其中一个或全部
1 |
|
代码参考
官方代码很好了解一些入参出参的写法,而sig做了相应的封装。
main.go
1 |
|
webhook.go 核心方法
1 |
|