【K8s】集群安全机制(三):准入控制

前两篇已经把认证和授权讲清楚了:

认证解决"你是谁",授权解决"你能干什么"。这篇要讲的是最后一道关卡------你这样做,合不合理?


目录

  • 一、什么是准入控制

  • 二、两大核心机制:Mutating & Validating

  • 三、准入控制完整流程

  • 四、常见准入控制器解析

  • 五、实战配置示例

  • 六、插件管理操作

  • 七、踩坑经验总结

  • 八、总结


一、什么是准入控制

先说一个很多人的误区:

"通过了 RBAC 就能操作资源"

实际上不对。请求进入 API Server 的完整路径是这样的:

复制代码
请求 → 认证 → 授权 → 准入控制 → 写入 etcd

准入控制是最后一道拦截层,处理的是"合法但不合理"的场景。


两类插件

准入控制器本质上是一组插件,分为两类:

类型 作用
功能增强型 为请求补充默认值、注入字段
规则校验型 检查请求是否符合规则,不合规直接拒绝

重要:读取请求不经过准入控制

getlistwatch 这些操作会绕过准入控制层,只有变更类操作(创建、修改、删除)才会被拦截。


二、两大核心机制


2.1 Mutating(变更型)

可以修改请求内容

常见用途:自动补充资源限制(CPU / Memory)、自动注入 sidecar、自动挂载 ServiceAccount、添加默认 label / annotation。


2.2 Validating(验证型)

只做判断,不能修改,要么放行,要么拒绝。

常见用途:超出配额拒绝、namespace 不存在拒绝、安全策略不合规拒绝。


有些控制器两者兼具

比如 LimitRanger:先补默认值(Mutating),再校验是否超限(Validating)。


三、准入控制完整流程

执行顺序固定:

复制代码
Mutating 阶段 → Validating 阶段 → 写入 etcd

有几点需要注意:

① 任何一个控制器拒绝,整个请求立即失败

不会继续走后续步骤,直接返回错误给调用方。

② Validating 看到的是"改完之后"的资源

因为 Mutating 先跑,所以验证阶段拿到的已经是补完默认值的资源。

③ 部分控制器有副作用

有些控制器在处理过程中会创建资源(比如更新配额)。如果后续被其他控制器拒绝,这些副作用不会自动回滚,需要配套的清理机制。这是生产环境中比较容易踩坑的地方。


四、常见准入控制器解析


4.1 LimitRanger

类型:Mutating + Validating

两件事:检查资源请求是否在 LimitRange 约束范围内;为没有设置资源限制的 Pod 自动补默认值。

比如你创建了一个 Pod,没写 resources.limits,LimitRanger 会自动帮你填上,不会报错也不会让容器无限制跑。


4.2 ResourceQuota

类型:Validating

控制 namespace 级别的资源总量上限。如果创建请求会导致超配额,直接拒绝。

复制代码
创建 Pod → 校验 namespace 已用量 + 新增用量 > 配额 → 拒绝

这是防止某个 namespace "撑爆集群"的核心手段。


4.3 NamespaceLifecycle

类型:Validating

三个职责:禁止在正在删除中的 namespace 里创建新资源;禁止操作不存在的 namespace;禁止删除系统保留 namespace(defaultkube-systemkube-public)。

这个一般不会主动关,关了容易出问题。


4.4 NamespaceExists

类型:Validating

确保请求中引用的 namespace 已经存在(注意:它不检查 Namespace 资源对象本身)。


4.5 ServiceAccount

类型:Mutating + Validating

主要做两件事:如果 Pod 没指定 SA,自动挂载 default ServiceAccount;确保指定的 SA 存在。

前文提过每个 namespace 都有一个 default SA,就是这个控制器自动创建的。


五、实战配置示例


场景 1:限制单个容器资源范围

复制代码
apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limit
  namespace: dev
spec:
  limits:
  - type: Container
    default:
      cpu: 200m
      memory: 256Mi
    defaultRequest:
      cpu: 100m
      memory: 128Mi
    max:
      cpu: "1"
      memory: 1Gi

效果:没写资源限制的容器自动补 100m CPU / 128Mi 内存;超过 1核 / 1G 的请求直接拒绝创建。


场景 2:限制 namespace 资源总量

复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    pods: "20"
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"

超配额时会看到这类报错:

复制代码
Error from server (Forbidden): exceeded quota: dev-quota

