当你在k8s集群中一个不存在的namespace中创建一个pod,会返回一个namespace not found类似的错误,你有想过这个是哪个组件完成的吗?对就是admission plugin。
从控制器说起
什么是准入插件,在APIServer中有这样一个参数--enable-admission-plugins
,用于对创建的对象的合理性进行验证和二次修改。可选的参数如下所示:
- AlwaysAdmit, # 一直允许
- AlwaysDeny, # 一直禁止
- AlwaysPullImages, # 在启动容器之前总是去下载镜像,相当于每当容器启动前做一次用于是否有权使用该容器镜像的检查
- DefaultStorageClass, # 默认的sc
- DefaultTolerationSeconds,
- DenyEscalatingExec, # 拒绝exec和attach命令到有升级特权的Pod的终端用户访问。如果集中包含升级特权的容器,而要限制终端用户在这些容器中执行命令的能力,推荐使用此插件
- DenyExecOnPrivileged,
- EventRateLimit, # event 限流
- ExtendedResourceToleration,
- ImagePolicyWebhook,
- LimitPodHardAntiAffinityTopology,
- LimitRanger, # 默认资源限额,用于Pod和容器上的配额管理,它会观察进入的请求,确保Pod和容器上的配额不会超标。准入控制器LimitRanger和资源对象LimitRange一起实现资源限制管理
- MutatingAdmissionWebhook, # 授权后的webhook
- NamespaceAutoProvision,
- NamespaceExists,# 命名空间是否存在
- NamespaceLifecycle, # 当一个请求是在一个不存在的namespace下创建资源对象时,该请求会被拒绝。当删除一个namespace时,将会删除该namespace下的所有资源对象
- NodeRestriction,
- OwnerReferencesPermissionEnforcement,
- PersistentVolumeClaimResize, # PVC 扩容
- PersistentVolumeLabel, # PVC标签
- PodNodeSelector,# pod 节点选择器
- PodPreset, # 向namespace注入变量和存储
- PodSecurityPolicy, # pod安全策略
- PodTolerationRestriction,
- Priority, # 调度策略?
- ResourceQuota, # 用于namespace上的配额管理,它会观察进入的请求,确保在namespace上的配额不超标。推荐将这个插件放到准入控制器列表的最后一个。ResourceQuota准入控制器既可以限制某个namespace中创建资源的数量,又可以限制某个namespace中被Pod请求的资源总量。ResourceQuota准入控制器和ResourceQuota资源对象一起可以实现资源配额管理
- SecurityContextDeny, # 将Pod定义中定义了的SecurityContext选项全部失效。SecurityContext包含在容器中定义了操作系统级别的安全选型如fsGroup,selinux等选项
- ServiceAccount, #这个插件实现了serviceAccounts等等自动化,如果使用ServiceAccount对象,强烈推荐使用这个插件
- StorageObjectInUseProtection,
- TaintNodesByCondition,
- ValidatingAdmissionWebhook.
Webhokk控制器主要作用在授权和认证之后,持久化到etcd之前。本文主要介绍的是MutatingAdmissionWebhook和ValidatingAdmissionWebhook,如下图所示:
作用
安全
可以通过在整个命名空间或集群中强制使用合理的安全基准来提高安全性。 内置的PodSecurityPolicy控制器可能是最突出的例子; 例如,它可以用于禁止容器以root身份运行,或者确保容器的根文件系统始终以只读方式挂载。 可通过基于webhook的自定义准入控制器实现的其他用例包括: 拒绝不符合安全标准的deployment,例如使用privileged标志的容器可以规避许多安全检查。 基于webhook的准入控制器可以减轻此风险,该准入控制器拒绝此类部署(验证)或覆盖privileged标志,将其设置为false 。
治理
控制器可以强制遵守某些做法,例如具有良好的标签,注释,资源限制或其他设置。 一些常见的场景包括: 对不同对象强制执行标签验证,以确保将正确的标签用于各种对象,例如分配给团队或项目的每个对象,或指定应用程序标签的每个部署。 自动向对象添加注释,例如为“dev”部署资源分配正确的成本中心。
配置管理
验证群集中运行的对象的配置,并防止任何明显的错误配置命中群集。 可用于检测和修复没有语义标签的部署图像,例如: 自动添加资源限制或验证资源限制, 确保合理的标签被添加到pod,或 确保生产部署中使用的图像引用不使用latest标记或带有-dev后缀的标记。
示例
https://github.com/stackrox/admission-controller-webhook-demo
Ref
A Guide to Kubernetes Admission Controllers
https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/
Kubernetes 中如何保证优雅地停止 Pod
https://pingcap.com/blog-cn/tidb-opeartor-webhook/
深度剖析Kubernetes动态准入控制之Initializers