用Node.js构建Kubernetes Webhook实现Pod创建自定义校验
用Node.js构建Kubernetes Webhook实现Pod创建自定义校验
什么是Kubernetes Webhook?
准备工作
步骤一:创建Node.js Webhook服务器
步骤二:生成TLS证书
步骤三:创建Kubernetes Secret存储证书
步骤四:创建Kubernetes Service暴露Webhook
步骤五:配置ValidatingWebhookConfiguration
步骤六:测试Webhook
总结
用Node.js构建Kubernetes Webhook实现Pod创建自定义校验
在Kubernetes的世界里,Webhook就像一个灵活的“钩子”,允许你在集群内部事件发生时,拦截并执行自定义的逻辑。今天,咱们就来聊聊如何用Node.js打造一个简单的Kubernetes Webhook,实现对Pod创建的自定义校验。这玩意儿能让你在Pod真正跑起来之前,先做一层“体检”,确保它们符合你的规则。
什么是Kubernetes Webhook?
简单来说,Kubernetes Webhook是一种HTTP回调机制。当Kubernetes API Server接收到创建、更新或删除资源的请求时,它可以配置成将这些请求的信息发送到你指定的Webhook服务器。Webhook服务器收到请求后,可以根据自己的逻辑进行处理,然后返回一个允许或拒绝该请求的决策。
Webhook主要分为两种:
- Mutating Admission Webhook(变更准入Webhook): 它可以修改Kubernetes API Server接收到的对象。比如,你可以用它来自动注入sidecar容器。
- Validating Admission Webhook(验证准入Webhook): 它只负责验证Kubernetes API Server接收到的对象是否有效,不进行修改。如果验证失败,它可以拒绝该请求。
咱们今天要实现的,就是一个Validating Admission Webhook,用来校验Pod的创建请求。
准备工作
在开始之前,你需要确保已经安装了以下工具:
- Node.js (v14 或更高版本)
- npm 或 yarn
- kubectl
- 一个Kubernetes集群 (minikube, kind, 或其他)
- openssl (用于生成证书)
步骤一:创建Node.js Webhook服务器
初始化项目
首先,创建一个新的Node.js项目目录,并在其中初始化一个npm项目:
mkdir k8s-webhook cd k8s-webhook npm init -y 安装依赖
我们需要安装一些必要的依赖,包括
express
用于创建HTTP服务器,body-parser
用于解析请求体:npm install express body-parser
编写Webhook服务器代码
创建一个名为
server.js
的文件,并添加以下代码:const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.post('/validate', (req, res) => { const admissionReview = req.body; // 在这里实现你的校验逻辑 const pod = admissionReview.request.object; const isValid = pod.metadata.labels && pod.metadata.labels['app'] === 'my-app'; const response = { apiVersion: 'admission.k8s.io/v1', kind: 'AdmissionReview', response: { uid: admissionReview.request.uid, allowed: isValid, status: { code: isValid ? 200 : 403, message: isValid ? 'Pod is valid' : 'Pod is invalid: missing or incorrect app label', }, }, }; res.send(response); }); const port = 3000; app.listen(port, () => { console.log(`Webhook server listening on port ${port}`); }); 这段代码创建了一个简单的HTTP服务器,监听
/validate
路径。当收到请求时,它会解析请求体中的AdmissionReview
对象,提取其中的Pod对象,并进行校验。如果Pod的metadata.labels.app
等于my-app
,则认为Pod是有效的,否则认为无效。最后,它会构造一个AdmissionReview
响应,并将其发送回Kubernetes API Server。运行Webhook服务器
在终端中运行以下命令启动Webhook服务器:
node server.js
步骤二:生成TLS证书
由于Kubernetes Webhook必须使用HTTPS,我们需要生成TLS证书。你可以使用openssl
来生成自签名证书:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=webhook.example.com'
请注意,CN
(Common Name)必须与你将在Kubernetes中配置的Webhook服务器的域名或IP地址匹配。在这个例子中,我们使用了webhook.example.com
。
步骤三:创建Kubernetes Secret存储证书
将生成的证书存储在Kubernetes Secret中,以便Webhook可以使用它们:
kubectl create secret tls webhook-certs --key key.pem --cert cert.pem
步骤四:创建Kubernetes Service暴露Webhook
为了让Kubernetes API Server能够访问到Webhook服务器,我们需要创建一个Kubernetes Service:
apiVersion: v1 kind: Service metadata: name: webhook-service namespace: default spec: selector: app: webhook ports: - port: 443 targetPort: 3000
将以上内容保存为service.yaml
,然后执行以下命令创建Service:
kubectl apply -f service.yaml
你还需要创建一个Deployment来运行Webhook服务器。这里不再赘述,你可以参考Kubernetes官方文档。
步骤五:配置ValidatingWebhookConfiguration
最后,我们需要创建一个ValidatingWebhookConfiguration
对象,告诉Kubernetes API Server在创建Pod时调用我们的Webhook:
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: pod-validator webhooks: - name: pod-validator.example.com clientConfig: service: name: webhook-service namespace: default path: /validate caBundle: $(cat cert.pem | base64 | tr -d '\n') rules: - operations: [ "CREATE" ] apiGroups: [ "" ] apiVersions: [ "v1" ] resources: [ "pods" ] admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None
clientConfig.service.name
和clientConfig.service.namespace
指定了Webhook服务器的Service名称和命名空间。clientConfig.service.path
指定了Webhook服务器的路径。caBundle
包含了证书的Base64编码,用于验证Webhook服务器的身份。rules
指定了Webhook生效的规则,这里我们指定了只对Pod的创建操作生效。sideEffects: None
表明该Webhook没有副作用,即不会修改Kubernetes集群的状态。
将以上内容保存为webhook.yaml
,然后执行以下命令创建ValidatingWebhookConfiguration
:
kubectl apply -f webhook.yaml
步骤六:测试Webhook
现在,你可以尝试创建一个Pod来测试Webhook是否生效。首先,创建一个包含app: my-app
标签的Pod:
apiVersion: v1 kind: Pod metadata: name: valid-pod labels: app: my-app spec: containers: - name: nginx image: nginx
将以上内容保存为valid-pod.yaml
,然后执行以下命令创建Pod:
kubectl apply -f valid-pod.yaml
如果一切正常,Pod应该能够成功创建。接下来,创建一个不包含app: my-app
标签的Pod:
apiVersion: v1 kind: Pod metadata: name: invalid-pod spec: containers: - name: nginx image: nginx
将以上内容保存为invalid-pod.yaml
,然后执行以下命令创建Pod:
kubectl apply -f invalid-pod.yaml
你应该会看到一个错误消息,提示Pod无效,无法创建。这表明Webhook已经成功拦截了Pod的创建请求,并根据你的规则进行了校验。
总结
通过以上步骤,我们成功地使用Node.js构建了一个Kubernetes Webhook,实现了对Pod创建的自定义校验。你可以根据自己的需求,修改Webhook服务器的代码,实现更复杂的校验逻辑。Webhook是Kubernetes的一个强大的扩展机制,它可以让你在不修改Kubernetes核心代码的情况下,定制Kubernetes的行为,满足各种各样的需求。