WEBKT

用Node.js构建Kubernetes Webhook实现Pod创建自定义校验

17 0 0 0

用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服务器

  1. 初始化项目

    首先,创建一个新的Node.js项目目录,并在其中初始化一个npm项目:

    mkdir k8s-webhook
    cd k8s-webhook
    npm init -y
  2. 安装依赖

    我们需要安装一些必要的依赖,包括express用于创建HTTP服务器,body-parser用于解析请求体:

    npm install express body-parser
    
  3. 编写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。

  4. 运行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.nameclientConfig.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的行为,满足各种各样的需求。

K8s探索者 KubernetesWebhookNode.js

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/10162