浅识 k8s 中的准入控制器
背景
在 k8s中各组件和kube apiserver通信时的认证和鉴权 中提到"NodeRestriction 准入插件",实际上它是一个"准入控制器"。
"准入控制器"是一个重要的概念,在 istio、apisix、某些安全产品中都有用到。
本文简要记录一下以下内容:
"准入控制器"是什么
怎么开启"准入控制器"
从源码浅析"准入控制器"
本文使用的 k8s 集群是用kubekey搭建,命令是./kk create cluster --with-kubernetes v1.21.5 --with-kubesphere v3.2.1
分析
"准入控制器"是什么?
它有点类似"插件",为 apiserver 提供了很好的"可扩展性"。
请求 apiserver 时,通过认证、鉴权后、持久化("api 对象"保存到 etcd)前,会经过"准入控制器",让它可以做"变更和验证"。
"变更"可以修改"api 对象",比如 istio 用来实现 pod 注入。"验证"可以用来校验"api 对象",比如 校验当前集群是否有足够多的资源满足"api 对象"、校验当前提交的"pod 对象"是否合法。
怎么开启"准入控制器"?
根据命令行帮助可以知道,默认会开启 17 个"准入控制器"。
也可以用--enable-admission-plugins 开启额外的"准入控制器"。
这些"准入控制器"介绍可以查看 使用准入控制器 文档。在我的实验环境中,可以看到额外开启了NodeRestriction准入控制器
,它实现了 apiserver 对 kubelet 请求的权限控制。
从源码浅析"准入控制器"
我们可以通过"断点调试"结合源码分析,验证前面说的两个结论:
请求先经过认证、鉴权,然后经过"准入控制器"
默认开启 17 个"准入控制器";加上 NodeRestriction 就是 18 个
"认证、日志审计、鉴权"在 apiserver 中都是以 filter 的形式存在,而"准入控制器"有点像包装了一层 servlet。
finishRequest 函数中会开 goroutine 调用"准入控制器"
可以看到 admissionHandler 切片长度是 18,17 个"默认开启的准入控制器"加上 NodeRestriction
部分控制器代码在 plugin/pkg/admission 目录中,会实现 Admit 接口
总结
请求先经过认证、鉴权,然后经过"准入控制器"
默认开启 17 个"准入控制器";NodeRestriction 不是默认开启的
默认开启的"准入控制器"中有两个很特殊的,ValidatingAdmissionWebhook 和 MutatingAdmissionWebhook。这两个控制器让 apiserver 有了更多的可扩展性,实现了"动态准入控制"。
文章首发于火线 Zone:https://zone.huoxian.cn/d/1255-k8s作者:leveryd
评论