> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Cluster Roles

> Guide to inspecting and creating Kubernetes ClusterRoles and ClusterRoleBindings to grant user Michelle access to cluster scoped resources like nodes and storage

This lesson walks through ClusterRoles and ClusterRoleBindings: how to inspect what's already in the cluster, examine who has cluster-admin privileges, and create ClusterRoles and ClusterRoleBindings to grant a user (michelle) access to cluster-scoped resources (nodes and storage).

## Inspect existing ClusterRoles

Count all ClusterRoles in the cluster:

```bash theme={null}
kubectl get clusterroles --no-headers | wc -l
```

Example output (your environment will vary; this environment shows 69):

```text theme={null}
69
```

ClusterRoles are cluster-scoped (not namespaced). To list them:

```bash theme={null}
kubectl get clusterroles
```

You will see many system roles, for example `cluster-admin`, controller roles, and add-on roles such as `system:coredns` or `local-path-provisioner-role`.

## Inspect existing ClusterRoleBindings

Count ClusterRoleBindings:

```bash theme={null}
kubectl get clusterrolebindings --no-headers | wc -l
```

Example output in this environment:

```text theme={null}
54
```

ClusterRoleBindings are cluster-scoped as well.

<Callout icon="lightbulb" color="#1CB2FE">
  ClusterRoles and ClusterRoleBindings are cluster-scoped objects — they do not belong to any namespace.
</Callout>

## Check who has cluster-admin

Find ClusterRoleBindings that reference the `cluster-admin` ClusterRole:

```bash theme={null}
kubectl get clusterrolebindings | grep cluster-admin
```

Example output:

```text theme={null}
cluster-admin                          12m   ClusterRole/cluster-admin
helm-kube-system-traefik               12m   ClusterRole/cluster-admin
helm-kube-system-traefik-crd           12m   ClusterRole/cluster-admin
```

Describe the `cluster-admin` ClusterRoleBinding to view its subjects:

```bash theme={null}
kubectl describe clusterrolebinding cluster-admin
```

Example output (shows the `system:masters` group is bound):

```text theme={null}
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name           Namespace
  ----   ----           ---------
  Group  system:masters
```

Inspect the `cluster-admin` ClusterRole to see the full privileges it grants:

```bash theme={null}
kubectl describe clusterrole cluster-admin
```

Example output:

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

This shows `cluster-admin` grants full access across all resources and non-resource URLs.

<Callout icon="warning" color="#FF6B6B">
  The `cluster-admin` role provides full cluster-wide privileges. Bind it only to trusted users or service accounts.
</Callout>

## Task: Grant Michelle access to nodes

Michelle currently cannot list nodes. To see the error when attempting to list nodes as `michelle`:

```bash theme={null}
kubectl get nodes --as=michelle
```

Example error:

```text theme={null}
Error from server (Forbidden): nodes is forbidden: User "michelle" cannot list resource "nodes" in API group "" at the cluster scope
```

To grant Michelle read-only access to nodes (list/get/watch), create a ClusterRole and bind it to her:

Create the ClusterRole:

```bash theme={null}
kubectl create clusterrole michelle-role --verb=get,list,watch --resource=nodes
```

Create the ClusterRoleBinding that ties the role to the user `michelle`:

```bash theme={null}
kubectl create clusterrolebinding michelle-role-binding --clusterrole=michelle-role --user=michelle
```

Verify the ClusterRole:

```bash theme={null}
kubectl describe clusterrole michelle-role
```

Example output:

```text theme={null}
Name:        michelle-role
Labels:      <none>
Annotations: <none>
PolicyRule:
  Resources   Non-Resource URLs   Resource Names   Verbs
  --------    -----------------   --------------   -----
  nodes       []                  []               [get list watch]
```

Verify the ClusterRoleBinding:

```bash theme={null}
kubectl describe clusterrolebinding michelle-role-binding
```

Example output:

```text theme={null}
Name:        michelle-role-binding
Labels:      <none>
Annotations: <none>
Role:
  Kind:  ClusterRole
  Name:  michelle-role
Subjects:
  Kind   Name      Namespace
  -----  ----      -------
  User   michelle
```

Test the permission as Michelle:

