Kubernetes API 访问控制之认证、鉴权、准入控制的介绍

45 阅读4分钟

简介

Kubernetes 自身并没有用户管理能力,无法像操作 Pod 一样,通过 API 的方式创建/删除一个用户的资源对象。

同时 Kubernetes 内置的资源对象中也没有一个是对应用户的。

当然这里就会有人问:"那 ServiceAccount 是啥呢?它不算是用户么?"。

其实,在我理解里,ServiceAccount 只能算是一种访问凭证,比如像是 Jwt 的 token,之类的东西,它没有传统意义上的用户相关的数据,如果说邮箱、手机号等等之类的。

我们如果需要访问 Kubernetes 集群的话,我们可以使用 ServiceAccount 访问,同时也可以使用 Kubernetes 为我们提供的其中一种认证方式并结合集群外的用户访问控制系统来进行认证访问,例如 ldap。

到这里,肯定也会有人有疑惑,那就是 kubectl 是通过什么方式进行访问的呢,其实 kubectl 是通过 Kubernetes 配置文件中的证书来进行认证访问的,别着急,后面我会一一的介绍到对应的各种认证方式。

img.png

认证

不管是使用 kubectl 还是通过 Client-Go 与 Kubernetes APIServer 交互的时候,都是最先进入认证这一环节的。

在认证的这一环节来校验,请求是否为一个有效的用户发送的。

同时,我们还可以配置多个认证模块,请求会依次进行认证模块的校验,只要有一个认证模块通过校验,则可进入下一环节。反之,若所有的模块都校验失败,则会给客户端发送 401 的 HTTP 状态码。

认证通过后,会解析认证信息中的用户,这个用户会作为后续步骤的决策依据。

需要注意的是,虽然 Kubernetes 通过用户来进行对 Kubernetes APIServer 请求的认证及审计,但是,正如上面说的,Kubernetes 本身是没有用户这个资源对象的,因此也无法通过 API 进行管理和查询。

当然我们也可以使用自定义 CRD 的方式,来完善一下我们缺失的这个用户相关的资源对象。

鉴权

在请求通过认证后,则会进入到鉴权这一环节,鉴权这一环节可以决定是接受还是拒绝请求。

Kubernetes 中支持多种鉴权模块,比如 Node、ABAC、RBAC、WebHook。通过配置这些鉴权模块,我们就可以进行请求的鉴权校验。

  • Node:节点鉴权是一种特殊用途的鉴权模式,专门对 kubelet 发出的 API 请求进行授权。
  • ABAC:基于属性的访问控制。
  • RBAC:基于角色的访问控制。
  • Webhook:基于 Webhook 的一种 HTTP 回调机制,通过给 URL 发送 POST 请求,进行远程鉴权管理。

鉴权同样也支持开启多个鉴权模块,如果开启多个鉴权模块,则按照顺序依次执行鉴权模块的校验,排在前面的鉴权模块有较高的优先级来允许或者拒绝请求。只要有一个鉴权模块通过,则鉴权成功。若所有鉴权模块都拒绝了请求,则会给客户端返回一个 403 的 HTTP 状态码。

准入控制

在请求通过认证和鉴权后,就进入了准入控制器环节。

准入控制器只针对创建、修改或删除资源对象的请求有效,对于只读的请求是无效的。

准入控制器也是可以配置多个的,会按照顺序依次进行调用。但是与认证和鉴权不同的是,当有任何一个准入控制器拒绝了请求,则这个请求同样会被其他准入控制器拒绝。

一旦请求通过了所有的准入控制器,则会使用相应的验证逻辑对资源对象进行验证,验证通过后,便会写入到存储中。

准入控制器的作用分为两个阶段,分别是变更验证

  • 变更(MutatingAdmission):变更用户提交的资源对象信息,例如补充一些字段的默认值。
  • 验证(ValidatingAdmission):校验用户提交的资源对象信息。

准入控制器一般是以插件的形式在 Kubernetes APIServer 中运行的。 通常在启动 APIServer 的时候通过参数的形式进行准入控制器的配置。

准入控制器根据上面的两个阶段可以划分为两种类型,一个准入控制器可能属于以上两者中的一种,也可能两者都属于。当请求到达 API Server 的时候首先执行变更准入控制,然后再执行验证准入控制。

需要注意的是,我们在部署 Kubernetes 集群的时候,通常都会默认开启一系列准入控制器,如果没有设置这些准入控制器的话,那么可以说您的 Kubernetes 集群就是在裸奔,且应该只有集群管理员可以修改集群的准入控制器。