本文目录导读:

Kubernetes准入控制器(Admission Controller)是集群安全治理的最后一道防线,它在请求被持久化到etcd之前拦截并处理API请求,以下是核心机制与实战用法:
核心工作原理
-
执行流程顺序:
- API请求 → 认证 → 授权(RBAC) → 准入控制器 → etcd存储
- 准入控制器位于授权之后、持久化之前,可修改或拒绝请求
-
两种类型:
- Mutating(变更):先执行,可修改请求对象(如注入Sidecar)
- Validating(验证):后执行,仅做校验(如资源配额检查)
- 每个控制器可同时实现两种逻辑
启用与配置(以内部控制器为例)
查看默认启用列表(kube-apiserver启动参数)
# 查看当前启用的准入控制器 kubectl -n kube-system exec kube-apiserver-master -- kube-apiserver -h | grep enable-admission-plugins
常用内部控制器功能
| 控制器名称 | 作用场景 |
|---|---|
NamespaceLifecycle |
防止在删除中的Namespace创建资源 |
LimitRanger |
确保Pod设置资源请求限制(LimitRange) |
ResourceQuota |
强制执行Namespace级别的资源配额 |
MutatingAdmissionWebhook |
调用外部Webhook修改请求 |
ValidatingAdmissionWebhook |
调用外部Webhook验证请求 |
修改apiserver配置文件(静态Pod方式)
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --enable-admission-plugins=NodeRestriction,PodSecurity
- --disable-admission-plugins=LegacyAuthorization
高级用法:自定义Webhook准入控制器
当内置控制器不能满足需求时,可以开发外部Webhook:
开发一个简单的Webhook(Go示例片段)
// 验证Deployment名称不能包含"bad"
func mutateHandler(w http.ResponseWriter, r *http.Request) {
// 1. 解码AdmissionReview请求
var review admissionv1.AdmissionReview
json.NewDecoder(r.Body).Decode(&review)
// 2. 获取原始Pod对象
pod := corev1.Pod{}
json.Unmarshal(review.Request.Object.Raw, &pod)
// 3. 检查名称是否违规
if strings.Contains(pod.Name, "bad") {
review.Response = &admissionv1.AdmissionResponse{
Allowed: false,
Result: &metav1.Status{Message: "Pod名称不能包含'bad'"},
}
} else {
review.Response = &admissionv1.AdmissionResponse{Allowed: true}
}
// 4. 返回AdmissionReview响应
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(review)
}
部署Webhook服务并注册
# webhook-config.yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-name-check
webhooks:
- name: pod-name-check.example.com
clientConfig:
service:
name: webhook-service
namespace: webhook
path: "/validate"
caBundle: <base64编码CA证书>
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
scope: "Namespaced"
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 5
常见应用场景实战
强制Pod安全策略(替代废弃的PSP)
# 启用PodSecurity准入控制器(v1.23+)
kube-apiserver --enable-admission-plugins=PodSecurity
# 创建安全策略(标签驱动)
apiVersion: v1
kind: Namespace
metadata:
labels:
pod-security.kubernetes.io/enforce: restricted # 强制restricted级别
自动注入Sidecar代理
# MutatingWebhookConfiguration示例(Istio的注入原理)
webhooks:
- name: sidecar-injector.istio.io
clientConfig:
service:
name: istio-sidecar-injector
namespace: istio-system
path: "/inject"
rules:
- operations: ["CREATE"]
resources: ["pods"]
sideEffects: NoneOnDryRun
资源标签审计与自动修复
// Mutating Webhook:自动给所有Pod添加"managed-by=audit"标签
patchBytes := []byte(`[{"op":"add","path":"/metadata/labels/managed-by","value":"audit"}]`)
review.Response.Patch = patchBytes
review.Response.PatchType = func() *string { s := "JSONPatch"; return &s }()
故障排查与优化
查看准入控制器调用日志
# 增加APIServer的verbosity kube-apiserver --v=5 # 会输出准入决策信息 # 或查看Webhook服务日志 kubectl logs -n webhook deployment/webhook-service
性能优化建议
- 超时设置:Webhook
timeoutSeconds建议设置5-10秒,避免阻塞API Server - 故障模式:
failurePolicy: Ignore可避免Webhook故障影响集群 - 并发控制:使用
matchConditions减少不必要的Webhook调用
安全加固
- TLS双向认证:Webhook必须使用HTTPS且验证客户端证书
- 最小权限:合理设置
rules作用域,避免监听所有资源 - 混沌测试:定期测试Webhook故障时的集群行为
实战技巧汇总
-
调试新Webhook:使用
--dry-run=server测试效果kubectl create pod test-pod --dry-run=server -o yaml
-
逐步启用:生产环境建议先启用
Validating再启用Mutating -
审计追踪:结合
ValidatingAdmissionWebhook记录所有违规请求 -
版本兼容:v1.22+ 必须使用
admissionregistration.k8s.io/v1API版本
通过合理组合内置控制器和自定义Webhook,可以实现从简单配额管理到复杂策略引擎的全场景准入控制,建议从PodSecurity、ResourceQuota等内置控制器开始,逐步构建企业级准入治理体系。