一、RBAC对象配置解析

1.1 Role

在RBAC API中,Role包含表示一组权限的规则。权限纯粹是附加允许的,没有拒绝规则。

Role只能授权对单个命名空间内的资源的访问权限,比如授权对default命名空间的读取权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

上面参数说明如下:

  • kind:定义资源类型为Role
  • apiVersion:定义该资源的API版本,建议使用v1版本,因为其他版本(如Beta版本)在Kubernetes1.22+将被彻底启用。
  • metadata:元数据定义
  • namespace:因为Role是作用在单个Namespace下的,具有命名空间隔离,所以需要指定Namespace,不指定则为default
  • name:Role的名称
  • rules:定义具体的权限,切片类型,可以配置多个
  • apiGroups:包含该资源的apiGroup名称,比如extension,为空则为核心组
  • resources:定义对哪些资源进行授权,切片类型,可以定义多个,比如pods、service等
  • verbs:定义可以执行的操作,切片类型,可以定义多个,比如create、delete、list、get、watch、deletecollection等

1.2 ClusterRole

ClusterRole也可将上述权限授予作用于整个集群的Role,主要区别是,ClusterRole是集群范围的,因此它们还可以授予对以下内容的访问权限:

  • 集群范围的资源(如Node)
  • 非资源端点(如/healthz)
  • 跨所有命名空间的命名空间资源(如Pod)

比如,授予对任何特定命名空间或所有命名空间中的secret的读权限(取决于它的绑定方式)

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

上面参数说明如下:

  • kind:定义资源类型为ClusterRole
  • apiVersion:定义该资源的API版本,建议使用v1版本,因为其他版本(如Beta版本)在Kubernetes1.22+将被彻底启用。
  • metadata:元数据定义
  • namespace:因为Role是作用在单个Namespace下的,具有命名空间隔离,所以需要指定Namespace,不指定则为default
  • name:Role的名称
  • rules:定义具体的权限,切片类型,可以配置多个
  • apiGroups:包含该资源的apiGroup名称,比如extension,为空则为核心组
  • resources:定义对哪些资源进行授权,切片类型,可以定义多个,比如pods、service等
  • verbs:定义可以执行的操作,切片类型,可以定义多个,比如create、delete、list、get、watch、deletecollection等

1.3 RoleBinding

RoleBinding可以引用同一命名空间的Role进行授权,比如将上述创建的pod-reader的Role授予default命名空间的用户jane,这将允许jane读取default命名空间中所有Pod的权限:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role #这个可以是ClusterRole
  name: pod-reader 
  apiGroup: rbac.authorization.k8s.io

上面参数说明如下:

  • kind: RoleBinding:资源类型为 RoleBinding,用于将角色(RoleClusterRole)绑定到用户、组或服务账户,实现权限分配。
  • apiVersion: rbac.authorization.k8s.io/v1:使用 RBAC(基于角色的访问控制)API 版本,K8s 1.9+ 版本常用此版本。
  • name: read-podsRoleBinding 的名称,用于唯一标识当前绑定资源。
  • namespace: default:作用域命名空间,表明该 RoleBinding 仅在 default 命名空间内生效。
  • subjects:配置被绑定对象,可以配置多个
  • kind:绑定对象的类别,当前为User,还可以是Group、ServiceAccount
  • name:绑定对象名称

  • roleRef:绑定的类别,可以是Role或ClusterRole

  • kind:指定权限来源,可以是Role或ClusterRole
  • name:Role或ClusterRole的名字
  • apiGroup:API组名

RoleBinding也可以引用ClusterRole来授予对命名空间资源的某些权限。管理员可以为整个集群定义一组公用的ClusterRole,然后在多个命名空间中重复使用。

比如,创建一个RoleBinding引用ClusterRole,授予dave用户读取development命名空间的Secret:

# This role binding allows "dave" to read secrets in the "development" namespace.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-secrets
  namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
  name: dave # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

上面参数说明如下:

  • roleRef:绑定的类别,可以是Role或ClusterRole

1.4 ClusterRoleBinding

ClusterRoleBinding可用于在集群级别和所有命名空间中授予权限,比如允许组manager中的所有用户都能读取任何命名空间的Secret:

# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

注意:创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的 roleRef 将导致合法性检查错误。 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。

二、RBAC配置示例

2.1 Role示例

1.允许读取在核心 API 组下的 "pods"

rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

2.允许在 "apps" API 组中读/写 Deployment(在 HTTP 层面,对应 URL 中资源部分为 "deployments"):

rules:
- apiGroups: ["apps"]
  # 在 HTTP 层面,用来访问 Deployment 资源的名称为 "deployments"
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

3.允许读取核心 API 组中的 Pod 和读/写 "batch" API 组中的 Job 资源:

rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  # 在 HTTP 层面,用来访问 Job 资源的名称为 "jobs"
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

4.允许读取名称为 "my-config" 的 ConfigMap(需要通过 RoleBinding 绑定以限制为某名字空间中特定的 ConfigMap)

rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

5.允许读取在核心组中的 "nodes" 资源(因为 Node 是集群作用域的,所以需要 ClusterRole 绑定到 ClusterRoleBinding 才生效):

rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Node 资源的名称为 "nodes"
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

6.允许针对非资源端点 /healthz 和其子路径上发起 GET 和 POST 请求 (必须在 ClusterRole 绑定 ClusterRoleBinding 才生效):

rules:
#nonResourceURL 中的 '*' 是一个全局通配符
- nonResourceURLs: ["/healthz", "/healthz/*"] 
  verbs: ["get", "post"]

2.2 RoleBinding示例

RoleBinding 或者 ClusterRoleBinding 可绑定角色到某主体(Subject)上。 主体可以是组,用户或者服务账户。

Kubernetes 用字符串来表示用户名。 用户名可以是普通的用户名,像 "alice";或者是邮件风格的名称,如 "bob@example.com", 或者是以字符串形式表达的数字 ID。你作为 Kubernetes 管理员负责配置身份认证模块, 以便后者能够生成你所期望的格式的用户名。

注意:前缀 system: 是 Kubernetes 系统保留的,所以你要确保所配置的用户名或者组名不能出现上述 system: 前缀。除了对前缀的限制之外,RBAC 鉴权系统不对用户名格式作任何要求

1.对于名称为 alice@example.com 的用户:

subjects:
- kind: User
  name: "alice@example.com"
  apiGroup: rbac.authorization.k8s.io

2.对于名称为 frontend-admins 的用户组:

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

3.对于 kube-system 名字空间中的默认服务账户:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

4.对于 "qa" 名称空间中的所有服务账户:

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

上面参数说明:

  • 服务账户的用户名前缀为 system:serviceaccount:,属于前缀为 system:serviceaccounts: 的用户组。
  • system:serviceaccount: (单数)是用于服务账户用户名的前缀

5.对于在任何名字空间中的服务账户:

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

上面参数说明:

  • 服务账户的用户名前缀为 system:serviceaccount:,属于前缀为 system:serviceaccounts: 的用户组。
  • system:serviceaccounts: (复数)是用于服务账户组名的前缀

6.对于所有已经过身份认证的用户:

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

7.对于所有未通过身份认证的用户:

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

8.对于所有用户:

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io