CKA — Roles & ClusterRoles
CKA Exam Domain
Cluster Architecture, Installation & Configuration — 25%
Roles and ClusterRoles are the foundation of Kubernetes RBAC. They define what actions are allowed on which resources. You’ll see these on the CKA exam — creating them both imperatively and declaratively.
What Is a Role?
A Role grants permissions within a specific namespace. It says: “In this namespace, you can do these things to these resources.”
If you don’t specify a namespace, a Role cannot exist — it’s namespace-scoped by design.
Here’s a Role that allows reading Pods in the dev namespace:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Let’s break it down:
- apiGroups: [””] — The core API group (Pods, Services, ConfigMaps live here)
- resources: [“pods”] — Which resources this rule applies to
- verbs: [“get”, “list”, “watch”] — What actions are allowed
A Role can have multiple rules. Each rule is an independent permission grant:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-role
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
What Is a ClusterRole?
A ClusterRole grants permissions across the entire cluster — not limited to a single namespace.
Use ClusterRoles for:
- Cluster-scoped resources like Nodes, PersistentVolumes, Namespaces
- Permissions that should apply in all namespaces (when paired with a ClusterRoleBinding)
- Aggregated roles that combine multiple ClusterRoles
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
Notice: No namespace field — ClusterRoles are not namespaced.
Here’s another example granting access to PersistentVolumes and StorageClasses:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: storage-viewer
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
Role vs ClusterRole
| Aspect | Role | ClusterRole |
|---|---|---|
| Scope | Single namespace | Cluster-wide |
| Use Case | Namespace-specific permissions | Cluster resources or cross-namespace |
| Binds With | RoleBinding | ClusterRoleBinding (or RoleBinding for namespace scope) |
| Example Resources | Pods, Services, ConfigMaps | Nodes, PVs, Namespaces |
| metadata.namespace | Required | Not applicable |
Key insight for CKA: A ClusterRole can be bound with a RoleBinding to grant permissions in just one namespace. This is a very common pattern — define permissions once, apply per-namespace.
Defining Permissions
Verbs
Verbs define what you can do with a resource:
| Verb | Description | HTTP Method |
|---|---|---|
get |
Read a single resource | GET |
list |
List all resources of a type | GET (collection) |
watch |
Stream changes in real-time | GET (watch) |
create |
Create a new resource | POST |
update |
Replace an existing resource | PUT |
patch |
Partially modify a resource | PATCH |
delete |
Delete a single resource | DELETE |
deletecollection |
Delete multiple resources | DELETE (collection) |
Use "*" to grant all verbs — but be cautious with this in production.
API Groups
Resources belong to API groups:
| API Group | Resources |
|---|---|
"" (core) |
pods, services, configmaps, secrets, namespaces, nodes, persistentvolumes |
apps |
deployments, statefulsets, daemonsets, replicasets |
batch |
jobs, cronjobs |
rbac.authorization.k8s.io |
roles, clusterroles, rolebindings, clusterrolebindings |
networking.k8s.io |
networkpolicies, ingresses |
storage.k8s.io |
storageclasses |
Exam tip: If you’re unsure about the API group, run kubectl api-resources — it shows the group for every resource.
Resource Names
You can restrict access to specific resources by name:
rules:
- apiGroups: [""]
resources: ["pods"]
resourceNames: ["my-pod", "your-pod"]
verbs: ["get", "update"]
This limits the permission to only those specific Pods.
Common Role Patterns
Read-Only Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-only
namespace: dev
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "deployments", "services", "jobs", "configmaps"]
verbs: ["get", "list", "watch"]
Namespace Admin Role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: namespace-admin
namespace: dev
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
Pod Exec Role
This is CKA-relevant — granting someone the ability to exec into Pods:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-exec
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
Note the sub-resource pods/exec — this is how Kubernetes handles exec, logs, and port-forward.
Aggregated ClusterRoles
Aggregated ClusterRoles automatically combine rules from other ClusterRoles using label selectors. Kubernetes uses this for its built-in roles.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-view
labels:
rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
---
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 by the controller
The monitoring ClusterRole will automatically include all rules from any ClusterRole with the label rbac.example.com/aggregate-to-monitoring: "true".
This is how the built-in admin, edit, and view ClusterRoles work.
kubectl Commands
# Create a Role imperatively
kubectl create role pod-reader --verb=get,list,watch --resource=pods -n dev
# Create a ClusterRole imperatively
kubectl create clusterrole node-reader --verb=get,list,watch --resource=nodes
# List Roles in a namespace
kubectl get roles -n dev
# Describe a Role
kubectl describe role pod-reader -n dev
# List ClusterRoles (excluding system roles)
kubectl get clusterroles | grep -v system:
# View the YAML of a Role
kubectl get role pod-reader -n dev -o yaml
# Check which API group a resource belongs to
kubectl api-resources | grep deployments
Exam speed tip: Use kubectl create role to generate the object quickly, then modify with kubectl edit if needed.
Practice Questions
Q1. Create a Role named secret-reader in the finance namespace that allows get and list on Secrets.
Show Answer
kubectl create namespace finance
kubectl create role secret-reader --verb=get,list --resource=secrets -n finance
Or declaratively:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
namespace: finance
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
Q2. What is the difference between a Role and a ClusterRole?
Show Answer
A Role is namespace-scoped — it only grants permissions within a single namespace. A ClusterRole is cluster-wide — it can grant permissions on cluster-scoped resources (like Nodes) or be used across all namespaces.
Q3. Create a ClusterRole named pv-manager that allows all operations on PersistentVolumes.
Show Answer
kubectl create clusterrole pv-manager --verb='*' --resource=persistentvolumes
Or declaratively:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pv-manager
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["*"]
Q4. Create a Role that allows a user to exec into Pods in the debug namespace.
Show Answer
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-exec
namespace: debug
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
You need both the base pods resource (to find them) and the pods/exec sub-resource (to exec into them).
Q5. Which command shows the API group for a specific resource type?
Show Answer
kubectl api-resources | grep <resource-name>
For example:
kubectl api-resources | grep deployments
# Output: deployments deploy apps/v1 true Deployment
The apps in apps/v1 is the API group. Use "" (empty string) in your Role for core resources that have no group prefix.