# k8s 使用准入控制器(Admission Controllers)

准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数,在对 k8s api 服务器的请求过程中,先经过认证、授权后,执行准入操作,在对目标对象进行操作。这个准入插件代码在 apiserver 中,而且必须被编译到二进制文件中才能被执行。

在对集群进行请求时,每个准入控制插件都按顺序运行,只有全部插件都通过的请求才会进入系统,如果序列中的任何插件拒绝请求,则整个请求将被拒绝,并返回错误信息。

在某些情况下,为了适用于应用系统的配置,准入逻辑可能会改变目标对象。此外,准入逻辑也会改变请求操作的一部分相关资源。

# 为什么需要准入控制?

在 k8s 中,一些高级特性正常运行的前提条件为,将一些准入模块处于 enable 状态。总结下,对于 k8s apiserver,如果不适当的配置准入控制模块,他就不能称作是一个完整的 server,某些功能也不会正常的生效。

# 如何运行准入控制插件?

在 k8s apiserver 中有一个 flag:admission_control,他的值为一串用逗号连接起、有序的准入模块列表,设置后,就可在对象操作前执行一定顺序的准入模块调用。

# 每个插件都做什么的?

# AlwaysAdmit

结束所有的请求。

# AlwaysPullImages

该插件修改每个新的 Pod,强制 pull 最新镜像,这在多租户群集中非常有用,以便私有镜像只能由拥有授权凭据的用户使用。

# AlwaysDeny

拒绝所有请求,一般用于测试。

# DenyExecOnPrivileged(已弃用)

该插件将拦截所有请求。如果 pod 有一个 privileged container,将只执行这个 pod 中的命令。 如果自己的集群支持 privileged container,自己又希望限制用户在这些 privileged container 上执行命令,那么强烈推荐使用它。

此功能已合并到 DenyEscalatingExec 中。

# DenyEscalatingExec

禁止 privileged container 的 exec 和 attach 操作。

# ImagePolicyWebhook

通过 webhook 决定 image 策略,需要同时配置--admission-control=ImagePolicyWebhook,配置文件格式如下。

# 配置文件格式

ImagePolicyWebhook 使用 admission 配置文件--admission-control-config-file 为 Backend Behavior 设置配置选项。该文件可以是 json 或 yaml 并具有以下格式:

{
  "imagePolicy": {
     "kubeConfigFile": "path/to/kubeconfig/for/backend",
     "allowTTL": 50,           // time in s to cache approval
     "denyTTL": 50,            // time in s to cache denial
     "retryBackoff": 500,      // time in ms to wait between retries
     "defaultAllow": true      // determines behavior if the webhook backend fails
  }
}

配置文件必须引用一个 kubeconfig 格式的文件,该文件设置与后端的连接,通过 TLS 进行通信。

kubeconfig 文件的集群字段须指向 remote service,users 字段须包含 returned authorizer。

# clusters refers to the remote service.
clusters:
- name: name-of-remote-imagepolicy-service
  cluster:
    certificate-authority: /path/to/ca.pem    # CA for verifying the remote service.
    server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.

# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
  user:
    client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
    client-key: /path/to/key.pem          # key matching the cert

其他 HTTP 配置,请参考 kubeconfig 文档。

# ServiceAccount

该插件将 serviceAccounts 实现了自动化。如果打算使用 k8s ServiceAccount 对象,那么强烈建议使用此插件。

# SecurityContextDeny

该插件会将使用了 SecurityContext 的 pod 中定义的选项全部失效。

# ResourceQuota

该插件将会观察传入的所有请求,并确保它不会违反 ResourceQuota 对象中枚举的任何限制 Namespace。如果在 k8s Deployment 中使用了 ResourceQuota 对象,则必须使用此插件来约束 Container。

更多详细信息,请参阅 resourceQuota design doc 和 example of Resource Quota。

推荐在 Admission Control 参数列表中,这个插件排最后一个。

# LimitRanger

该插件将会观察传入的所有请求,并确保它不会违反 LimitRanger 对象中枚举的任何限制 Namespace,如果在 k8s Deployment 中使用了 LimitRanger 对象,则必须使用此插件。LimitRanger 还可使用 Apply 将 default 资源请求不指定任何的 Pods; 目前 LimitRanger 对 Default Namespace 中的所有 pod 应用要求 0.1 CPU

更多详细信息,请参阅 limitRange design doc 和 example of Limit Range。

# InitialResources(试验)

根据镜像的历史使用记录,为容器设置默认资源请求和 limits。

更多详细信息,参考 InitialResouces proposal。

# NamespaceLifecycle

该插件确保处于 Termination 状态的 Namespace 不再接收新的对象创建请求,并拒绝请求不存在的 Namespace。该插件还可以防止删除系统保留的 Namespace:default,kube-system,kube-public。

# DefaultStorageClass

该插件将观察 PersistentVolumeClaim,并自动设置默认的 Storage Class。

当没有配置默认 Storage Class 时,此插件不会执行任何操作。当有多个 Storage Class 被标记为默认值时,它也将拒绝任何创建,管理员必须重新访问 StorageClass 对象,并且只标记一个作为默认值。此插件不用于 PersistentVolumeClaim 的更新,仅用于创建。

更多详细信息,参考 persistent volume。

# DefaultTolerationSeconds

该插件设置 Pod 的默认 forgiveness toleration 为 5 分钟。

# PodSecurityPolicy

该插件用于创建和修改 pod,使用 Pod Security Policies 时需要开启。

当 Kubernetes <1.6.0 版本时,API 服务器需要启用扩展名/ v1beta1 / podsecuritypolicy API 扩展组(--runtime-config=extensions/v1beta1/podsecuritypolicy=true)。

更多信息,请参考 Pod Security Policy documentation。

# NodeRestriction

此插件限制 kubelet 修改 Node 和 Pod 对象,这样的 kubelets 只允许修改绑定到 Node 的 Pod API 对象,以后版本可能会增加额外的限制。

限制 kubelet 仅可访问 node、endpoint、pod、service 以及 secret、configmap、PV 和 PVC 等相关的资源(仅适用于 v1.7+)

# 不同版本推荐使用的一组插件?

对于 Kubernetes> = 1.6.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds

对于 Kubernetes> = 1.4.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota

对于 Kubernetes> = 1.2.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota

对于 Kubernetes> = 1.0.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAcco
Last Updated: 4/15/2023, 8:33:17 PM