Kubernetes RBAC Authorization(基于角色的访问控制)

本文深入探讨了Kubernetes中的基于角色的访问控制(RBAC),包括Role和ClusterRole的区别,RoleBinding和ClusterRoleBinding的使用,以及如何精细控制资源访问。RBAC通过Role和ClusterRole定义权限,通过RoleBinding和ClusterRoleBinding将权限赋予用户或服务账户。此外,文章还介绍了如何防止特权升级和初始化权限设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于角色的访问控制(RBAC),是一种其于用户的角色控制其对资源访问的方法。

RBAC利用rbac.authorization.k8s.io API组实现授权决策,允许管理通过kubernetes API动态配置策略。

在kubernetes 1.8版本中RBAC成为稳定特性,由rbac.authorization.k8s.io/v1 API在后端实现。

通过为apiserver指定--authorization-mode=RBAC选项打开RBAC功能。

概述

本节介绍RBAC API声明定义的四种顶级资源类型,它们的使用方法与普通的标准资源类型相同,如通过kubectl create -f 创建资源。

Role and ClusterRole

角色是一系列许可规则的集合,其中不包含拒绝规则。角色分成两种类型,"Role"表示某具namespace内部的角色,用"Role"类型资源表示。"ClusterRole"表示集群层面的角色,用"ClusterRole"类型的资源表示。

"Role"类型的角色只能被授权访问其所属的单个namespace之下的资源。以下示例表示default namespace下、具有读pod授权规则的"Role":

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"]

"ClusterRole"也可以像上例中的普通"Role"一样包含访问某个namespace的授权规则,但是因为"ClusterRole"是集群层面角色,它可以包含更大范围的受权规则:

  • 集群范围内资源,如node资源,它属于集群但不属于任何namespace
  • 非资源类型endpoint,如/healthz
  • 跨namespace,如存在于不同namespace下的pod

下例中的"ClusterRole"包含访问任意namespace下secrets资源的读权限:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding and ClusterRoleBinding

角色只包含许可规则,需要将角色赋予某个主体如用户、用户组、服务账号,然后主体就拥有了角色中所包含的许可规则授予的权限,这个过程就是绑定。在kubernetes中通过创建"RoleBingding"与"ClusterRoleBinding"两种类型的对象描述此过程,"RoleBinding"发生在某个namespace之下,"ClusterRoleBinding"发生在集群层面。绑定对象中包含一个主体列表,如用户、用户组、服务账号等,还包含一个"Role",表示访问列表中的主体拥有"Role"中定义的许可规则。

"RoleBinding"是namespace范围内的绑定,也就是访问的对象是本namespace所属的资源。其中的"Role"可能是相同namespace下的"Role",也可能是集群范围内的"ClusterRole"。

下例中的"RoleBinding"表示,在default namespace之内,将用户jane与上例中在同相namespace下创建的"Role"绑定,最后结果是用户jane被授权读访问default namespace下所有pod。

# This role binding allows "jane" to read pods in the "default" namespace.
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 #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

前文讲"RoleBinding"中的roleRef可以是"ClusterRole"。"ClusterRole"由系统管理员定义,一般情况下包含一些具有共性、可重复使用的许可规则,然后namespace管理员通过"RoleBinding"在namespace内部将"ClusterRole"与主体绑定。下例"RoleBing"使用"ClusterRole",提示主体dave被授权读"deployment" namespace下的secrets资源:

# 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

"ClusterRoleBing"是集群层面的绑定,比namespace层面的"RoleBing"更高。可以授权主机访问所有或者多个namespace下的资源。下例将读所有namespace下secrets的的权限授予manager用户组下的所有用户:

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
Referring to Resources

以上例子中的访问控制都是基于资源类型,当授权时,所有同类型的资源都被授权,有时候可能需要更细粒度的资源访问控制,比如特定资源。大部分类型的资源可以通过字符串名称引用,如pod等。但是,对于像某个pod的log这种子资源,它们没有名字,那么它又是如何引用?在RBCS中如果控制它们的访问呢?如下例中的子资源:

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

定义如下规则,包含对namespace下所有pod资源及pod子资源的读许可,注意子资源表示方法,下例中仍然没有对pod资源的名称为限定:

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

下列通过resourceNames字段,限定资源名称:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

显而易见,如果resourceNames字段被设置,那么verbs字段内就不可以包含list、create、watch、delete等操作。因为resourceNames限定的是具体的对象,不是对象集合,根据REST规范的定义,具体的对象不支持list、create、watch、delete等集合才支持的操作。

Aggregated ClusterRoles

从1.9版本开始支持"ClusterRole"聚合,新加aggregationRule子对象,通过其中的标签选择器聚合所有符合条件的"ClusterRole",取所有许可规则的并集作为新创建"ClusterRole"的许可规则,方便Role管理,如下例:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Rules are automatically filled in by the controller manager.

假如在创建完上述"ClusterRole"后,又新创建了包含标签rbac.example.com/aggregate-to-monitoring: true的"ClusterRole",那么新创建的"ClusterRole"仍然会被聚合,如:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: monitoring-endpoints
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
# These rules will be added to the "monitoring" role.
rules:
- apiGroups: [""]
  resources: ["services", "endpoints", "pods"]
  verbs: ["get", "list", "watch"]

系统中存在面向用户的默认Role,由系统自动创建。但是默认Role是系统内建,默认情况下只针对系统内建的资源类型。对于用户自定义资源类型,有时候也需要应用系统默认Role,如何实现?系统默认Role是聚合类的"ClusterRole",那么在为自定义资源类型定义Role时,只要包含特定的标签,则新定义的Role就会被自动聚合到系统的默认Role中,那么系统默认Role也就支持了用户自定义的新类型。

例如,用户自定义新类型"CronTabs",访问新资源的API组为"stable.example.com",按如下方法为新资源定义"ClusterRole",并指定如下标签,则所定义的许可规则会自动聚合到系统中默认的"admin、edit、view"Role中: 

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: aggregate-cron-tabs-edit
  labels:
    # Add these permissions to the "admin" and "edit" default roles.
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
rules:
- apiGroups: ["stable.example.com"]
  resources: ["crontabs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: aggregate-cron-tabs-view
  labels:
    # Add these permissions to the "view" default role.
    rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
  resources: ["crontabs"]
  verbs: ["get", "list", "watch"]

Role Examples

以下示例只显示Role中的rules字段。

允许核心API读pod:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

允许“extensions”与“apps”API组读写deployment:

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许核心API组读pod、读写job:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许核心API组读名为"my-config"的ConfigMap类型的资源(必需用RoleBinding限定在某个namespace之下):

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

允许核心API组读node资源(因为node是集群资源不属于任何namespace,因而引此规则类型必需是ClusterRole,必需用ClusterRoleBinding绑定才会生效):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值