# ClusterRole 和 ClusterRoleBinding

`ClusterRole` 和 `ClusterRoleBinding` 资源都是集群级资源。前者决定可以针对哪些 URL 路径（包括集群级别资源、命名空间级别资源、非资源型 URL）执行哪些操作；后者将前者与用户主体绑定。

{% hint style="info" %}
🧐 `ClusterRole` 也可以与 `RoleBinding` 进行绑定，虽然这样只能操作 `RoleBinding` 所在命名空间的 URL 路径
{% endhint %}

## 管理 ClusterRole 和 ClusterRoleBinding

### 创建 ClusterRole

ClusterRole 资源属于 Kubernetes 提供的资源类型，可以 YAML 定义进行创建，其共可以对两类 URL 路径进行操作权限控制：

* 资源（命名空间资源以及集群级资源）：在 `clusterrole.rules.resources` 中定义资源；
* 非资源型 URL（/api、/apis、/healthz 等）：在 `clusterrole.rules.nonresourceURLs` 中定义非资源型 URL；

下面举一个例子，创建一个名为 `pv-reader` 的 ClusterRole，该 Role 具备 `get` 和 `list` 所有 PV 资源的权限：

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole    # 类型为 ClusterRole
metadata:
  name: pv-reader
rules:    # 规则定义
- apiGroups: [""]    # 由于 persistentvolumes.apiGroup=v1，即没有 "/"，"/" 前面是资源所属的组，所以 persistentvolumes 不属于任何组，所以这里为空
  resources: ["persistentvolumes"]    # 限制的资源类型
  verbs: ["get", "list"]    # 能够执行 get 和 list 操作
  # resourceName: test-pv    # 可以指定具体的资源对象
# - nonResourceURLs:    # 对非资源型 URL 进行限制，包括 /api, /apis, /healthz
#   - /api
#   - /apis
#   - /healthz
#   verbs: ["get"]
```

同时也可以使用 `kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--non-resource-url=[]] [--dry-run] [options]` 命令创建 ClusterRole，如下：

```bash
kubectl create clusterrole pv-reader --verb=get,list --resource=persistentvolumes
```

### 创建 ClusterRoleBinding

ClusterRoleBinding 资源属于 Kubernetes 提供的资源类型，可以 YAML 定义进行创建。例如，创建一个名为 `pv-test` 的 ClusterRoleBinding，并将名为 `pv-reader` 的 ClusterRole 与命名空间 `foo` 中的 `default` ServiceAccount 进行绑定：

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding    # 资源类型
metadata:
  name: pv-test
roleRef:    # 绑定的 ClusterRole（与 RoleBinding 不同，它只能绑定 ClusterRole 资源）
  apiGroup: rbac.authorization.k8s.io    # ClusterRole 所属 API 组
  kind: ClusterRole    # 绑定 ClusterRole 资源
  name: pv-reader    # 绑定的 ClusterRole 名字
subjects:    # 绑定的用户主体（可以是用户、ServiceAccount、组）
- kind: ServiceAccount    # 绑定 foo 命名空间中的名为 default 的 ServiceAccount
  name: default
  namespace: foo
```

同时也可以使用 `kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] [options]` 命令来创建 ClusterRoleBinding，如下：

```bash
kubectl create clusterrolebinding pv-test --clusterrole=pv-reader --serviceaccount=foo:default
```

### 测试

根据上述的创建命令创建完后，会得到下面的关系图，由于 ServiceAccount 为命名空间中的默认 ServiceAccount，因此若 Pod 的 `pod.spec.serviceAccountName` 没有指定的话，则默认使用其所在命名空间的 `default` ServiceAccount。

