首页
导航
统计
留言
更多
壁纸
直播
关于
推荐
星的导航页
星的云盘
谷歌一下
腾讯视频
Search
1
Ubuntu安装 kubeadm 部署k8s 1.30
88 阅读
2
rockylinux 9.3详细安装drbd+keepalived
73 阅读
3
kubeadm 部署k8s 1.30
72 阅读
4
rockylinux 9.3详细安装drbd
68 阅读
5
ceshi
52 阅读
默认分类
日记
linux
docker
k8s
golang
prometheus
ELK
Jenkins
登录
/
注册
Search
标签搜索
k8s
linux
docker
drbd+keepalivde
ansible
dcoker
webhook
星
累计撰写
41
篇文章
累计收到
46
条评论
首页
栏目
默认分类
日记
linux
docker
k8s
golang
prometheus
ELK
Jenkins
页面
导航
统计
留言
壁纸
直播
关于
推荐
星的导航页
星的云盘
谷歌一下
腾讯视频
搜索到
1
篇与
的结果
2023-08-20
k8s的webhook开发
一、知识储备1、Admission Webhooks是什么 请求链路 ------------|--------|-------------》etcd 关卡 关卡 webhook指的是中途拦击请求做定制化处理,包含 (1)mutate:截胡请求之后做修改,改完之后扔回原链路 (2)validate:对请求的数据做校验,不符合规定的直接扔掉 Admission翻译为准入,入指的是入到etcd数据库中2、webhook的执行时机 Admission Webhook 本质是 api-server 的一个 webhook 调用, 总结出两种webhook的触发时机 1、总提来说,Admission Webhooks 机制是在 API Server 接收到请求、执行授权检查后和将请求持久化到 etcd 之前触发。 2、详细的看,Mutating Webhook 在 Validating Webhook 之前触发,因此可以先对资源进行修改,然后再进行验证。 3、Admission Webhook的运行流程 ┌──────────────────────────────────┐ ┌─────────────────┐ │ │ apply │ │ read │ validatingwebhookconfiguration │ ────────────►│ api-server │◄───────────┤ │ │ │ │ mutatingwebhookconfiguration │ └────────┬────────┘ │ │ │ └──────────────────────────────────┘ │ │ 回调 │ │ ┌────────▼────────┐ │ │ │ webhookservice │ │ │ └─────────────────┘4、Admission Webhook的应用场景mutating webhook应用场景举例 自动注入sidecar容器 自动配置资源限制 注入配置或者标签 Validating Webhook应用场景举例 强制标签和注解策略 必须用私有仓库的镜像 安全策略审计:例如不允许使用特权模式二、mutating webhook实战案例1.储备知识:基于flask框架开发一个web程序,对外提供api接口# 安装python3解释器 # 为解释器环境安装flask代码包: pip3 install flask from flask import Flask app = Flask(__name__) # 创建一个 Flask 应用实例 @app.route('/xxx', methods=['GET']) # http://192.168.71.2:8888/xxx def mutate(): print("run....................") return "hello" @app.route('/yyy', methods=['GET']) # http://192.168.71.2:8888/xxx def test(): print("run22222222222222222....................") return "hello2222222222222222222222222" if __name__ == '__main__': app.run(host='0.0.0.0', port=8888,)2.需求:为所有新创建的pod打上标签:environment: production(1)先准备webhook程序cat > webhook.py << 'EOF' from flask import Flask, request, jsonify # 导入 Flask 框架、请求处理和 JSON 响应模块 import json import ssl import base64 app = Flask(__name__) # 创建一个 Flask 应用实例 def create_patch(metadata): """ 创建 JSON Patch 以添加 'mutate' 注释。 如果 metadata.annotations 不存在,则首先创建该路径。 """ if 'labels' in metadata: dic = metadata['labels'] else: dic = {} patch = [ # 添加 'labels' 键,如果不存在 {'op': 'add', 'path': '/metadata/labels', 'value': dic}, # 添加 'environment' 标签 {'op': 'add', 'path': '/metadata/labels/environment', 'value': 'production'} ] patch_json = json.dumps(patch) patch_base64 = base64.b64encode(patch_json.encode('utf-8')).decode('utf-8') return patch_base64 @app.route('/mutate', methods=['POST']) # https://webhook-service.default.svc:443/mutate def mutate(): """ 处理 Mutating Webhook 的请求,对 Pod 对象应用 JSON Patch。 """ admission_review = request.get_json() # 从请求中提取 AdmissionReview 对象 # 验证 AdmissionReview 格式是否正确 # admission_review['request']['object'] if 'request' not in admission_review or 'object' not in admission_review['request']: return jsonify({ 'kind': 'AdmissionReview', 'apiVersion': 'admission.k8s.io/v1', 'response': { 'allowed': False, # 如果格式无效,则禁止当前提交过来的资源请求 'status': {'message': 'Invalid AdmissionReview format'} } }) req = admission_review['request'] # 提取请求对象 print('--->',req) # 生成 JSON Patch metata = req['object']['metadata'] patch_json = create_patch(metata) # 准备 AdmissionResponse 响应 admission_response = { 'kind': 'AdmissionReview', 'apiVersion': 'admission.k8s.io/v1', 'response': { 'uid': req['uid'], 'allowed': True, 'patchType': 'JSONPatch', 'patch': patch_json # 直接包含 Patch 数据作为 JSON 字符串 } } print(admission_response) return jsonify(admission_response) if __name__ == '__main__': # 加载 SSL 证书和私钥 context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain('/certs/tls.crt', '/certs/tls.key') # Run the Flask application with SSL app.run(host='0.0.0.0', port=443, ssl_context=context) EOF python webhook.py(2)制作镜像(包含webhook.py的运行环境,依赖python3解释器、依赖flask框架)文件dockerfile内容如下# 使用官方 Python 镜像作为基础镜像 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 将当前目录的所有文件复制到容器的 /app 目录 COPY webhook.py . # 安装 Flask 及其依赖 RUN pip install Flask # 启动 Flask 应用 CMD ["python", "webhook.py"] 然后构建镜像:docker build -t egon-mute-webhook:v1.0 .打标签上传docker tag c0f805ffaa01 registry.cn-guangzhou.aliyuncs.com/xingcangku/egon-mute-webhook:v1.0 docker push registry.cn-guangzhou.aliyuncs.com/xingcangku/egon-mute-webhook:v1.0(3)配置 Webhook 的 Secret# 生成 CA 私钥 openssl genrsa -out ca.key 2048 # 生成自签名 CA 证书,有效期为 100 年 openssl req -x509 -new -nodes -key ca.key -subj "/CN=webhook-service.default.svc" -days 36500 -out ca.crt创建证书请求的配置文件cat > webhook-openssl.cnf << 'EOF' [req] default_bits = 2048 prompt = no default_md = sha256 req_extensions = req_ext distinguished_name = dn [ dn ] C = CN ST = Shanghai L = Shanghai O = egonlin OU = egonlin CN = webhook-service.default.svc [ req_ext ] subjectAltName = @alt_names [alt_names] DNS.1 = webhook-service DNS.2 = webhook-service.default DNS.3 = webhook-service.default.svc DNS.4 = webhook-service.default.svc.cluster.local [req_distinguished_name] CN = webhook-service.default.svc [v3_req] keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [ v3_ext ] authorityKeyIdentifier=keyid,issuer:always basicConstraints=CA:FALSE keyUsage=keyEncipherment,dataEncipherment extendedKeyUsage=serverAuth,clientAuth subjectAltName=@alt_names EOF使用webhook-openssl.cnf这个配置文件生成 CSR:# 生成 Webhook 服务的私钥 openssl genrsa -out webhook.key 2048 # 使用 OpenSSL 配置文件生成 CSR openssl req -new -key webhook.key -out webhook.csr -config webhook-openssl.cnf openssl x509 -req -in webhook.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out webhook.crt -days 36500 -extensions v3_ext -extfile webhook-openssl.cnf #最终得到webhook.crt、webhook.key将生成的证书和私钥存储在 Kubernetes Secret 中#可能有残留可以先删一下 kubectl delete secrets webhook-certs kubectl create secret tls webhook-certs \ --cert=webhook.crt \ --key=webhook.key \ --namespace=default --dry-run=client -o yaml | kubectl apply -f -3.创建deployment来部署webhook服务cat > webhook-deployment.yaml << 'EOF' apiVersion: apps/v1 kind: Deployment metadata: name: webhook-deployment namespace: default spec: replicas: 1 selector: matchLabels: app: webhook template: metadata: labels: app: webhook spec: containers: - name: webhook image: registry.cn-guangzhou.aliyuncs.com/xingcangku/axingcangku:v2.0 command: [ "/bin/sh", "-c", "tail -f /dev/null" ] volumeMounts: - name: webhook-certs mountPath: /certs readOnly: true volumes: - name: webhook-certs secret: secretName: webhook-certs --- apiVersion: v1 kind: Service metadata: name: webhook-service namespace: default spec: ports: - port: 443 targetPort: 443 selector: app: webhook EOF4.基于kind: mutatingwebhookconfiguration 该资源类型创建出一个资源,相当于于一道关卡在该资源中声明把请求转给的目标webhook程序的api地址基于脚本来生成yaml:cat a.sh#!/bin/bash base64 -w 0 ca.crt > ca.crt.base64 # 定义文件路径 ca_base64_file="ca.crt.base64" yaml_file="m-w-c.yaml" # 读取 ca.crt.base64 的内容 ca_base64_content=$(cat "$ca_base64_file" | tr -d '\n') # 生成替换后的 YAML 文件内容 # 将 base64 内容插入到 YAML 文件中 cat <<EOF > "$yaml_file" apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: example-mutating-webhook webhooks: - name: example.webhook.com clientConfig: service: name: webhook-service namespace: default path: "/mutate" # 替换为 cat ca.crt.base64的内容 caBundle: "$ca_base64_content" rules: - operations: ["CREATE"] apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] admissionReviewVersions: ["v1"] sideEffects: None EOF echo "YAML 文件已更新。" 5、创建pod进行测试[root@k8s-master-01 word]# cat test.yaml apiVersion: v1 kind: Pod metadata: name: test-pod spec: containers: - name: nginx image: nginx:1.18
2023年08月20日
11 阅读
0 评论
0 点赞