前面说了k8s如何做认证,如何做鉴权,分别判断你是谁,你有什么样的操作权限,你有某个对象的操作权限但是并不代表这个对象是合法的,所以apiserver里面会有更加深层次的一个行为,它还是需要去校验你的对象,这个环节叫做准入。

为资源增加自定义属性


  • 作为多租户集群方案中的一环,我们需要在 namespace的准入控制中,获取用户信息,并将用户信息更新的namespace的annotation。
  • 只有当namespace中有有效用户信息时,我们才可以在namespace创建时,自动绑定用户权限,namespace才可用。

准入控制通常有两种主要的目的,一个是你给了我request,这个request长的这个样子,是你填的所有的属性,但是我从平台的一个层面,我希望给它添加一些附加属性。比如说有些值你没有赋值,我希望给它默认值,或者对其中某些值做调整,那么需要对原始对象去做变形的,也就是增加自定义属性。

还有一种方式就是做完变形之后,或者不变形,不管变不变行我都要去校验你这个对象是否是合法的,包括你自身是不是合法,同时在集群内部的请求是不是合法的。

准入控制使用场景


一个最常用的场景就是配额管理,为什么要做配额管理呢?通常一个集群的管理规模和承受能力是有上线的,集群的计算资源也是有限的。如果将集群给出去,不可能让用户无休止的创建对象,这个是需要管控的,将资源均分。 

作为多租户的集群,希望使用配额来做管控来控制谁能够使用多少计算资源。

其次etcd里面有存储配额,它有自己的存储上限,那么就不能让每个用户都无休止的创建对象,创建100w,200w个的话,那么etcd的配额很快就会用完。

Kubernetes API Server 准入控制_自定义

超出了配额和认证鉴权没有关系,是准入控制环节出现了问题。

如果对每个namespace都创建resourcequota,那么就能够精确的控制namespace建立多少个对象。这样就能够合理的分配集群的资源。

准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数。不同于授权和认证只关心请求的用户和操作,准入控制还处理请求的内容,并且仅对创建、更新、删除或连接(如代理)等有效,而对读操作无效。

准入控制支持同时开启多个插件,它们依次调用,只有全部插件都通过的请求才可以放过进入系统。

准入插件


Kubernetes API Server 准入控制_自定义_02

AlwaysPullImages:总是拉取最新镜像,这个准入控制插件自动的更改你的ImagePullPolicy,只要你的pod一创建就将其改为always。

ImagePolicyWebhook:webhook来决定这个image是不是合法的,这个用于场景通常容器镜像要去做安全扫描,基于安全软件来扫描容器镜像是不是安全的,扫描完之后会出一个结果,这个结果存放在系统里面说这个镜像是否安全,ImagePolicyWebhook就是在建立pod的时候来看容器镜像扫描是不是过了,它的结果通过还是失败,失败就拦截下来。

Kubernetes API Server 准入控制_kubernetes_03

LimitRanger:一个pod我希望去限制你某个namespace pod所申请的最高资源,限制申请资源的上线和下线,以及它的默认值。

当你创建pod的时候就会去校验你的pod里面资源指定的情况,然后和LimitRanger对象做个整合,是给你塞一个默认值呢还是已经塞好的资源是不是合法。

可以看到有些插件是enable的,有些插件是disable的

Kubernetes API Server 准入控制_默认值_04

准入控制插件的开发


如果默认的插件没有办法满足我的需求,希望在此基础之上做额外的配置,我有自定义的逻辑,有没有什么样的扩展方法。 kubernetess认证,鉴权都支持webhook,那么准入的环节也支持webhook的。

除默认的准入控制插件以外,Kubernetes 预留了准入控制插件的扩展点,用户可自定义准入控制插件实现自定义准入功能。

准入插件有两种,如下:

MutatingWebhookConfiguration∶变形插件,支持对准入对象的修改。(给对象的属性做修改的,它可以修改你的对象)

ValidatingWebhookConfiguration∶校验插件,只能对准入对象合法性进行校验,不能修改。(不修改对象,只做校验,)

Kubernetes API Server 准入控制_用户信息_05

当一个对象结果认证鉴权之后,到了apiserver这里,apiserver会去看admission的配置了,这个配置发现有对应的webhook,它就会往webhook发起一个admission review的request,你要去解析这个admission review,将request拿出来。

如果是mutating webhook,你可能要在原始对象基础上面,它admissionreview基本上就是把整个request都发个你了,比如说是一个pod,那么你就在pod基础上面做一些属性的修改。

修改完之后就要真正的去做校验,所以mutating会先运行,validating会后运行,会去校验变形之后的对象是否合法,validating返回一个是否通过这样的结果给apiserver,apiserver通过之后将这个请求往下传递。

Kubernetes API Server 准入控制_自定义_06

现在k8s支持了MutatingWebHookConfiguration和ValidatingWebHookConfiguration 这两个对象,在这个对象里面就可以定义告诉apiserver我要去mutating,正真要去做mutating的时候这个请求应该发送到哪里去,rules是针对什么样的对象什么操作,比如针对node的create操作去做mutating。

所以通过这种配置,就将整个apiserver这端的配置完成了。

这里面对mutating validating的webhook都有限制,凡是admission的webhook都必须起https的服务,不允许明文的访问。

既然是https的服务,这里就有cabundle,你server端是自签名的证书,那么你要将它对应的ca填在这里面。也就是将server的ca做个base64的encode填在这个cabundle。这样apiserver才能够合法的去访问后端,否则认为后端的服务是不可信任的。