目錄
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 插件或調度器擴展)配合使用,以實現更精細的資源管理策略。