目录
1.什么是 Mutating Admission Webhook?
2.如何用 Mutating Admission Webhook 实现超卖?
3.实现超卖
3.1 理解目标
3.2 前置准备
3.3 开发 Mutating Webhook
3.4 配置 Webhook Server TLS 认证
3.5 注册 MutatingWebhookConfiguration
3.6 部署 Webhook 到集群
3.7 测试功能
3.8 监控与告警
1.什么是 Mutating Admission Webhook?
- 定义:是一种拦截 Kubernetes API 请求的插件,在对象被持久化之前对其进行修改。
- 典型用途:
- 注入默认资源请求/限制(如 CPU/Memory)
- 修改 Pod Spec(如注入 sidecar 容器)
- 实现多租户资源配额控制
2.如何用 Mutating Admission Webhook 实现超卖?
场景目标
允许 requests.cpu 超出节点实际物理容量(如 64 核),但通过策略控制其不超过一定比例(如 110%)。
实现思路
1.拦截 Pod 创建请求
使用 Mutating Webhook 拦截所有 Pod 的创建或更新请求。
2.读取当前节点已分配资源
获取该 Pod 即将调度到的节点上已有的 requests.cpu 总和。
可以通过 kubelet 或 metrics-server 获取。
3.判断是否超出超卖上限
若总请求 + 当前 Pod 请求 > Allocatable * OvercommitRatio,则拒绝或自动调整请求值。
4.自动设置默认值(可选)
如果未设置 requests.cpu,可以自动注入一个合理默认值(例如 500m)。
5.返回修改后的 Pod Spec
在 Admission Response 中返回修改后的 Pod Spec。
3.实现超卖
3.1 理解目标
我们希望达到的效果是:
- 允许 Pod 的 requests.cpu 超出节点实际可分配资源(如 Allocatable=64核)
- 但限制其总和不超过一定比例(例如:110%)
- 在 Pod 创建/更新时动态拦截并验证或修改请求内容
3.2 前置准备
环境要求
- Kubernetes 集群(v1.20+)
- 启用 MutatingAdmissionWebhook 控制器(默认启用)
- 安装 kubebuilder 或使用 Go 开发
- TLS 证书用于 webhook server(可通过 cert-manager 自动生成)
3.3 开发 Mutating Webhook
1. 初始化项目(使用 kubebuilder)
kubebuilder init --domain example.com
kubebuilder create api --group admission --version v1 --kind OvercommitWebhook
2. 编写 Webhook 核心逻辑
a. 拦截 Pod 创建请求
func (r *PodWebhook) Default(ctx context.Context, obj runtime.Object) error {pod := obj.(*corev1.Pod)// 如果未设置 CPU request,则注入默认值if pod.Spec.Containers != nil {for i := range pod.Spec.Containers {if _, ok := pod.Spec.Containers[i].Resources.Requests[corev1.ResourceCPU]; !ok {pod.Spec.Containers[i].Resources.Requests = corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("500m"),}}}}return nil
}
b. 判断是否超出超卖限制
func checkOvercommit(pod *corev1.Pod, nodeName string) bool {nodeInfo, err := getNodeAllocatable(nodeName)if err != nil {log.Error(err, "无法获取节点信息")return false}totalRequestedCPU := getCurrentTotalCPURequests(nodeName)newRequestCPU := getResourceMilliCPU(pod)overcommitRatio := 1.1 // 110%maxAllowedCPU := nodeInfo.Allocatable.Cpu().MilliValue() * int64(overcommitRatio)return (totalRequestedCPU + newRequestCPU) <= maxAllowedCPU
}// 获取当前 Pod 请求的 CPU 总量
func getResourceMilliCPU(pod *corev1.Pod) int64 {var total int64for _, container := range pod.Spec.Containers {cpuReq := container.Resources.Requests.Cpu()if cpuReq != nil {total += cpuReq.MilliValue()}}return total
}
c. 修改或拒绝请求
func mutatePod(pod *corev1.Pod) ([]byte, error) {// 示例:自动注入 sidecar 或修改 requestspod.Spec.Containers[0].Resources.Requests[corev1.ResourceCPU] = resource.MustParse("700m")return json.Marshal(pod)
}
3.4 配置 Webhook Server TLS 认证
1. 使用 cert-manager 自动生成证书(推荐)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:name: webhook-cert
spec:secretName: webhook-server-certissuerRef:name: selfsigned-issuerkind: ClusterIssuerdnsNames:- webhook-service.default.svc- webhook-service.default.svc.cluster.local
2. 配置 Webhook Server 使用证书
server := &webhook.Server{Host: "0.0.0.0",Port: 443,CertDir: "/tmp/cert",TLSOpts: []func(*tls.Config){func(config *tls.Config) {config.ClientAuth = tls.NoClientCert},},
}
3.5 注册 MutatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:name: overcommit-mutating-webhook
webhooks:- name: mutating.overcommit.example.comrules:- operations: ["CREATE"]apiGroups: [""]apiVersions: ["v1"]resources: ["pods"]clientConfig:service:namespace: defaultname: webhook-servicecaBundle: <base64 encoded CA cert>admissionReviewVersions: ["v1"]sideEffects: NonetimeoutSeconds: 5
caBundle 是你的 CA 证书的 base64 编码。
3.6 部署 Webhook 到集群
1. 构建镜像并推送到仓库
make docker-build docker-push IMG=myregistry/overcommit-webhook:latest
2. 部署 Deployment 和 Service
apiVersion: apps/v1
kind: Deployment
metadata:name: webhook-deployment
spec:replicas: 1selector:matchLabels:app: webhooktemplate:metadata:labels:app: webhookspec:containers:- name: webhookimage: myregistry/overcommit-webhook:latestports:- containerPort: 443
---
apiVersion: v1
kind: Service
metadata:name: webhook-service
spec:ports:- port: 443targetPort: 443selector:app: webhook
3.7 测试功能
1. 创建一个 Pod
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: nginximage: nginxresources:requests:cpu: 500m
2. 查看是否被拦截并修改
kubectl describe pod test-pod
查看是否注入了新的 CPU 请求或被拒绝创建。
3.8 监控与告警
建议结合 Prometheus + Grafana:
- 监控指标:
container_cpu_usage_seconds_total
kube_node_allocatable_cpu_cores
kube_pod_container_resource_requests_cpu_cores
- 告警规则示例:
groups:- name: cpu-overcommitrules:- alert: HighCpuRequestUsageexpr: sum(kube_pod_container_resource_requests_cpu_cores) by (node) / kube_node_allocatable_cpu_cores > 1.1for: 5mlabels:severity: warningannotations:summary: Node {{ $labels.node }} CPU 请求已超过 110%
如果你正在构建一个支持 CPU 、内存资源超卖 的 Kubernetes 平台,建议将此 Mutating Webhook 与调度器插件(如 Kube-scheduler 插件或调度器扩展)配合使用,以实现更精细的资源管理策略。