kubernetes 主要通过 APIServer 对外提供服务,对于这样的系统集群来说,请求访问的安全性是非常重要的考虑因素。如果不对请求加以限制,那么会导致请求被滥用,甚至被黑客攻击。
kubernetes 对于访问 API 来说提供了两个步骤的安全措施:认证和授权。认证解决用户是谁的问题,授权解决用户能做什么的问题。通过合理的权限管理,能够保证系统的安全可靠。
下图是 API 访问要经过的三个步骤,前面两个是认证和授权,第三个是 Admission Control,它也能在一定程度上提高安全性,不过更多是资源管理方面的作用。
NOTE: 只有通过 HTTPS 访问的时候才会通过认证和授权,HTTP 不需要。
Authentication (认证)
All Kubernetes clusters have two categories of users: service accounts managed by Kubernetes, and normal users.
当您(真人用户)访问集群(例如使用kubectl
命令)时,apiserver
会将您认证为一个特定的 User Account
(目前通常是admin
,除非您的系统管理员自定义了集群配置)。Pod
容器中的进程也可以与 apiserver
联系。 当它们在联系 apiserver
的时候,它们会被认证为一个特定的 Service Account
(例如default)。
normal users
normal users 由外部系统管理,并不由 kubernetes 管理,kubernetesq API中也没有关于 normal users 的定义,所以不能通过 kubernetes API 创建和管理。
service accounts
Service Account 用来访问 kubernetes API,通过 kubernetes API 创建和管理,每个 account 只能在一个 namespace 上生效,存储在 kubernetes API 中的 Secrets
资源。kubernetes 会默认创建,并且会自动挂载到 Pod 中的 /run/secrets/kubernetes.io/serviceaccount
目录下。
Authorization (授权)
RBAC(Role-Based Access Control)
要启用RBAC,请使用--authorization-mode=RBAC
启动API Server。
RBAC 是官方才 1.6 版本之后推荐使用的授权方式,因为它比较灵活,而且能够很好地实现资源隔离效果。
这种方法引入了一个重要的概念:Role,翻译成角色。所有的权限都是围绕角色进行的,也就是说角色本身会包含一系列的权限规则,表明某个角色能做哪些事情。比如管理员可以操作所有的资源,某个 namespace 的用户只能修改该 namespace的内容,或者有些角色只允许读取资源。角色和 pods、services 这些资源一样,可以通过 API 创建和删除,因此用户可以非常灵活地根据需求创建角色。
Role与ClusterRole
在RBAC API中,一个角色包含了一套表示一组权限的规则。 权限以纯粹的累加形式累积(没有”否定”的规则)。 角色可以由命名空间(namespace)内的Role对象定义,而整个Kubernetes集群范围内有效的角色则通过ClusterRole对象实现。
一个Role对象只能用于授予对某一单一命名空间中资源的访问权限。 以下示例描述了”default”命名空间中的一个Role对象的定义,用于授予对pod的读访问权限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # 空字符串""表明使用core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
ClusterRole对象可以授予与Role对象相同的权限,但由于它们属于集群范围对象, 也可以使用它们授予对以下几种资源的访问权限:
- 集群范围资源(例如节点,即node)
- 非资源类型endpoint(例如”/healthz”)
- 跨所有命名空间的命名空间范围资源(例如pod,需要运行命令
kubectl get pods --all-namespaces
来查询集群中所有的pod)
下面示例中的ClusterRole定义可用于授予用户对某一特定命名空间,或者所有命名空间中的secret(取决于其绑定方式)的读访问权限:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
# 鉴于ClusterRole是集群范围对象,所以这里不需要定义"namespace"字段
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding与ClusterRoleBinding
角色绑定将一个角色中定义的各种权限授予一个或者一组用户。 角色绑定包含了一组相关主体(即subject, 包括用户——User、用户组——Group、或者服务账户——Service Account)以及对被授予角色的引用。 在命名空间中可以通过RoleBinding
对象授予权限,而集群范围的权限授予则通过ClusterRoleBinding
对象完成。
RoleBinding
可以引用在同一命名空间内定义的Role
对象。 下面示例中定义的RoleBinding
对象在”default”命名空间中将”pod-reader”角色授予用户”jane”。 这一授权将允许用户”jane”从”default”命名空间中读取pod。
# 以下角色绑定定义将允许用户"jane"从"default"命名空间中读取pod。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io