1.4.5 安全类
安全始终是Kubernetes发展过程中的一个关键领域。
从本质上来说,Kubernetes可被看作一个多用户共享资源的资源管理系统,这里的资源主要是各种Kubernetes里的各类资源对象,比如Pod、Service、Deployment等。只有通过认证的用户才能通过Kubernetes的API Server查询、创建及维护相应的资源对象,理解这一点很关键。
Kubernetes里的用户有两类:我们开发的运行在Pod里的应用;普通用户,如典型的kubectl命令行工具,基本上由指定的运维人员(集群管理员)使用。在更多的情况下,我们开发的Pod应用需要通过API Server查询、创建及管理其他相关资源对象,所以这类用户才是Kubernetes的关键用户。为此,Kubernetes设计了Service Account这个特殊的资源对象,代表Pod应用的账号,为Pod提供必要的身份认证。在此基础上,Kubernetes进一步实现和完善了基于角色的访问控制权限系统——RBAC(Role-Based Access Control)。
在默认情况下,Kubernetes在每个命名空间中都会创建一个默认的名称为default的Service Account,因此Service Account是不能全局使用的,只能被它所在命名空间中的Pod使用。通过以下命令可以查看集群中的所有Service Account:
Service Account是通过Secret来保存对应的用户(应用)身份凭证的,这些凭证信息有CA根证书数据(ca.crt)和签名后的Token信息(Token)。在Token信息中就包括了对应的Service Account的名称,因此API Server通过接收到的Token信息就能确定Service Account的身份。在默认情况下,用户创建一个Pod时,Pod会绑定对应命名空间中的default这个Service Account作为其“公民身份证”。当Pod里的容器被创建时,Kubernetes会把对应的Secret对象中的身份信息(ca.crt、Token等)持久化保存到容器里固定位置的本地文件中,因此当容器里的用户进程通过Kubernetes提供的客户端API去访问API Server时,这些API会自动读取这些身份信息文件,并将其附加到HTTPS请求中传递给API Server以完成身份认证逻辑。在身份认证通过以后,就涉及“访问授权”的问题,这就是RBAC要解决的问题了。
首先我们要学习的是Role这个资源对象,包括Role与ClusterRole两种类型的角色。角色定义了一组特定权限的规则,比如可以操作某类资源对象。局限于某个命名空间的角色由Role对象定义,作用于整个Kubernetes集群范围内的角色则通过ClusterRole对象定义。下面是Role的一个例子,表示在命名空间default中定义一个Role对象,用于授予对Pod资源的读访问权限,绑定到该Role的用户则具有对Pod资源的get、watch和list权限:
接下来就是如何将Role与具体用户绑定(用户授权)的问题了。我们可以通过RoleBinding与ClusterRoleBinding来解决这个问题。下面是一个具体的例子,在命名空间default中将“pod-reader”角色授予用户“Caden”,结合对应的Role的定义,表明这一授权将允许用户“Caden”从命名空间default中读取pod。
在RoleBinding中使用subjects(目标主体)来表示要授权的对象,这是因为我们可以授权三类目标账号:Group(用户组)、User(某个具体用户)和Service Account(Pod应用所使用的账号)。
在安全领域,除了以上针对API Server访问安全相关的资源对象,还有一种特殊的资源对象——NetworkPolicy(网络策略),它是网络安全相关的资源对象,用于解决用户应用之间的网络隔离和授权问题。NetworkPolicy是一种关于Pod间相互通信,以及Pod与其他网络端点间相互通信的安全规则设定。
NetworkPolicy资源使用标签选择Pod,并定义选定Pod所允许的通信规则。在默认情况下,Pod间及Pod与其他网络端点间的访问是没有限制的,这假设了Kubernetes集群被一个厂商(公司/租户)独占,其中部署的应用都是相互可信的,无须相互防范。但是,如果存在多个厂商共同使用一个Kubernetes集群的情况,则特别是在公有云环境中,不同厂商的应用要相互隔离以增加安全性,这就可以通过NetworkPolicy来实现了。