一、RBAC是什么

RBAC:Role-Based Access Control,是一种基于角色的访问控制机制,用于管理用户和应用程序对Kubernetes资源的访问权限。通过RBAC,管理员可以细粒度地控制哪些用户或服务账户可以执行哪些操作,从而确保集群的安全性和资源的合理使用。

基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对计算机或网络资源的访问的方法。其在Kubernetes 1.5版本中引入,在1.6版本中升级为Beta版本,并成为Kubeadm安装方式下的默认选项。

RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组来驱动鉴权决定, 允许你通过 Kubernetes API 动态配置策略。

要启用 RBAC,在启动 API 服务器时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC

kube-apiserver --authorization-mode=Example,RBAC --<其他选项> --<其他选项>

其中关于两种安装方式的配置文件路径如下:

  • 二进制方式安装:/usr/lib/systemd/system/kube-apiserver.service
  • kubeadm方式安装:/etc/kubernetes/manifests/kube-apiserver.yml

根据不同的安装方式,在对应的配置文件中添加--authorization-mode=Node,RBAC参数。

注意:RBAC只具备添加权限,不具备拒绝权限

RBAC授权模式分为Roles和Binding两种组件:

  • Roles:用于定义相关权限
  • Bindings:用于把权限绑定至相关主体,比如用户和组

二、RBAC出现背景

在生产环境中,Kubernetes管理员具有Kubernetes集群中各类资源增删改查的权限,并且也具有授权其他用户权限的权限。之前提到过使用kubectl客户端工具操作集群时,会默认使用~/.kube/config文件访问集群,该文件具有操作集群的各类权限,有可能是管理员权限,也有可能只是某个命名空间的权限。在实际使用时,需要访问并操作Kubernetes集群的不仅仅是管理员,也有可能是某个项目的负责人、某个应用的开发者等,所以在Kubernetes中实现细粒度的权限管理是一件很重要的事情,而具体权限的管控都由一个叫RBAC的资源进行管理配置。

三、RBAC对象分类

Roles和Bindings分类:

  • 1)Role:命名空间级别的权限,权限规则仅限于命名空间内
  • 2)ClusterRole:集群级别的权限,权限规则覆盖整个集群,同时可以绑定到某个空间内
  • 3)RoleBinding:将Role或者ClusterRole的权限绑定到用户组或服务账户,并指定到某个空间内,绑定后用户只具备该空间的相关权限
  • 4)ClusterRoleBinding:将ClusterRole绑定到用户、组或服务账户,绑定后用户具备集群的相关权限

RBAC API 声明了四种 Kubernetes 对象:RoleClusterRoleRoleBindingClusterRoleBinding。你可以像使用其他 Kubernetes 对象一样, 通过类似 kubectl 这类工具描述或修补RBAC 对象。

RBAC四种对象之间的关系

3.1 Role 和 ClusterRole

RBAC 的 RoleClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。

Role 总是用来在某个名字空间内设置访问权限; 在你创建 Role 时,你必须指定该 Role 所属的名字空间。

与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole) 是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的,不可两者兼具。

ClusterRole 有若干用法。你可以用它来:

  • 定义对某名字空间域对象的访问权限,并将在个别名字空间内被授予访问权限;
  • 为名字空间作用域的对象设置访问权限,并被授予跨所有名字空间的访问权限;
  • 为集群作用域的资源定义访问权限。

小结:Role和ClusterRole的关键区别是,Role是作用于命名空间内的角色,ClusterRole是作用于整个集群的集群角色。在RBAC API中,Role包含表示一组权限的规则。权限纯粹是附加允许的,没有拒绝规则。

3.2 RoleBinding 和 ClusterRoleBinding

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干主体(Subject)(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。 RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。

一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果你希望将某 ClusterRole 绑定到集群中所有名字空间,你要使用 ClusterRoleBinding。

RoleBinding 或 ClusterRoleBinding 对象的名称必须是合法的路径分段名称。

小结:RoleBinding和ClusterRoleBinding最大的区别与Role和ClusterRole的区别类似,即RoleBinding作用于命名空间,ClusterRoleBinding作用于集群。

四、对集群资源的权限控制

在 Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。 例如,对于 Pod 应使用 "pods"。 RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。 有一些 Kubernetes API 涉及子资源(subresource),例如 Pod 的日志。 对 Pod 日志的请求看起来像这样:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这里,pods 对应名字空间作用域的 Pod 资源,而 logpods 的子资源。 在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,你可以这样写:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

对于某些请求,也可以通过 resourceNames 列表按名称引用资源。 在指定时,可以将请求限定为资源的单个实例。 下面的例子中限制可以 getupdate 一个名为 my-configmap 的ConfigMap:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  #  HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

注意:如果使用了resourceNames,则verbs不能是list、watch、create、deletecollection等。