使用RBAC授权

使用 RBAC 授权

基于角色的访问控制 (RBAC) 是一种根据组织内各个用户的角色来调节对计算机或网络资源的访问的方法。

RBAC 授权使用rbac.authorization.k8s.io API 组推动授权决策,允许您通过 Kubernetes API 动态配置策略。

要启用 RBAC,请启动API 服务器--authorization-mode标志设置为逗号分隔的列表,其中包括RBAC; 例如:

kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options

API 对象

RBAC API 声明了四种 Kubernetes 对象:RoleClusterRoleRoleBindingClusterRoleBinding。您可以 像任何其他 Kubernetes 对象一样使用工具来描述或修改对象。kubectl,

警告:这些对象在设计上会施加访问限制。如果您在学习过程中对集群进行更改,请参阅 权限提升预防和引导 以了解这些限制如何阻止您进行某些更改。

角色和集群角色

RBAC角色ClusterRole包含表示一组权限的规则。权限纯粹是附加的(没有“拒绝”规则)。

角色总是在特定的范围内设置权限命名空间; 创建角色时,必须指定它所属的命名空间。

相反,ClusterRole 是一个非命名空间资源。资源具有不同的名称(Role 和 ClusterRole),因为 Kubernetes 对象总是必须具有命名空间或不具有命名空间;不可能两者兼而有之。

ClusterRoles 有多种用途。您可以使用 ClusterRole 来:

  1. 定义命名空间资源的权限并在单个命名空间内授予
  2. 定义命名空间资源的权限并在所有命名空间中授予
  3. 定义集群范围资源的权限

如果要在命名空间中定义角色,请使用角色;如果要在集群范围内定义角色,请使用 ClusterRole。

角色示例

这是“默认”命名空间中的示例角色,可用于授予对 豆荚

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

集群角色示例

