Kubernetes学习笔记——基于API Server的安全机制浅析

集群安全机制的目标

  • 隔离性,限制容器给集群带来的副作用
  • 最小权限原则
  • 组件的边界划分需要明确
  • 角色划分和权限分配

关于API Server

API Server作为集群控制请求的实际入口,通常暴露了两个端口——本地端口(Localhost Por)和安全端口(Secure Port)。

本地端口 安全端口
使用场景 测试和启动时使用,Master节点中不同组件通信 任意场景
安全协议 TLS
端口 默认8080,
insecure-port
修改 默认6443,
secure-port
修改
IP 默认localhost,
insecure-bind-address
修改 默认为第一个非localhost网卡地址,
bind-address
修改
处理流程 无需认证和授权 需要认证和授权
准入控制
访问控制 需要拥有主机访问权限 需要认证和授权模块正常运行

注:TLS中,证书和私钥相关参数为tls-cert-filetls-private-key-file
访问API Server的方式有kubectl,客户端的库和Rest请求。通常来说,想在外部访问API Server需要通过安全端口访问。通过安全端口访问需要经过三重校验,即Authentication(身份认证),Authorization(授权)和Admission Control(准入控制)。

Authentication(身份认证)

Authentication is the act of confirming the truth of an attribute of a single piece of data claimed true by an entity.
From: https://en.wikipedia.org/wiki/Authentication
通俗的来说,身份认证解决的是“让系统/服务端知道你是谁”的问题,即对用户身份的确认。值得注意的是,Wikipedia中还特别标注“ Not to be confused with authorization.
对于身份的认证,现实生活中可能是查验证件,也可能是对暗号。

对应的,在Kubernetes中,也有对应的几种客户端身份认证方式:

  • 证书认证:基于CA根证书签名的双向数字证书认证方式;
  • Token认证:通过Token来认证;
  • 用户密码:通过用户密码的方式认证;

可以同时指定多个身份认证模块,在流程中将会以顺序执行的方式进行认证过程,直到其中一个认证模块认证成功。如果请求认证失败,则会返回401状态码。(PS:这里引入了一个401状态码的历史遗留问题——401的语义其实应该是Unauthenticated)

一旦认证成功,用户就会被分配一个特定的username。在随后的访问控制流程中,这个username将会一直使用。尽管如此,这个username却也不会对应存在一个真实的用户对象,该信息也不会被存储。

(我的理解:这个所谓的username的存在仅仅是为了在整个访问控制流程中能够进行上下文信息的传递,完成一个链式的验证。和传统意义上的用户相比,K8S的访问控制基于单次的请求,在请求的过程中抽象来决定行为的合法性和有效性。)

Authorization(授权)

Authorization is the function of specifying access rights/privileges to resources, which is related to information security and computer security in general and to access control in particular.
From: https://en.wikipedia.org/wiki/Authorization
与身份认证不同的是,授权关注的是对资源的访问控制,通俗的说就是“系统要知道你这个身份能够做什么”。

当请求通过了身份认证之后,请求才会进入授权流程。请求的内容包含三个部分:用户名(username of the requester),动作( requested action),动作影响的对象(the object affected by the action)。在已有的多种授权策略中,只要有一个能够声明此用户有执行对应动作的权限,则请求就被授权成功。若所有授权策略全部失败,则返回403状态码。
授权模块的种类:

  • ABAC
  • RBAC
  • Node
  • Webhook

Admission Control(准入控制)

通过认证和授权流程之后,请求的调用还需要通过准入控制链的检查。与上述模块不同,准入控制能够修改请求参数完成一些任务。
当多个准入控制模块配置完毕后,请求的调用会依次按顺序进行检查。一旦任意一个准入控制模块检查不通过,则请求立即被拒绝。而请求完成了所有检查后,会采用相应API对象的验证流程对请求进行验证,然后写入对象库。

Once a request passes all admission controllers, it is validated using the validation routines for the corresponding API object, and then written to the object store (shown as step 4).

总结

从整体来看,Kubernetes对于API Server的请求主要分为两大部分:内部和外部。
内部是指在master节点使用kubectl命令进行操作,这时,因为是在节点内部操作,因此并不会使用安全端口,直接采用localhost这个ip上的非安全端口进行访问。
而对于API Server的外部请求调用(包括Pod和Rest请求),则需要使用安全端口进行访问。通过安全端口的请求,需要进行严格的三层校验才能调用成功。这就通过确保只执行权限内允许的操作保证了集群操作的安全性。
关于每个部分的详细介绍,会单独抽成三部分继续分解。