24

ClusterRole and ClusterRoleBinding

Video: Day 24/40 — Kubernetes RBAC Continued (ClusterRole & ClusterRoleBinding) • https://www.youtube.com/watch?v=DswQe7shSa4 • Duration: ~15 min

Key terms

TermMeaning
ClusterRoleA cluster-wide permission set
ClusterRoleBindingGrants a ClusterRole across the whole cluster
Cluster-scopedObjects not tied to a namespace (nodes, PVs)
NamespacedObjects that live inside a namespace
AggregationComposing ClusterRoles via labels
Built-in rolesadmin / edit / view / cluster-admin

Problem & solution

Namespaced Roles can't grant access to cluster-scoped resources (nodes, PVs, namespaces, CSRs) or apply across all namespaces at once. Cluster-wide permissions need a cluster-scoped RBAC mechanism.

Solution: Use a ClusterRole + ClusterRoleBinding for cluster-scoped resources (nodes, PVs) or to grant the same permissions across all namespaces.

The analogy

Now hand a senior engineer a master keycard that opens doors in every building across the whole port, not just one. The same card also reaches shared facilities that belong to no single building at all, the main gates, the rail yard, the perimeter fence. In Kubernetes a ClusterRole is that port-wide list of doors, a ClusterRoleBinding is the master card linking it to a person, and together they grant access across all namespaces plus cluster-scoped resources like nodes that no namespace owns.

Where this fits in the cluster

The same cluster entities appear in every day's notes; the diagram below shows where this day's topic fits.

Why we need cluster-scoped RBAC

Role/RoleBinding (Day 23) are namespaced — they can't grant access to:

   - cluster-scoped resources: nodes, persistentvolumes, namespaces, CSRs
   - resources across ALL namespaces at once

ClusterRole + ClusterRoleBinding solve exactly that.

Namespaced vs cluster-scoped (the whole map)

RBAC has two tiers: namespaced objects (Role + RoleBinding) and cluster-wide objects (ClusterRole + ClusterRoleBinding). The binding decides the scope.

   SCOPE        PERMISSIONS        BINDING
   namespace    Role               RoleBinding         -> one namespace
   cluster      ClusterRole        ClusterRoleBinding  -> whole cluster

Concretely, that means each permission object can reach a different set of resources:

   Role         -> verbs on namespaced resources, in ONE namespace
   ClusterRole  -> verbs on cluster-scoped resources, OR namespaced
                   resources across EVERY namespace

Trick: a ClusterRole can be reused by a RoleBinding to grant it in just one namespace — write the permission once, scope it where you like.

Which resources are cluster-scoped?

Ask the API which resources live outside namespaces — those are the ones that require a ClusterRole to grant access.

kubectl api-resources --namespaced=false    # cluster-scoped (nodes, pv, ns...)
kubectl api-resources --namespaced=true     # namespaced (pods, svc, cm...)

ClusterRole (the permissions)

A ClusterRole defines a set of verbs on resources, just like a Role, but it is not tied to any namespace. This is the real Prometheus ClusterRole: the monitoring server must read nodes, services, endpoints, and pods across every namespace to discover its scrape targets.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
  - apiGroups: [""]
    resources: ["nodes", "nodes/metrics", "services", "endpoints", "pods"]
    verbs: ["get", "list", "watch"]
  - nonResourceURLs: ["/metrics"]      # scrape the api-server's own metrics
    verbs: ["get"]

ClusterRoleBinding (attach to a subject, cluster-wide)

A ClusterRoleBinding attaches a ClusterRole to a subject across the entire cluster, every namespace included. Prometheus runs as a ServiceAccount, so the binding targets that SA.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
subjects:
  - kind: ServiceAccount
    name: prometheus
    namespace: monitoring
roleRef:
  kind: ClusterRole
  name: prometheus
  apiGroup: rbac.authorization.k8s.io

Imperative shortcuts

The same objects can be created in one line with kubectl create, handy in the exam and for quick experiments.

kubectl create clusterrole prometheus \
  --verb=get,list,watch --resource=nodes,services,endpoints,pods

kubectl create clusterrolebinding prometheus \
  --clusterrole=prometheus --serviceaccount=monitoring:prometheus

Verify

Use kubectl auth can-i with --as to confirm the binding actually grants the access you intended.

kubectl auth can-i list nodes \
  --as=system:serviceaccount:monitoring:prometheus     # -> yes (cluster-wide)
kubectl auth can-i list pods -A \
  --as=system:serviceaccount:monitoring:prometheus     # -> yes (every namespace)

Built-in ClusterRoles worth knowing

Kubernetes ships with default ClusterRoles you can bind directly instead of writing your own.

   cluster-admin -> god mode (all verbs, all resources) — handle with care
   admin / edit  -> common namespace-level roles (used via RoleBinding)
   view          -> read-only

End-to-end example: Prometheus discovers targets cluster-wide

Prometheus needs to read nodes (cluster-scoped) and pods/services in every namespace, which only a ClusterRole can grant.

Graph legend — each step maps to a concrete object or decision:

Graph stepMaps toWhat it does
list nodes and pods across all namespacesPrometheus service discovery callsEnumerates scrape targets cluster-wide
AuthN system:serviceaccount:monitoring:prometheusthe SA token authnIdentifies the Prometheus ServiceAccount
a namespaced Role can never grant nodesRBAC scope ruleNodes/all-namespace reads are out of a Role's reach
ClusterRoleBinding to ClusterRole prometheusClusterRoleBinding prometheusGrants the SA get/list/watch cluster-wide
200 OK, cluster-wide targets returnedthe allow pathReturns nodes, services, endpoints, and pods everywhere

End-to-end flow

Cluster-scoped resources like nodes can only be granted through a ClusterRole.

Graph legend — each node maps to a concrete object or decision:

Graph nodeMaps toWhat it does
prometheus SA: list nodes/podsthe discovery requestReads targets across the whole cluster
api-server AuthNthe SA token authnResolves the Prometheus ServiceAccount identity
Resource scope?the RBAC authorizerRecognizes nodes are cluster-scoped and reads span all ns
ClusterRoleBinding -> ClusterRole prometheusClusterRoleBinding prometheusBinds the SA to the cluster-wide read role
Allows get/list/watch ... cluster-widethe prometheus ClusterRole rulesPermits reading nodes, services, endpoints, pods everywhere
200 OK: cluster-wide targets returnedthe allow pathPrometheus receives the full target list

Key takeaways

  • ClusterRole/ClusterRoleBinding = cluster-wide RBAC.
  • Needed for cluster-scoped resources (nodes, PVs, namespaces, CSRs) and for granting access across all namespaces.
  • A ClusterRole can be bound by a RoleBinding to limit it to one namespace.
  • Use kubectl api-resources --namespaced=false to see what's cluster-scoped.

Checklist

  • [ ] Listed cluster-scoped resources with api-resources --namespaced=false
  • [ ] Created the prometheus ClusterRole + ClusterRoleBinding
  • [ ] Verified kubectl auth can-i list nodes --as=system:serviceaccount:monitoring:prometheus
  • [ ] Understand reusing a ClusterRole via a RoleBinding for one namespace