原文:Extensible Admission is Beta
Kubernetes API Server 中有一个功能,能让用户(对工作负载)进行决策,这一功能在 1.9 中已经走入成熟期。
Admission 是 Kubernetes 中最强大的工具之一,可以通过限制创建对象的方式来增强 Kubernetes 集群的安全性,这部分一直是编译在代码之中的。在 1.9 中,我们将 Admission 的 Webhook 升级成 Beta,让用户可以在 API Server 之外对 Admission 施加影响。
Admission(注1),是在认证之后,资源持久化之前 的一个处理 API Server 请求的步骤。Admission 能获取到和认证过程一致的信息(用户、URL 等),以及绝大多数 API 请求的完整报文。
Admission 阶段由不同插件组成,每个 Admission 都会对一个侧面进行观察和操作。例如:影响调度决策的PodNodeSelector
、阻止恶意容器的PodSecurityPolicy
以及实现 Namespace 资源分配的ResourceQuota
。
Admission 内部分为两个阶段:
Admission 插件可以在这两个阶段起作用,但是变更总是在验证之前。
Admission 的变更功能可以在资源生成之前进行修改。在 Admission 链条上可以多次修改同一个字段,因此插件不是无序的。
PodNodeSelector
就是一个例子,他使用 Namespace 的一个注解namespace.annotations[“scheduler.alpha.kubernetes.io/node-selector”]
,在其中查找标签选择器,并将其加入pod.spec.nodeselector
字段。这一功能限制某个 Namespace 的 Pod,只能运行在指定节点上,同 Taint 的功能正好相反(也是 Admission 插件)。
Admission 的验证阶段用来对特定 API 资源进行验证。这一阶段会在所有变更执行结束之后,API 资源不再发生变化的情况下进行。
PodNodeSelector
插件同样演示了这一活动,他确保 Pod 的spec.nodeSelector
字段符合该 Namespace 的限制。如果变更链上有其他 Admission 尝试在PodNodeSelector
之后修改了资源的spec.nodeSelector
,就会在验证阶段因为不符合限制而被拒绝创建。
Admission webhook 允许 Kubernetes 安装者或集群管理员无需重新编译就可以加入 Admission 插件,像其他基于 k8s.io/apiserver 1.9 的扩展 API Server(例如 metrics(注 2), service-catalog(注 3) 、以及 kube-projects(注 4))一样。两种 Admission Webhook 都在各自的链条尾端运行,和编译的 Admission 插件具有同样的能力和限制。
Webhook Admission 插件允许对任何 API Server 的任何资源进行变更和验证,所以可能有多种形态的应用,比较普通的用例包括:
Webhook Admission 插件需要注册,所有的 API Server(Kube API server 以及所有扩展 API Server)都共享一个配置。在注册过程中插件需要提供如下信息:
如果连接失败,API Server 怎么办。
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: namespacereservations.admission.online.openshift.io
webhooks:
- name: namespacereservations.admission.online.openshift.io
clientConfig:
service:
namespace: default
name: kubernetes
path: /apis/admission.online.openshift.io/v1alpha1/namespacereservations
caBundle: KUBE_CA_HERE
rules:
- operations:
- CREATE
apiGroups:
- ""
apiVersions:
- "*"
resources:
- namespaces
failurePolicy: Fail
name
:Webhook 的名称。变更类的 Hook 会使用名称进行排序。clientConfig
:如何连接,证书信任,以及如何向 Webhook Admission 服务器发送数据。rules
:API Server 应该在什么时机调用 Webhook。这里只有创建 Namespace 的时候才触发。这里可以指定任何资源,例如serviceinstances.servicecatalog.k8s.io
的create
操作也是可以定义的。failurePolicy
:如果 Webhook Admission 服务器无法连接,如何处置?有两个选项分别是 ”Ignore“(失败就通过) 和 ”Fail“(失败就拒绝)。失败则通过的设置,可能会导致无法预测的行为。
因为 Webhoo Admission 插件能够获取任何发送过来的请求资源的内容,并且能进行变更,所以很有必要回答下面的问题:
连接主要分为三种:
要支持这些类别,Webhook Admission 插件可以用一个 kubeconfig 文件来得知如何连接到独立的服务器。为了和外部的 Admission Webook 进行通信,因为认证、授权都是外部服务器处理的,因此只能手工指定,别无他法。
自有服务来说,一个明智的插件会提供缺省的安全设施,提供简单、安全、可移植、零配置,并可以在各个 API Server 运行的能力。
如果把 Webhook Admission 服务器构建成扩展 API Server 的模式,就有可能把它聚合为一个普通的 API 服务器,会收到如下益处:
kubernetes.default.svc
(例如 https://kubernetes.default.svc/apis/admission.example.com/v1/mymutatingadmissionreviews
)服务的面目出现。可以使用kubectl
进行测试。简单说来,这一安全拓扑可以使用 API Server 的所有安全机制,并且无需额外配置。
其他用法也是可以的,不过就需要附加的手工配置,以及大量的额外工作来完成同等目标。
编写一个具有认证和鉴权能力的完整的服务是个令人生畏的任务。为简化这一工作,有些基于 Kubernetes 1.9 的项目提供了库支持,能把代码量缩减到两百行甚至更少。可以参考 generic-admission-apiserver(注 5)以及 kubernetes-namespace-reservation(注 6)作为创建自己的安全、可移植的 Webhook Server 的示例。
在 1.9 中有了 Admission Webhook,让 Kubernetes 更加贴近用户需求,我们希望 Red Hat 和 Google 的这一工作能让支持更多的工作负载,为整体生态贡献更多(例如 Istio),现在是时候试一试了!
如果有兴趣做出贡献或者反馈,请加入 SIG API machinery(注 7)
https://kubernetes.io/docs/admin/admission-controllers/#what-are-they
https://github.com/kubernetes/metrics
https://github.com/kubernetes-incubator/service-catalog
https://github.com/openshift/kube-projects
https://github.com/openshift/generic-admission-server
https://github.com/openshift/kubernetes-namespace-reservation
https://github.com/kubernetes/community/tree/master/sig-api-machinery