```bash theme={null}
kubectl get nodes --as=michelle
```

Example successful output:

```text theme={null}
NAME           STATUS   ROLES                   AGE   VERSION
controlplane   Ready    control-plane,master    16m   v1.23.3+k3s1
```

## Task: Grant Michelle access to storage (PersistentVolumes and StorageClasses)

Michelle now needs permissions for storage resources. Use `kubectl api-resources` to determine resource names, short names, API groups, and whether a resource is namespaced:

```bash theme={null}
kubectl api-resources
```

Relevant cluster-scoped storage resources include:

| Resource | Short name | apiGroup / apiVersion | Namespaced? |
| - | - | - | - |
| persistentvolumes | `pv` | `v1` (core) | No |
| storageclasses | `sc` | `storage.k8s.io/v1` | No |

Create a ClusterRole that allows Michelle to `list`, `create`, `get`, and `watch` PersistentVolumes and StorageClasses:

```bash theme={null}
kubectl create clusterrole storage-admin --resource=persistentvolumes,storageclasses.storage.k8s.io --verb=list,create,get,watch
```

Describe the new ClusterRole:

```bash theme={null}
kubectl describe clusterrole storage-admin
```

Example output:

```text theme={null}
Name:        storage-admin
Labels:      <none>
Annotations: <none>
PolicyRule:
  Resources                         Non-Resource URLs  Resource Names  Verbs
  ---------                         -----------------  --------------  -----
  persistentvolumes                 []                 []               [list create get watch]
  storageclasses.storage.k8s.io     []                 []               [list create get watch]
```

You can also view the ClusterRole YAML:

```bash theme={null}
kubectl get clusterrole storage-admin -o yaml
```

Example YAML output:

```yaml theme={null}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: "2022-04-18T00:20:48Z"
  name: storage-admin
  resourceVersion: "921"
  uid: e0ee52a7-b32c-4a42-b8b7-a783b040cd4e
rules:
- apiGroups:
  - ""
  resources:
  - persistentvolumes
  verbs:
  - list
  - create
  - get
  - watch
- apiGroups:
  - storage.k8s.io
  resources:
  - storageclasses
  verbs:
  - list
  - create
  - get
  - watch
```

Bind the `storage-admin` ClusterRole to Michelle:

```bash theme={null}
kubectl create clusterrolebinding michelle-storage-binding --clusterrole=storage-admin --user=michelle
```

Verify Michelle can list storage classes (or persistent volumes) by running as Michelle:

```bash theme={null}
kubectl get storageclasses --as=michelle
# or short name:
kubectl get sc --as=michelle
```

If the binding is configured correctly, Michelle will be able to list StorageClasses and PersistentVolumes.

## Quick reference: Useful kubectl commands

| Purpose | Command |
| - | - |
| Count ClusterRoles | `kubectl get clusterroles --no-headers \| wc -l` |
| List ClusterRoleBindings | `kubectl get clusterrolebindings` |
| Inspect a ClusterRoleBinding | `kubectl describe clusterrolebinding <name>` |
| Inspect a ClusterRole | `kubectl describe clusterrole <name>` |
| Show API resources | `kubectl api-resources` |
| Test permissions as a user | `kubectl get <resource> --as=<username>` |

## Summary

* ClusterRoles and ClusterRoleBindings are cluster-scoped RBAC objects.
* `cluster-admin` grants full cluster privileges and is typically bound to `system:masters`.
* To grant a user access to cluster-scoped resources (nodes, PVs, StorageClasses), create a ClusterRole with the necessary verbs and resources, then create a ClusterRoleBinding to associate the role with the user (or group or service account).
* Use `kubectl api-resources` to discover resource names, shortnames, API groups, and whether a resource is namespaced.

## Links and references

* Kubernetes RBAC: [https://kubernetes.io/docs/reference/access-authn-authz/rbac/](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
* kubectl reference: [https://kubernetes.io/docs/reference/kubectl/overview/](https://kubernetes.io/docs/reference/kubectl/overview/)
* kubectl api-resources: [https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#api-resources](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#api-resources)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/77826599-d456-4cb5-8cbc-b713cc077b45/lesson/cee9fef5-f409-40d3-949f-91efa928cb5b" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.