![部署结果关系图](https://2906552408-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6Ub8CloS5kJszh6xSR%2Fsync%2F046cf59d446186558ba8d0f091abedf39636d350.png?generation=1588594612965647\&alt=media)

在命名空间 `foo` 中生成一个 Pod，使用命名空间中的默认 ServiceAccount，那么正常情况下，这个 Pod 将能通过 API 服务器获得集群资源中的所有的 PV 对象信息。在 Pod 中的测试命令如下（Pod 使用的是 luksa/kubectl-proxy 镜像，内部安装了 kubectl 组件）：

```bash
curl localhost:8001/api/v1/persistentvolumes
{
  "kind": "PersistentVolumeList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/persistentvolumes",
    "resourceVersion": "840811"
  },
  "items": [
    {
      "metadata": {
        "name": "pvc-221ca811-2028-4703-bd7f-a0f178a7d510",
        "selfLink": "/api/v1/persistentvolumes/pvc-221ca811-2028-4703-bd7f-a0f178a7d510",
        "uid": "c1475ff5-baab-4f48-87b7-46b031cbd8ca",
                ...
```

> 从输出结果可以看出，在 iterms 中详细列出了所有 PV 资源对象的详细信息

## 集群中默认的 ClusterRole 和 ClusterRoleBinding

Kubernetes 提供了一些默认的 `ClusterRole` 资源和 `ClusterRoleBinding` 资源，每次 API 服务器重启时都会重置它们，因为这样可以保证若用户由于错误操作修改了权限配置，导致默认的 ServiceAccount 不安全时，在重启后即可解决该问题。

默认的 ClusterRole 和 ClusterRoleBinding 资源如下：

```bash
# kubectl get clusterrole
NAME                                                                   AGE
admin                                                                  109d
cluster-admin                                                          109d
edit                                                                   109d
kubernetes-dashboard                                                   109d
minikube-ingress-dns                                                   66d
system:aggregate-to-admin                                              109d
system:aggregate-to-edit                                               109d
system:aggregate-to-view                                               109d
system:auth-delegator                                                  109d
system:basic-user                                                      109d
system:certificates.k8s.io:certificatesigningrequests:nodeclient       109d
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   109d
system:controller:attachdetach-controller                              109d
system:controller:certificate-controller                               109d
system:controller:clusterrole-aggregation-controller                   109d
system:controller:cronjob-controller                                   109d
system:controller:daemon-set-controller                                109d
system:controller:deployment-controller                                109d
system:controller:disruption-controller                                109d
system:controller:endpoint-controller                                  109d
system:controller:expand-controller                                    109d
system:controller:generic-garbage-collector                            109d
system:controller:horizontal-pod-autoscaler                            109d
system:controller:job-controller                                       109d
system:controller:namespace-controller                                 109d
system:controller:node-controller                                      109d
system:controller:persistent-volume-binder                             109d
system:controller:pod-garbage-collector                                109d
system:controller:pv-protection-controller                             109d
system:controller:pvc-protection-controller                            109d
system:controller:replicaset-controller                                109d
system:controller:replication-controller                               109d
system:controller:resourcequota-controller                             109d
system:controller:route-controller                                     109d
system:controller:service-account-controller                           109d
system:controller:service-controller                                   109d
system:controller:statefulset-controller                               109d
system:controller:ttl-controller                                       109d
system:coredns                                                         109d
system:csi-external-attacher                                           109d
system:csi-external-provisioner                                        109d
system:discovery                                                       109d
system:heapster                                                        109d
system:kube-aggregator                                                 109d
system:kube-controller-manager                                         109d
system:kube-dns                                                        109d
system:kube-scheduler                                                  109d
system:kubelet-api-admin                                               109d
system:nginx-ingress                                                   109d
system:node                                                            109d
system:node-bootstrapper                                               109d
system:node-problem-detector                                           109d
system:node-proxier                                                    109d
system:persistent-volume-provisioner                                   109d
system:public-info-viewer                                              109d
system:volume-scheduler                                                109d
view                                                                   109d
# kubectl get clusterrolebinding
NAME                                                   AGE
cluster-admin                                          109d
kubeadm:kubelet-bootstrap                              109d
kubeadm:node-autoapprove-bootstrap                     109d
kubeadm:node-autoapprove-certificate-rotation          109d
kubeadm:node-proxier                                   109d
kubernetes-dashboard                                   109d
minikube-ingress-dns                                   66d
minikube-rbac                                          109d
storage-provisioner                                    109d
system:basic-user                                      109d
system:controller:attachdetach-controller              109d
system:controller:certificate-controller               109d
system:controller:clusterrole-aggregation-controller   109d
system:controller:cronjob-controller                   109d
system:controller:daemon-set-controller                109d
system:controller:deployment-controller                109d
system:controller:disruption-controller                109d
system:controller:endpoint-controller                  109d
system:controller:expand-controller                    109d
system:controller:generic-garbage-collector            109d
system:controller:horizontal-pod-autoscaler            109d
system:controller:job-controller                       109d
system:controller:namespace-controller                 109d
system:controller:node-controller                      109d
system:controller:persistent-volume-binder             109d
system:controller:pod-garbage-collector                109d
system:controller:pv-protection-controller             109d
system:controller:pvc-protection-controller            109d
system:controller:replicaset-controller                109d
system:controller:replication-controller               109d
system:controller:resourcequota-controller             109d
system:controller:route-controller                     109d
system:controller:service-account-controller           109d
system:controller:service-controller                   109d
system:controller:statefulset-controller               109d
system:controller:ttl-controller                       109d
system:coredns                                         109d
system:discovery                                       109d
system:kube-controller-manager                         109d
system:kube-dns                                        109d
system:kube-scheduler                                  109d
system:nginx-ingress                                   109d
system:node                                            109d
system:node-proxier                                    109d
system:public-info-viewer                              109d
system:volume-scheduler                                109d
```

其中比较重要的 ClusterRole 有 `view`、`edit`、`admin` 以及 `cluster-admin`。

#### view 允许对资源的只读访问

可以通过 `kubectl describe clusterrole view` 查看其定义。

它允许 `get`, `list`, `watch` 大多数命名空间级别的资源，除了 Role、RoleBinding 以及 Secret 资源。

#### edit 允许对资源的修改

可以通过 `kubectl describe clusterrole edit` 查看其定义。

它允许对命名空间级别的资源进行修改，同时允许读取和修改 Secret 资源，但是不能查看或修改 Role 和 RoleBinding 资源。

#### admin 赋予一个命名空间全部控制权

可以通过 `kubectl describe clusterrole admin` 查看其定义。

它允许对命名空间级别的所有资源进行读取和修改。

#### cluster-admin 得到完全控制

可以通过 `kubectl describe clusterrole cluster-admin` 查看其定义：

```bash
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]
```

它允许对 Kubernetes 集群的完全控制权限。
