Files
kuboard-press/learning/k8s-advanced/sec/rbac/api.md
huanqing.shao ceb6b8eeab remove hash
2020-02-05 17:39:19 +08:00

393 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
vssueId: 175
layout: LearningLayout
description: Kubernetes教程_Role-based_access_control_(RBAC)基于角色的访问控制_是Kubernetes中支持的一种授权方式。使用rbac.authorization.k8s.io_API来驱动授权决策_允许管理员通过该API动态配置授权策略。
meta:
- name: keywords
content: Kubernetes 教程,Kubernetes 授权,Kubernetes RBAC,Kubernetes权限
---
# RBAC 授权接口
<AdSenseTitle/>
> 参考文档:[Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
<Course courseId="484058" />
Role-based access control (RBAC)基于角色的访问控制是Kubernetes中支持的一种授权方式。使用 `rbac.authorization.k8s.io` API 来驱动授权决策,允许管理员通过该 API 动态配置授权策略。自 Kubernetes 1.8 起RBAC 模式已稳定可用,且通过 `rbac.authorization.k8s.io/v1` API 提供支持。如果要激活 RBAC在启动 API Server 时必须使用参数 `--authorization-mode=RBAC`
> 译者注:
>
> 使用 kubeadm 安装 kubernetes 后,启动 API Server 的参数有 `--authorization-mode=Node,RBAC`,同时激活了 [Node Authorization](https://kubernetes.io/docs/reference/access-authn-authz/node/) 和 RBAC Authorization。因此如果您参考 kuboard.cn 提供的文档安装 kubernetes默认是启用 RBAC 授权的。
RBAC API 声明了四种顶级top-levelKubernetes 对象类型,管理员可以使用 kubectl、API接口调用等方式操作这四种类型的对象。在阅读本系列 RBAC 文档时,您可以使用 `kubectl apply -f (resource).yaml` 直接执行并尝试其效果。
## Role和ClusterRole
在 RBAC API 中,角色包含了一组授权规则。此处的授权规则是纯粹的“授予”规则(没有“否定”规则)。角色可以用以下两种形式定义:
* 名称空间中的 `Role`
* 集群范围内的 `ClusterRole`
`Role` 只能用来授权访问单个名称空间内部的资源。下面的例子中定义的 `Role` 授权读取 `default` 名称空间中的 Pod
``` yaml
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` 可以用来授予与 `Role` 相同的权限,但是由于 `ClusterRole` 是集群范围内的,也可以用来授权访问如下资源:
* 集群范围内的资源(例如节点)
* 非资源性质的端口(例如 "/healthz"
* 所有名称空间内的资源(例如 Pod授权后可以使用这类语句 `kubectl get pods --all-namespaces`
下面的 `ClusterRole` 可以授权读取任意特定名称空间的 secrets或所有名称空间的 secrets取决于如何 [绑定](#RoleBinding和ClusterRoleBinding)
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
```
## RoleBinding和ClusterRoleBinding
角色绑定将角色中定义的权限授予给一个用户或者一组用户。角色绑定包含了一个被授权对象的列表user、group、service account以及一个被授予的角色的引用。角色绑定有如下两种定义方式
* 名称空间内的 `RoleBinding`
* 集群范围内的 `ClusterRoleBinding`
`RoleBinding` 可以引用同名称空间下的 `Role`。下面的 `RoleBinding` 将 “default” 名称空间中的角色 “pod-reader” 授予给用户 “jane”此时 “jane” 可以读取 “default” 名称空间中的 pod。
* `roleRef`:引用被授予的角色
* `kind` 可以是 `Role` 或者 `ClusterRole`
* `name` 是被引用的 `Role` 或者 `ClusterRole` 的名称
此例中的 RoleBinding 使用 `roleRef` 将用户 “jane” 绑定到上面创建的 `pod-reader` 这个 `Role`
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
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` 也可以引用一个 `ClusterRole`,用来授予 `RoleBinding` 所在名称空间中的对象的访问权限。这样,管理员可以在集群内定义一组通用的角色,并且在不同的名称空间中重用这些角色。
例如,尽管下面的 `RoleBinding` 引用了 `ClusterRole`“dave”被授权的用户大小写敏感将只能够读取 “development” 名称空间(`RoleBinding`所在的名称空间)中的 secrets 对象。
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
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
```
`ClusterRoleBinding` 可以被用来授权访问集群级别的资源,以及所有名称空间中的资源。下面的 `ClusterRoleBinding` 允许 “manager” 用户组中的用户读取任何名称空间中的 secrets
``` yaml
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
```
`RoleBinding`、`ClusterRoleBinding` 创建后,其 `roleRef` 字段不可修改,如果尝试修改则会报错。如果需要修改 `roleRef` 字段,必须将 `RoleBinding` 或 `ClusterRoleBinding` 删除后重新创建。这样做的主要原因有如下两点:
1. `roleRef` 不同的话,本质上是完全不同的绑定关系。要求删除并重建 `RoleBinding` 或 `ClusterRoleBinding` 以修改 `roleRef` 字段可以确保列表中的被授权的对象用户、用户组、Service Account都是经过考虑的如果直接修改 `roleRef` 字段用户将不会核对列表中的用户、用户组、Service Account是否应该被授予新的角色
2. 不允许修改 `roleRef` 字段的情况下,可以将修改 `RoleBinding`、`ClusterRoleBinding` 的权限授予给某个用户使其可以管理其中的被授权对象列表用户、用户组、Service Account但是不能够修改对应的角色权限
`kubectl auth reconcile` 命令行工具可以创建或更新包含 RBAC 对象的描述文件,删除、重新创建 `RoleBinding`、`ClusterRoleBinding`。更多信息请参考 [command usage and examples](./cmd.html#kubectl-auth-reconcile)
## Referring to Resources
大多数的资源都以其名称作为标识,例如 “pods”与其 API 的 URL 路径中的标识相同。某些 Kubernetes API 也包含了 “subresource 子资源”,例如 pod 的 logs。其 API 的 URL 如下所示:
```
GET /api/v1/namespaces/{namespace}/pods/{name}/log
```
此时, “pods” 是名称空间中的资源“log” 是 pod 的子资源。在 RBAC 的 role 中,通过 `/` 来分隔资源和子资源。例如,下面的 yaml 可以授权读取 pod 和 pod 的 log
``` yaml
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` 列表来引用其实例。此时,可以限定被访问的单个对象实例
。例如,下面的 yaml 可以授权对单个 configmap 进行 “get” 和 “update” 操作:
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
```
> * “create” 操作不能通过 resourceName 来限定,因为该对象的名字在授权的时候还不存在
> * “deletecollection” 操作也不能通过 resourceName 来限定
## Aggregated ClusterRoles
KUbernetes 1.9 开始,可以使用 `aggregationRule` 来将 ClusterRole 与其他的 ClusterRole 合并。Aggregated ClusterRole 的权限由控制器管理,是所有与其 label selector 匹配的 ClusterRole 中所定义权限的并集。下面是一个 aggregated ClusterRole 的例子:
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # Rules are automatically filled in by the controller manager.
```
创建一个与 aggregated ClusterRole 的 label selector 匹配的 ClusterRole 时,将会向该 aggregated ClusterRole 添加规则。在上面的例子中,可以向通过创建另外一个包含标签 `rbac.example.com/aggregate-to-monitoring: true` 的 ClusterRole 向名称为 “monitoring” 的 ClusterRole 添加规则:
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
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"]
```
默认的面向用户的角色是 aggregated ClusterRole。这样管理员就可以为默认角色添加 custom resource 的规则,例如 CustomResourceDefinition。
例如,下面的 ClusterRole 允许 “admin” 和 “edit” 这两个默认角色管理 custom resource “CronTabs”而 “view” 角色则只能读取这些资源。
``` yaml
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 Examples
> 例子中只展示了 `rules` 这一部分。
允许读取 core [API Group](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups) 中的 “pods”
``` yaml
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
```
允许 读取/写入 “extensions” 和 “apps” API Group 中的 “deployments”
``` yaml
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
```
允许读取 “pods”、读取/写入 “jobs”
``` yaml
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
```
允许读取名为 “my-config” 的 ConfigMap必须绑定到某个名称空间中的 `RoleBinding`
``` yaml
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
```
允许读取 core API Group 中的 “nodes” (由于节点时集群级别的对象,此规则必须定义在 `ClusterRole` 中,也不惜绑定到一个 `ClusterRoleBinding`
``` yaml
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
```
允许对非资源型的端口 “/healthz”及其所有子路径执行 “GET” 和 “POST” 请求(此规则必须定义在 `ClusterRole` 中,也不惜绑定到一个 `ClusterRoleBinding`
``` yaml
rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
verbs: ["get", "post"]
```
## Referring to Subjects
`RoleBinding`、`ClusterRoleBinding` 将角色绑定到被授权主体。被授权主体可以是 group、user、service account。
User 通过 string 来标识,可以是普通的 username例如 “alice”email风格的名称例如“bob@example.com”或者以字符数形式定义的数字ID。由集群管理员通过配置 [authentication modules](https://kubernetes.io/docs/reference/access-authn-authz/authentication/) 来决定产生何种格式的 usernameRBAC 授权系统对此做限定。但是,`system:` 前缀是被 Kubernetes 系统预留的,管理员应该确保 username 不包含这一前缀。
KUbernetes 中的 Group 信息由 Authenticator 模块提供。与 user 一样group 也使用 string 来标识,`system:` 前缀也是被预留的,但是没有格式要求。
[Service Account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 使用 `system:serviceaccount:` 前缀的 username并且属于 `system:serviceaccounts:` 前缀的 group。
### Role Binding Examples
下面的例子中只显示了 `RoleBinding`、`ClusterRoleBinding` 的 `subjects` 部分。
绑定 user “alice@example.com”
``` yaml
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
```
绑定 group “frontend-admins”
``` yaml
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
```
绑定 kube-system 名称空间中的 default service account
``` yaml
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
```
绑定 qa 名称空间中的所有 service account
``` yaml
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
```
绑定任意 service account
``` yaml
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
```
绑定所有已认证的用户kubernetes 1.5+
``` yaml
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
```
绑定所有未认证用户kubernetes 1.5+
``` yaml
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
```
绑定所有用户kubernetes 1.5+
``` yaml
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
```