kubernetes Admission Control

大番茄 2019年12月11日 1,118次浏览

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查询的。

image-bce5dd30


介绍一些访问控制插件

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:NoExecuteunreachable:NoExecute 这些 taint 5分钟。

PodNodeSelector:

通过读取命名空间的annotation字段和全局配置, 来对命名空间中对象的NodeSelector设置默认或限制取值。

NodeRestriction

防止 kubelet 添加/删除/更新带有 node-restriction.kubernetes.io/ 前缀的标签。

用于预防节点被污染以后恶意修改node标签, 导致pod被调度。