Kubernetes通过一系列机制来实现集群的安全控制,其中包括API Server的认证授权、准入控制机制及保护敏感信息的Secret机制等。集群的安全性主要有如下目标:
Kubernetes集群中所有资源的访问和变更都是通过Kubernetes API Server的RESTAPI来实现的,因此集群安全的关键点就在于如何识别并认证客户端身份(Authentication),以及随后访问权限的授权(Authorization)环节。
Kubernetes集群提供了3种级别的客户端身份认证方式。
此方式需要有一个CA证书,CA是PKI系统中通信双方都信任的实体,被称为可信第三方(TrustedThirdParty,TTP)。CA作为可信第三方的重要条件之一就是CA的行为具有非否认性。作为第三方而不是简单的上级,就必须能让信任者有追究自己责任的能力。
CA通过证书证实他人的公钥信息,证书上有CA的签名。用户如果因为信任证书而有了损失,则证书可以作为有效的证据用于追究CA的法律责任。正是因为CA承担责任的承诺,所以CA也被称为可信第三方。
在很多情况下,CA与用户是相互独立的实体,CA作为服务提供方,有可能因为服务质量问题(例如,发布的公钥数据有错误)而给用户带来损失。在证书中绑定了公钥数据和相应私钥拥有者的身份信息,并带有CA的数字签名;在证书中也包含了CA的名称,以便于依赖方找到CA的公钥,验证证书上的数字签名。
CA认证涉及诸多概念,比如根证书、自签名证书、密钥、私钥、加密算法及HTTPS等。
如下大致为SSL协议的流程,在Kubernetes CA中认证大概包含下面几个步骤:
上述是双向认证SSL协议的具体通信过程,这种情况要求服务器和用户双方都有证书。单向认证SSL协议则不需要客户端拥有CA证书,对于上面的步骤,只需将服务器端验证客户证书的过程去掉,之后协商对称密码方案和对称通话密钥时,服务器发送给客户的密码没被加密即可。
HTTP Token的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串—Token来表明客户身份的一种方式。在通常情况下,Token是一个很复杂的字符串,比如我们用私钥签名一个字符串后的数据就可以被当作一个Token。此外,每个Token对应一个用户名,存储在API Server能访问的一个文件中。当客户端发起API调用请求时,需要在HTTP Header里放入Token,这样一来,API Server就能识别合法用户和非法用户了。
通常,HTTP是无状态的,浏览器和Web服务器之间可以通过Cookie来进行身份识别。桌面应用程序(比如新浪桌面客户端、SkyDrive客户端、命令行程序)一般不会使用Cookie,若需要与Web服务器之间通信并且进行认证。则需要使用HTTP Base认证,这种认证方式是把“用户名+冒号+密码”用BASE64算法进行编码后的字符串放在HTTP Request中的Header Authorization域里发送给服务端,服务端在收到后进行解码,获取用户名及密码,然后进行用户身份鉴权。
当客户端发起API Server调用时,API Server内部要先进行用户认证,然后执行用户授权流程,即通过授权策略来决定一个API调用是否合法。对合法用户进行授权并且随后在用户访问时进行鉴权,是权限与安全系统的重要一环。
授权就是授予不同的用户不同的访问权限。
API Server目前支持以下几种授权策略(通过API Server的启动参数“--authorization-mode”设置):
API Server在接收到请求后,会读取该请求中的数据,生成一个访问策略对象,如果在该请求中不带某些属性(如Namespace),则这些属性的值将根据属性类型的不同,设置不同的默认值(例如,为字符串类型的属性设置一个空字符串;为布尔类型的属性设置false;为数值类型的属性设置0)。然后将这个访问策略对象和授权策略文件中的所有访问策略对象逐条匹配,如果至少有一个策略对象被匹配,则该请求被鉴权通过,否则终止API调用流程,并返回客户端的错误调用码。
在API Server启用ABAC模式时,需要指定授权策略文件的路径和名称(--authorization-policy-file=SOME_FILENAME),授权策略文件里的每一行都以一个Map类型的JSON对象进行设置,这被称为“访问策略对象”。通过设置访问策略对象中的apiVersion、kind、spec属性来确定具体的授权策略。
其中,apiVersion当前版本为abac.authorization.kubernetes.io/v1beta1;kind被设置为Policy;spec指详细的策略设置,包括主题属性、资源属性、非资源属性这三个字段。
API Server进行ABAC授权的算法为:在API Server收到请求之后,首先识别出请求携带的策略对象的属性,然后根据在策略文件中定义的策略对这些属性进行逐条匹配,以判定是否允许授权。如果有至少一条匹配成功,那么这个请求就通过了授权(不过还是可能在后续其他授权校验中失败)。
常见的策略配置如下:
kubectl使用API Server的/api和/apis端点来获取版本信息。要验证kubectlcreate/update命令发送给服务器的对象,kubectl需要向OpenAPI进行查询,对应的URL路径为/openapi/v2。
当使用ABAC授权模式时,下列特殊资源必须显式地通过nonResourcePath属性进行设置:
在使用kubectl操作时,如果需要查看发送到API Server的HTTP请求,则可以将日志级别设置为8。
更多ABAC参考:《附007.Kubernetes ABAC授权》。
见《附006.Kubernetes RBAC授权》