v1.16
https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/
用户合法认证-----> 权限认证(如:rbac, node) ---------> 访问控制(Admission Control)
访问控制
用于在对象持久之前但在请求得到验证和授权之后,截取对Kubernetes API服务器的请求, 然后做一些动作。
相当于是执行操作前做的一些动作, 如:
修改请求内容, 创建相关的资源, 添加默认配置, 以及资源限制。。。。。
Kubernetes中的许多高级功能都需要启用访问控制
才能正确支持该功能。因此,未正确配置正确的访问控制器集的Kubernetes API服务器是不完整的服务器。如: LimitRanger、ResourceQuota。
v1.16 默认启动的插件:
NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, RuntimeClass, ResourceQuota
所有的插件:
AlwaysAdmit, AlwaysDeny, AlwaysPullImages, DefaultStorageClass, DefaultTolerationSeconds, DenyEscalatingExec, DenyExecOnPrivileged, EventRateLimit, ExtendedResourceToleration, ImagePolicyWebhook, LimitPodHardAntiAffinityTopology, LimitRanger, MutatingAdmissionWebhook, NamespaceAutoProvision, NamespaceExists, NamespaceLifecycle, NodeRestriction, OwnerReferencesPermissionEnforcement, PersistentVolumeClaimResize, PersistentVolumeLabel, PodNodeSelector, PodPreset, PodSecurityPolicy, PodTolerationRestriction, Priority, ResourceQuota, RuntimeClass, SecurityContextDeny, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook
这里显示的插件没有顺序关系。 在实际使用的时候顺序也很重要。
在每个请求被集群接受之前,准入控制插件依次执行。如果插件序列中任何一个拒绝了该请求,则整个请求将立即被拒绝并且返回一个错误给终端用户。
api-server启动参数:
--enable-admission-plugins
: 用来指定启用的插件。这个不是白名单,默认启动的插件就算没有指定也会启动。
--disable-admission-plugins
: 用来指定禁用的插件。
默认启用的插件只要没有禁用都会启用。
已经启用的插件可以通过apiserver的metrics接口获apiserver_admission_controller_admission_duration_seconds
的数据,如下面是在prometheus查询的。
介绍一些访问控制插件
AlwaysAdmit
:
允许所有,相当于没有访问控制, 不推荐使用。
AlwaysPullImages
:
影响镜像拉取策略,在启动容器之前总是尝试重新拉取镜像,v1.16测试发现设置pod的imagePullPolicy=Never以后照样还是会拉取镜像。
对于多租户的环境非常有用,不允许使用其他租户下载的镜像,只能去重新拉取自己的。因为镜像在同一台机器上,镜像名称相同的话就可以使用其他租户已经下载的镜像了,这对于其他租户肯定是不乐意的。
AlwaysDeny
:
拒绝所有请求,已被弃用。
DenyExecOnPrivileged
:
已废弃,合并到了DenyEscalatingExec
如果一个pod 拥有一个特权容器,这个插件将拦截所有在该 pod 中执行 exec 命令的请求。
如果集群支持特权容器,并且希望限制用户在这些容器中执行 exec 命令的能力,强烈建议启用这个插件。
DenyEscalatingExec
:
这个插件将拒绝在拥有衍生特权而具备访问宿主机能力的 pod 中执行 exec 和 attach 命令。这包括在特权模式运行的 pod ,可以访问主机 IPC 命名空间的 pod ,和访问主机 PID 命名空间的 pod 。
如果集群支持使用以衍生特权运行的容器,并且希望限制最终用户在这些容器中执行 exec 命令的能力,强烈建议启用这个插件。
启用以后执行kubectl exec
会被拒绝。
[root@k8s-master1 ~]# kubectl exec -it pods/test-serviceaccount /bin/bash
Error from server (Forbidden): pods "test-serviceaccount" is forbidden: cannot exec into or attach to a privileged container
ImagePolicyWebhook
:
ImagePolicyWebhook 插件允许使用一个后端的 webhook 程序来完成admission controller的功能。这个插件需要一个配置文件,通过--admission-control-config-file
参数指定。
ServiceAccount
:
这个插件实现了serviceaccount的自动配置以及错误提醒。 如果使用 Kubernetes 的 ServiceAccount 对象,最好都要指定。
功能如:
1、pod配置中如果没有指定serviceaccountname,会自动添加上default serviceaccount,并且挂载serviceaccount(namespace,token,ca) 到 /var/run/secrets/kubernetes.io/serviceaccount。如果没有这个插件,就算pod中指定了serviceaccountname,启动的容器里也不会挂载指定的serviceaccount。
2、pod配置中指定的serviceaccount不存在的话会报错,创建失败。 如果没有指定这个插件,不会报错。
SecurityContextDeny
:
该插件将拒绝任何试图设置SecurityContext字段的 pod。如果集群没有使用 pod 安全策略来限制安全上下文,那么应该启用这个功能。
这个securitycontext
是PodSecurityContext,pod级别的属性与安全设置,不是设置在containers
里的那个。
比如:
apiVersion: v1
kind: Pod
metadata:
labels:
app: test-serviceaccount
name: test-serviceaccount
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
containers:
- args:
- /bin/bash
- -c
- while true;do echo hello world hh;sleep 2;done
image: harbor.qfpay.net/library/qfpaypython2.7
imagePullPolicy: Always
name: test-serviceaccount
[root@k8s-master1 ~]# kubectl create -f tttt
Error from server (Forbidden): error when creating "tttt": pods "test-serviceaccount" is forbidden: pod.Spec.SecurityContext.RunAsUser is forbidden
ResourceQuota
:
资源配额,作用于namespace。跟踪所有请求,以确保请求符合 ResourceQuota
中的限制,确保在namespace上的资源配额使用不会超标。如果您在 Kubernetes 部署中使用了 ResourceQuota
,您必须使用这个插件来强制执行配额限制。
强烈建议将这个插件配置在准入控制插件序列的末尾。这样namespace所使用配额资源就不会过早地增加,然后在后面的准入控制中又被拒绝。
LimitRanger
:
确保请求符合在 Namespace
中定义的 LimitRange
对象的资源限制。如果您在 Kubernetes 中使用了 LimitRange
对象,则必须启用此插件。
NamespaceLifecycle
:
使用不存在 Namespace
的请求会被拒绝。并且删除 Namespace
会触发删除该命名空间中所有对象的操作。
DefaultStorageClass
:
对于 PersistentVolumeClaim
对象的创建,如果没有指定storage class,会自动添加默认的 storage class 。
当没有配置默认 storage class 时,这个插件不会执行任何操作。当一个以上的 storage class 被标记为默认时,拒绝 PersistentVolumeClaim
创建并返回错误,管理员必须重新检查 StorageClass
对象,并且只标记一个作为默认值。这个插件忽略了任何 PersistentVolumeClaim
更新,它只对创建起作用。
DefaultTolerationSeconds
:
这个插件设置了 pod 默认的宽恕容忍时间,对于那些没有设置宽恕容忍时间的 pod ,可以容忍 notready:NoExecute
和 unreachable:NoExecute
这些 taint 5分钟。
PodNodeSelector
:
通过读取命名空间的annotation字段和全局配置, 来对命名空间中对象的NodeSelector设置默认或限制取值。
NodeRestriction
防止 kubelet 添加/删除/更新带有 node-restriction.kubernetes.io/ 前缀的标签。
用于预防节点被污染以后恶意修改node标签, 导致pod被调度。