场景 3:安全策略(Pod Security)

高版本 K8s 推荐直接用 PodSecurity 准入控制器,通过 namespace label 控制安全级别:

复制代码
kubectl label namespace dev \
  pod-security.kubernetes.io/enforce=restricted

效果:该 namespace 内禁止特权容器、禁止 root 用户运行、强制只读根文件系统。


六、插件管理操作


查看支持的插件

复制代码
kube-apiserver -h | grep enable-admission-plugins

查看当前启用的插件

复制代码
ps -ef | grep kube-apiserver | grep admission

启用插件

复制代码
kube-apiserver \
  --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ResourceQuota

禁用插件

复制代码
kube-apiserver \
  --disable-admission-plugins=PodNodeSelector

K8s 1.35 默认启用插件列表

复制代码
CertificateApproval, CertificateSigning, CertificateSubjectRestriction,
DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds,
LimitRanger, MutatingAdmissionWebhook, NamespaceLifecycle,
PersistentVolumeClaimResize, PodSecurity, Priority, ResourceQuota,
RuntimeClass, ServiceAccount, StorageObjectInUseProtection,
TaintNodesByCondition, ValidatingAdmissionPolicy, ValidatingAdmissionWebhook

一般不建议随意禁用默认启用的插件,尤其是 NamespaceLifecycleResourceQuotaServiceAccount


七、踩坑经验总结


1)准入控制不等于权限控制

两者经常被混淆,区别如下:

机制 解决的问题
RBAC 有没有权限做这件事
准入控制 这件事做得对不对

用户有权限创建 Pod,不等于这个 Pod 可以被成功创建。


2)LimitRange 和 ResourceQuota 要配套用

只配 ResourceQuota,不配 LimitRange:Pod 没写资源请求,配额计算为 0,直接绕过了配额限制。两个一起配,才能真正控住。


3)Webhook 型控制器风险大

MutatingAdmissionWebhook / ValidatingAdmissionWebhook 虽然灵活,但 Webhook 服务挂了会导致所有请求卡住,配置错误会让集群资源全部无法创建。

建议:设置合理的 failurePolicyIgnoreFail);Webhook 服务本身要保证高可用。


4)副作用问题

某些控制器会在处理中创建资源(比如自动创建 SA、更新配额计数)。如果后续阶段拒绝了请求,这些副作用不会自动回滚。这类场景要特别注意清理逻辑,否则时间长了会产生"脏数据"。


5)调试失败请求看这两个地方

复制代码
# 看事件
kubectl get events -n dev

# 看详细原因
kubectl describe pod <pod-name> -n dev

八、总结

这篇核心就一句话:

准入控制 = 请求写入 etcd 前的最后一道规则校验

核心要点回顾:不拦截读取请求(get/list/watch 直接绕过);两阶段执行,Mutating 先改,Validating 再验;任意阶段拒绝则整个请求失败;部分控制器有副作用,需要关注清理;LimitRanger 和 ResourceQuota 要配套使用。

三道关卡串起来:

阶段 解决的问题
认证 你是谁
授权 你能干什么
准入控制 你这样做合不合理

RBAC 控制边界,准入控制把守细节。

相关推荐
志栋智能1 小时前
超自动化巡检的核心价值:效率、质量与洞察
运维·服务器·网络·人工智能·自动化
恶猫2 小时前
自动拨号换ip软件简单实现。aardio版。
java·网络·aardio·adsl·换ip·rasphone.exe·rasdial.exe
Hello_Embed2 小时前
嵌入式上位机开发入门(二十八):JSON 与 JsonRPC 入门
网络·笔记·网络协议·tcp/ip·嵌入式
代码羊羊2 小时前
Rust-特征trait和特征对象
服务器·网络·rust
minji...2 小时前
Linux 网络套接字编程(一)端口号port,socket套接字,socket,bind,socket 通用结构体
linux·运维·服务器·开发语言·网络
七七powerful2 小时前
Kubernetes 弹性伸缩(HPA)设计思想深度解析
云原生·容器·kubernetes
SPC的存折2 小时前
Cisco Packet Tracer 8.0 上的 VLAN 综合实验报告
运维·网络
yuezhilangniao2 小时前
告别网络排障恐惧症-告别UI版wireshark:用 curl + tcpdump + tshark + ss 构建完整工具链 - 含TCPIP老鸟常识
网络·wireshark·tcpip