ClusterRole 可用于授予与角色相同的权限。由于 ClusterRoles 是集群范围的,您还可以使用它们来授予对以下内容的访问权限:

  • 集群范围的资源(如节点)

  • 非资源端点(如/healthz

  • 跨所有命名空间的命名空间资源(如 Pod)

    例如:您可以使用 ClusterRole 来允许特定用户运行 kubectl get pods --all-namespaces

下面是一个 ClusterRole 示例,可用于授予对 秘密在任何特定命名空间中,或跨所有命名空间(取决于它的绑定方式):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Secret
  # objects is "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

Role 或 ClusterRole 对象的名称必须是有效的 路径段名称

RoleBinding 和 ClusterRoleBinding

角色绑定将角色中定义的权限授予一个用户或一组用户。它包含一个主题列表(用户、组或服务帐户),以及对被授予角色的引用。RoleBinding 授予特定命名空间内的权限,而 ClusterRoleBinding 授予访问集群范围的权限。

RoleBinding 可以引用同一命名空间中的任何角色。或者,RoleBinding 可以引用 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 的命名空间。如果要将 ClusterRole 绑定到集群中的所有命名空间,请使用 ClusterRoleBinding。

RoleBinding 或 ClusterRoleBinding 对象的名称必须是有效的 路径段名称

角色绑定示例

下面是一个 RoleBinding 示例,它将“pod-reader”角色授予“default”命名空间中的用户“jane”。这允许“jane”读取“default”命名空间中的 pod。

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: jane # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  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 还可以引用 ClusterRole 以将该 ClusterRole 中定义的权限授予 RoleBinding 命名空间内的资源。这种引用允许您在集群中定义一组通用角色,然后在多个命名空间中重用它们。

例如,即使以下 RoleBinding 引用 ClusterRole,“dave”(主题,区分大小写)也只能读取“development”命名空间中的 Secret,因为 RoleBinding 的命名空间(在其元数据中)是“development” .

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
# You need to already have a ClusterRole named "secret-reader".
kind: RoleBinding
metadata:
  name: read-secrets
  #
  # The namespace of the RoleBinding determines where the permissions are granted.
  # This only grants permissions within the "development" namespace.
  namespace: development
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

ClusterRoleBinding 示例

要在整个集群中授予权限,您可以使用 ClusterRoleBinding。以下 ClusterRoleBinding 允许组“manager”中的任何用户读取任何命名空间中的机密。

apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
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

创建绑定后,您无法更改它所引用的角色或集群角色。如果您尝试更改绑定roleRef,则会收到验证错误。如果确实要更改roleRef绑定,则需要删除绑定对象并创建替换。

这种限制有两个原因:

  1. 使roleRef不可变允许授予某人update对现有绑定对象的权限,以便他们可以管理主题列表,而无需更改授予这些主题的角色。
  2. 绑定到不同的角色是根本不同的绑定。要求删除/重新创建绑定以更改roleRef 确保绑定中的完整主题列表旨在被授予新角色(而不是在不验证所有现有主题的情况下仅启用或意外修改 roleRef 应该是给定新角色的权限)。

命令行实用程序创建或更新包含 RBAC 对象的kubectl auth reconcile清单文件,并在需要更改绑定对象引用的角色时处理删除和重新创建绑定对象。有关详细信息,请参阅命令用法和示例

参考资源

在 Kubernetes API 中,大多数资源都使用其对象名称的字符串表示形式来表示和访问,例如podsPod。RBAC 使用与相关 API 端点的 URL 中出现的完全相同的名称来引用资源。一些 Kubernetes API 涉及 子资源,例如 Pod 的日志。对 Pod 日志的请求如下所示:

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

在这种情况下,pods是 Pod 资源的命名空间资源,并且logpods. 要在 RBAC 角色中表示这一点,请使用斜杠 ( /) 来分隔资源和子资源。要允许主题读取pods并访问log每个 Pod 的子资源,请编写:

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列表为某些请求按名称引用资源。指定后,可以将请求限制为资源的单个实例。这是一个将其主题限制为 onlygetupdatea 配置映射命名my-configmap

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing ConfigMap
  # objects is "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

注意:您不能通过资源名称来限制createdeletecollection请求。对于create,此限制是因为在授权时可能不知道新对象的名称。如果您限制listwatch通过资源名称,客户端必须在其或请求中包含与指定资源名称匹配的metadata.name字段选择器才能获得授权。例如,list``watch``kubectl get configmaps --field-selector=metadata.name=my-configmap

聚合集群角色

您可以将多个 ClusterRole聚合为一个组合的 ClusterRole。一个控制器,作为集群控制平面的一部分运行,用一个集合监视 ClusterRole 对象aggregationRule。定义一个aggregationRule标签 选择器控制器用来匹配应该组合到这个rules 字段中的其他 ClusterRole 对象。

这是一个聚合 ClusterRole 的示例:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # The control plane automatically fills in the rules

如果您创建与现有聚合 ClusterRole 的标签选择器匹配的新 ClusterRole,则该更改会触发将新规则添加到聚合 ClusterRole 中。这是一个示例,通过创建另一个标记为 的 ClusterRole,将规则添加到“监控”ClusterRole rbac.example.com/aggregate-to-monitoring: true

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

默认的面向用户的角色使用 ClusterRole 聚合。这使您作为集群管理员可以包含自定义资源的规则,例如由 自定义资源定义 或聚合 API 服务器,以扩展默认角色。

例如:以下 ClusterRoles 让“admin”和“edit”默认角色管理名为 CronTab 的自定义资源,而“view”角色只能对 CronTab 资源执行读取操作。您可以假设 CronTab 对象"crontabs"在 API 服务器看到的 URL 中命名。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
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 或 ClusterRole 对象的摘录,仅显示该rules部分。

允许"pods"在核心中读取资源 API 组

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Pod
  # objects is "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

允许在 API 组和API 组中读/写部署(在 HTTP 级别:"deployments" 在其 URL 的资源部分中的对象) :"extensions"``"apps"

rules:
- apiGroups: ["extensions", "apps"]
  #
  # at the HTTP level, the name of the resource for accessing Deployment
  # objects is "deployments"
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取核心 API 组中的 Pod,以及读取或写入 API 组中的 Job"batch"资源"extensions"

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Pod
  # objects is "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  #
  # at the HTTP level, the name of the resource for accessing Job
  # objects is "jobs"
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取名为“my-config”的 ConfigMap(必须与 RoleBinding 绑定以限制单个命名空间中的单个 ConfigMap):

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing ConfigMap
  # objects is "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

允许读取"nodes"核心组中的资源(因为节点是集群范围的,这必须在与 ClusterRoleBinding 绑定的 ClusterRole 中才能生效):

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Node
  # objects is "nodes"
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

允许对非资源端点/healthz和所有子路径的 GET 和 POST 请求(必须在与 ClusterRoleBinding 绑定的 ClusterRole 中才能生效):

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
  verbs: ["get", "post"]

提及主题

RoleBinding 或 ClusterRoleBinding 将角色绑定到主题。主题可以是组、用户或 服务帐户.

Kubernetes 将用户名表示为字符串。这些可以是: 简单的名称,例如“alice”;电子邮件样式的名称,例如“bob@example.com”;或表示为字符串的数字用户 ID。作为集群管理员,您可以配置身份验证模块 ,以便身份验证以您想要的格式生成用户名。

注意:前缀system:是为 Kubernetes 系统保留的,因此您应该确保您没有名称system:以意外开头的用户或组。除了这个特殊的前缀,RBAC 授权系统不需要任何格式的用户名。

在 Kubernetes 中,Authenticator 模块提供组信息。组,如用户,表示为字符串,并且该字符串没有格式要求,除了system:保留前缀。

ServiceAccounts的名称以 为前缀system:serviceaccount:,并且属于名称以 为前缀的组system:serviceaccounts:

笔记:

  • system:serviceaccount:(单数)是服务帐户用户名的前缀。
  • system:serviceaccounts:(复数)是服务帐户组的前缀。

角色绑定示例

以下示例是RoleBinding仅显示该subjects部分的摘录。

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

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

对于名为 的组frontend-admins

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

对于“kube-system”命名空间中的默认服务帐户:

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

对于任何命名空间中“qa”组中的所有服务帐户:

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

对于“开发”命名空间中“开发”组中的所有服务帐户:

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

对于任何命名空间中的所有服务帐户:

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

对于所有经过身份验证的用户:

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

对于所有未经身份验证的用户:

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

对于所有用户:

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

默认角色和角色绑定

API 服务器创建一组默认 ClusterRole 和 ClusterRoleBinding 对象。其中很多都是带system:前缀的,表示资源是由集群控制平面直接管理的。所有默认的 ClusterRoles 和 ClusterRoleBindings 都标有kubernetes.io/bootstrapping=rbac-defaults

警告:使用带有system:前缀的名称修改 ClusterRole 和 ClusterRoleBindings 时要小心。对这些资源的修改可能会导致集群无法正常工作。

自动对账

在每次启动时,API 服务器会使用任何缺失的权限更新默认集群角色,并使用任何缺失的主题更新默认集群角色绑定。这允许集群修复意外修改,并有助于在新 Kubernetes 版本中权限和主题发生变化时保持角色和角色绑定是最新的。

要退出此协调,请将rbac.authorization.kubernetes.io/autoupdate 默认集群角色或角色绑定上的注释设置为false. 请注意,缺少默认权限和主题可能会导致集群无法正常工作。

如果 RBAC 授权方处于活动状态,则默认情况下会启用自动对帐。

API 发现角色

默认角色绑定授权未经身份验证和经过身份验证的用户读取被认为安全且可公开访问的 API 信息(包括 CustomResourceDefinitions)。要禁用匿名未经身份验证的访问,请添加--anonymous-auth=false到 API 服务器配置。

通过kubectl运行查看这些角色的配置:

kubectl get clusterroles system:discovery -o yaml

注意:如果您编辑该 ClusterRole,您的更改将在 API 服务器重新启动时通过auto-reconciliation被覆盖。为避免覆盖,请不要手动编辑角色,或禁用自动协调。

<caption style="box-sizing: border-box; padding-top: 0.75rem; padding-bottom: 0.75rem; color: rgb(121, 118, 118); text-align: left; caption-side: bottom;">Kubernetes RBAC API 发现角色</caption><colgroup style="box-sizing: border-box;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box;"></colgroup>

默认集群角色 默认 ClusterRoleBinding 描述
系统:基本用户 系统:认证 允许用户以只读方式访问有关他们自己的基本信息。在 v1.14 之前,此角色还绑定到<tt style="box-sizing: border-box;">system:unauthenticated</tt>默认情况下。
系统:发现 系统:认证 允许对发现和协商 API 级别所需的 API 发现端点进行只读访问。在 v1.14 之前,此角色还绑定到<tt style="box-sizing: border-box;">system:unauthenticated</tt>默认情况下。
系统:公共信息查看器 system:authenticatedsystem:unauthenticated 允许对有关集群的非敏感信息进行只读访问。在 Kubernetes v1.14 中引入。

面向用户的角色

一些默认 ClusterRoles 没有system:前缀。这些旨在成为面向用户的角色。它们包括超级用户角色 ( cluster-admin)、旨在使用 ClusterRoleBindings 在集群范围内授予的角色,以及旨在使用 RoleBindings ( admineditview) 在特定命名空间内授予的角色。

面向用户的 ClusterRoles 使用ClusterRole 聚合来允许管理员在这些 ClusterRoles 上包含自定义资源的规则。要将规则添加到admineditview角色,请创建具有以下一个或多个标签的 ClusterRole:

metadata:
  labels:
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"

<colgroup style="box-sizing: border-box;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box;"></colgroup>

默认集群角色 默认 ClusterRoleBinding 描述
集群管理员 系统:大师 允许超级用户访问对任何资源执行任何操作。在ClusterRoleBinding中使用时,它可以完全控制集群和所有命名空间中的每个资源。在RoleBinding中使用时,它可以完全控制角色绑定命名空间中的每个资源,包括命名空间本身。
行政 没有 允许管理员访问,旨在使用RoleBinding在命名空间内授予。

如果在RoleBinding中使用,则允许对命名空间中的大多数资源进行读/写访问,包括在命名空间中创建角色和角色绑定的能力。此角色不允许对资源配额或命名空间本身进行写访问。此角色还不允许对使用 Kubernetes v1.22+ 创建的集群中的端点进行写访问。更多信息可在 “端点的写入访问”部分中找到。

|
| 编辑 | 没有 | 允许对命名空间中的大多数对象进行读/写访问。

此角色不允许查看或修改角色或角色绑定。但是,该角色允许访问 Secrets 并作为命名空间中的任何 ServiceAccount 运行 Pod,因此它可以用于获取命名空间中任何 ServiceAccount 的 API 访问级别。此角色还不允许对使用 Kubernetes v1.22+ 创建的集群中的端点进行写访问。更多信息可在 “端点的写入访问”部分中找到。

|
| 看法 | 没有 | 允许只读访问以查看命名空间中的大多数对象。它不允许查看角色或角色绑定。

此角色不允许查看 Secret,因为读取 Secret 的内容可以访问命名空间中的 ServiceAccount 凭证,这将允许 API 访问命名空间中的任何 ServiceAccount(一种权限提升形式)。

|

核心组件角色

<colgroup style="box-sizing: border-box;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box;"></colgroup>

默认集群角色 默认 ClusterRoleBinding 描述
系统:kube-调度程序 系统:kube-scheduler用户 允许访问所需的资源调度器零件。
系统:卷调度器 系统:kube-scheduler用户 允许访问 kube-scheduler 组件所需的卷资源。
系统:kube-controller-manager 系统:kube-controller-manager用户 允许访问所需的资源控制器管理器零件。各个控制器所需的权限在控制器角色中有详细说明。
系统:节点 没有 允许访问 kubelet 所需的资源,包括对所有 secret 的读取访问权限,以及对所有 pod 状态对象的写入访问权限

您应该使用Node 授权者和NodeRestriction 准入插件而不是<tt style="box-sizing: border-box;">system:node</tt>角色,并允许根据计划在其上运行的 Pod 授予对 kubelet 的 API 访问权限。

<tt style="box-sizing: border-box;">system:node</tt>角色的存在只是为了兼容从 v1.8 之前的版本升级的 Kubernetes 集群。

|
| 系统:节点代理 | 系统:kube-proxy用户 | 允许访问所需的资源kube-代理零件。 |

其他组件角色

<colgroup style="box-sizing: border-box;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box; width: 296.406px;"><col style="box-sizing: border-box;"></colgroup>

默认集群角色 默认 ClusterRoleBinding 描述
系统:授权委托人 没有 允许委托的身份验证和授权检查。这通常由附加 API 服务器用于统一身份验证和授权。
系统:堆垛机 没有 Heapster组件的角色(已弃用)。
系统:kube-聚合器 没有 kube-aggregator组件的角色。
系统:kube-dns kube -system命名空间中的 kube -dns服务帐户 kube-dns组件的角色。
系统:kubelet-api-admin 没有 允许完全访问 kubelet API。
系统:节点引导程序 没有 允许访问执行 kubelet TLS 引导所需的资源。
系统:节点问题检测器 没有 节点问题检测器组件的角色。
system:persistent-volume-provisioner 没有 允许访问大多数动态卷供应商所需的资源。
系统:监控 系统:监控 允许读取控制平面监控端点(即kube-apiserverliveness和 readiness 端点(<tt style="box-sizing: border-box;">/healthz</tt>、<tt style="box-sizing: border-box;">/livez</tt>、<tt style="box-sizing: border-box;">/readyz</tt>)、各个健康检查端点(<tt style="box-sizing: border-box;">/healthz/</tt>、<tt style="box-sizing: border-box;">/livez/</tt>、<tt style="box-sizing: border-box;">/readyz/*</tt>)和<tt style="box-sizing: border-box;">/metrics</tt>)。请注意,个别健康检查端点和指标端点可能会暴露敏感信息。

内置控制器的角色

Kubernetes控制器管理器运行 控制器内置在 Kubernetes 控制平面中。当使用 调用时--use-service-account-credentials,kube-controller-manager 使用单独的服务帐户启动每个控制器。每个内置控制器都有对应的角色,前缀为system:controller:. 如果控制器管理器不是以 启动的--use-service-account-credentials,它使用自己的凭据运行所有控制循环,必须授予所有相关角色。这些角色包括:

  • system:controller:attachdetach-controller
  • system:controller:certificate-controller
  • system:controller:clusterrole-aggregation-controller
  • system:controller:cronjob-controller
  • system:controller:daemon-set-controller
  • system:controller:deployment-controller
  • system:controller:disruption-controller
  • system:controller:endpoint-controller
  • system:controller:expand-controller
  • system:controller:generic-garbage-collector
  • system:controller:horizontal-pod-autoscaler
  • system:controller:job-controller
  • system:controller:namespace-controller
  • system:controller:node-controller
  • system:controller:persistent-volume-binder
  • system:controller:pod-garbage-collector
  • system:controller:pv-protection-controller
  • system:controller:pvc-protection-controller
  • system:controller:replicaset-controller
  • system:controller:replication-controller
  • system:controller:resourcequota-controller
  • system:controller:root-ca-cert-publisher
  • system:controller:route-controller
  • system:controller:service-account-controller
  • system:controller:service-controller
  • system:controller:statefulset-controller
  • system:controller:ttl-controller

特权升级预防和引导

RBAC API 可防止用户通过编辑角色或角色绑定来提升权限。因为这是在 API 级别强制执行的,所以即使没有使用 RBAC 授权方,它也适用。

对角色创建或更新的限制

仅当以下至少一项为真时,您才能创建/更新角色:

  1. 您已经拥有角色中包含的所有权限,与正在修改的对象处于相同的范围内(对于 ClusterRole,在集群范围内,在同一命名空间内,对于角色,在集群范围内)。
  2. 您被授予在API 组中的or资源escalate上执行动词的显式权限。roles``clusterroles``rbac.authorization.k8s.io

例如,如果user-1无法在集群范围内列出 Secret,则无法创建包含该权限的 ClusterRole。允许用户创建/更新角色:

  1. 授予他们一个角色,允许他们根据需要创建/更新 Role 或 ClusterRole 对象。
  2. 授予他们在他们创建/更新的角色中包含特定权限的权限:
    • 隐含地,通过授予他们这些权限(如果他们尝试创建或修改具有他们自己未授予权限的角色或集群角色,则 API 请求将被禁止)
    • 或明确允许在 a 中指定任何权限,RoleClusterRole通过授予他们对API 组中的资源或资源执行escalate动词的权限roles``clusterroles``rbac.authorization.k8s.io

对角色绑定创建或更新的限制

如果您已经拥有被引用角色中包含的所有权限(与角色绑定在同一范围内) ,或者如果您已被授权bind对被引用角色执行谓词,则只能创建/更新角色绑定。例如,如果user-1无法在集群范围内列出 Secret,则它们无法创建 ClusterRoleBinding 到授予该权限的角色。允许用户创建/更新角色绑定:

  1. 授予他们一个角色,允许他们根据需要创建/更新 RoleBinding 或 ClusterRoleBinding 对象。
  2. 授予他们绑定特定角色所需的权限:
    • 隐含地,通过授予他们角色中包含的权限。
    • 明确地,通过授予他们bind在特定角色(或 ClusterRole)上执行动词的权限。

例如,此 ClusterRole 和 RoleBinding 将允许user-1授予其他用户命名空间中的admineditview角色user-1-namespace

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles"]
  verbs: ["bind"]
  # omit resourceNames to allow binding any ClusterRole
  resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: user-1-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: user-1

在引导第一个角色和角色绑定时,初始用户有必要授予他们尚未拥有的权限。引导初始角色和角色绑定:

  • 使用带有“system:masters”组的凭据,该组通过默认绑定绑定到“cluster-admin”超级用户角色。
  • 如果您的 API 服务器在启用了不安全端口 ( --insecure-port) 的情况下运行,您还可以通过该端口进行 API 调用,这不会强制进行身份验证或授权。

命令行实用程序

kubectl create role

在单个命名空间中创建定义权限的角色对象。例子:

  • 创建一个名为“pod-reader”的角色,允许用户在 pod 上执行get,watchlist

    kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
    
    
  • 创建一个名为“pod-reader”并指定资源名称的角色:

    kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
    
  • 创建一个名为“foo”并指定 apiGroups 的角色:

    kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
    
    
  • 使用子资源权限创建一个名为“foo”的角色:

    kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
    
    
  • 创建一个名为“my-component-lease-holder”的角色,具有获取/更新具有特定名称的资源的权限:

    kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component
    
    

kubectl create clusterrole

创建一个 ClusterRole。例子:

  • 创建一个名为“pod-reader”的 ClusterRole,允许用户在 pod 上执行get,watchlist

    kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
    
    
  • 创建一个名为“pod-reader”的 ClusterRole,指定 resourceNames:

    kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
    
  • 创建一个名为“foo”并指定 apiGroups 的 ClusterRole:

    kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
    
    
  • 创建一个名为“foo”的具有子资源权限的 ClusterRole:

    kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
    
    
  • 创建一个名为“foo”的 ClusterRole,指定 nonResourceURL:

    kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
    
    
  • 创建一个名为“monitoring”的 ClusterRole 并指定一个 aggregationRule:

    kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"
    
    

kubectl create rolebinding

授予特定命名空间内的角色或集群角色。例子:

  • 在命名空间“acme”中,将“admin”ClusterRole 中的权限授予名为“bob”的用户:

    kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
    
    
  • 在命名空间“acme”中,将“view”ClusterRole 中的权限授予命名空间“acme”中名为“myapp”的服务帐户:

    kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
    
    
  • 在命名空间“acme”中,将“view”ClusterRole 中的权限授予命名空间“myappnamespace”中名为“myapp”的服务帐户:

    kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
    
    

kubectl create clusterrolebinding

在整个集群(所有命名空间)中授予 ClusterRole。例子:

  • 在整个集群中,将“cluster-admin”ClusterRole 中的权限授予名为“root”的用户:

    kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
    
    
  • 在整个集群中,将“system:node-proxier”ClusterRole 中的权限授予名为“system:kube-proxy”的用户:

    kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
    
    
  • 在整个集群中,将“view”ClusterRole 中的权限授予命名空间“acme”中名为“myapp”的服务帐户:

    kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
    
    

kubectl auth reconcile

rbac.authorization.k8s.io/v1从清单文件创建或更新API 对象。

如果需要,将创建缺少的对象,并为命名空间的对象创建包含的命名空间。

现有角色已更新以包含输入对象中的权限,并在--remove-extra-permissions指定时删除额外权限。

更新现有绑定以将主题包括在输入对象中,如果--remove-extra-subjects指定,则删除额外的主题。

例子:

  • 测试应用 RBAC 对象的清单文件,显示将要进行的更改:

    kubectl auth reconcile -f my-rbac-rules.yaml --dry-run=client
    
    
  • 应用 RBAC 对象的清单文件,保留任何额外的权限(在角色中)和任何额外的主题(在绑定中):

    kubectl auth reconcile -f my-rbac-rules.yaml
    
    
  • 应用 RBAC 对象的清单文件,删除任何额外的权限(在角色中)和任何额外的主题(在绑定中):

    kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
    
    

服务帐户权限

默认 RBAC 策略授予控制平面组件、节点和控制器的范围权限,但不授予命名空间之外的服务帐户kube-system权限(除了授予所有经过身份验证的用户的发现权限)。

这允许您根据需要将特定角色授予特定的 ServiceAccounts。细粒度的角色绑定提供了更高的安全性,但需要更多的管理工作。更广泛的授权可以为 ServiceAccounts 提供不必要的(并且可能会升级的)API 访问,但更易于管理。

按照从最安全到最不安全的顺序,这些方法是:

  1. 将角色授予特定于应用程序的服务帐户(最佳实践)

    这要求应用程序在其 pod 规范中指定 a serviceAccountName,并创建服务帐户(通过 API、应用程序清单kubectl create serviceaccount等)。

    例如,将“my-namespace”中的只读权限授予“my-sa”服务帐户:

    kubectl create rolebinding my-sa-view \
      --clusterrole=view \
      --serviceaccount=my-namespace:my-sa \
      --namespace=my-namespace
    
    
  2. 将角色授予命名空间中的“默认”服务帐户

    如果应用程序没有指定 a serviceAccountName,它将使用“默认”服务帐户。

    注意:授予“默认”服务帐户的权限可用于命名空间中未指定serviceAccountName.

    例如,将“my-namespace”中的只读权限授予“default”服务帐户:

    kubectl create rolebinding default-view \
      --clusterrole=view \
      --serviceaccount=my-namespace:default \
      --namespace=my-namespace
    
    

    许多附加组件作为命名空间中的“默认”服务帐户运行kube-system。要允许这些附加组件以超级用户访问权限运行,请将集群管理员权限授予kube-system命名空间中的“默认”服务帐户。

    警告:启用这意味着kube-system命名空间包含授予超级用户访问集群 API 的权限。

    kubectl create clusterrolebinding add-on-cluster-admin \
      --clusterrole=cluster-admin \
      --serviceaccount=kube-system:default
    
    
  3. 为命名空间中的所有服务帐户授予角色

    如果您希望命名空间中的所有应用程序都有一个角色,无论它们使用什么服务帐户,您都可以为该命名空间的服务帐户组授予一个角色。

    例如,将“my-namespace”中的只读权限授予该命名空间中的所有服务帐户:

    kubectl create rolebinding serviceaccounts-view \
      --clusterrole=view \
      --group=system:serviceaccounts:my-namespace \
      --namespace=my-namespace
    
    
  4. 为集群范围内的所有服务帐户授予有限角色(不鼓励)

    如果您不想管理每个命名空间的权限,您可以将集群范围的角色授予所有服务帐户。

    例如,将所有命名空间的只读权限授予集群中的所有服务帐户:

    kubectl create clusterrolebinding serviceaccounts-view \
      --clusterrole=view \
     --group=system:serviceaccounts
    
    
  5. 授予对集群范围内所有服务帐户的超级用户访问权限(强烈建议不要这样做)

    如果您根本不关心分区权限,您可以授予超级用户访问所有服务帐户的权限。

    警告:这允许任何应用程序完全访问您的集群,并授予任何对 Secrets 具有读取访问权限(或创建任何 pod)的用户对您的集群的完全访问权限。

    kubectl create clusterrolebinding serviceaccounts-cluster-admin \
      --clusterrole=cluster-admin \
      --group=system:serviceaccounts
    
    

端点的写入权限

在 Kubernetes v1.22 之前创建的 Kubernetes 集群在聚合的“编辑”和“管理员”角色中包含对端点的写入访问权限。作为 CVE-2021-25740的缓解措施,此访问权限不属于您使用 Kubernetes v1.22 或更高版本创建的集群中的聚合角色的一部分。

已升级到 Kubernetes v1.22 的现有集群将不受此更改的影响。CVE 公告包括在现有集群中限制此访问的指南。

如果您希望新集群在聚合角色中保留此级别的访问权限,您可以创建以下 ClusterRole:

access/endpoints-aggregated.yaml [图片上传失败...(image-7e18dd-1646729506282)]

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    kubernetes.io/description: |-
      Add endpoints write permissions to the edit and admin roles. This was
      removed by default in 1.22 because of CVE-2021-25740\. See
      https://issue.k8s.io/103675\. This can allow writers to direct LoadBalancer
      or Ingress implementations to expose backend IPs that would not otherwise
      be accessible, and can circumvent network policies or security controls
      intended to prevent/isolate access to those backends.      
  labels:
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
  name: custom:aggregate-to-edit:endpoints # you can change this if you wish
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "deletecollection", "patch", "update"]

从 ABAC 升级

最初运行旧 Kubernetes 版本的集群通常使用宽松的 ABAC 策略,包括授予对所有服务帐户的完整 API 访问权限。

默认 RBAC 策略授予控制平面组件、节点和控制器的范围权限,但不授予命名空间之外的服务帐户kube-system权限(除了授予所有经过身份验证的用户的发现权限)。

虽然更安全,但这可能会破坏期望自动接收 API 权限的现有工作负载。以下是管理这种转变的两种方法:

并行授权人

运行 RBAC 和 ABAC 授权方,并指定包含旧 ABAC 策略的策略文件:

--authorization-mode=...,RBAC,ABAC --authorization-policy-file=mypolicy.json

详细解释第一个命令行选项:如果较早的授权方(例如 Node)拒绝请求,则 RBAC 授权方会尝试授权 API 请求。如果 RBAC 也拒绝该 API 请求,则运行 ABAC 授权方。这意味着允许RBAC 或 ABAC 策略允许的任何请求。

--vmodule=rbac*=5当 kube-apiserver 在 RBAC 组件(或)的日志级别为 5 或更高级别运行时--v=5,您可以在 API 服务器日志中看到 RBAC 拒绝(以 为前缀RBAC)。您可以使用该信息来确定需要将哪些角色授予哪些用户、组或服务帐户。

角色授予服务帐户并且工作负载正在运行且服务器日志中没有 RBAC 拒绝消息后,您可以删除 ABAC 授权方。

许可 RBAC 权限

您可以使用 RBAC 角色绑定复制许可 ABAC 策略。

警告:

以下策略允许所有服务帐户充当集群管理员。在容器中运行的任何应用程序都会自动接收服务帐户凭据,并且可以针对 API 执行任何操作,包括查看机密和修改权限。这不是推荐的策略。

kubectl create clusterrolebinding permissive-binding \
  --clusterrole=cluster-admin \
  --user=admin \
  --user=kubelet \
  --group=system:serviceaccounts

过渡到使用 RBAC 后,您应该调整集群的访问控制,以确保这些满足您的信息安全需求。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容