CKAD field manual
k8s RBAC YAML example
Creating a ServiceAccount grants nothing. Bind a Role to it, then check with can-i.
kubectl create role pod-read -n app --verb=get,list,watch --resource=pods
kubectl create rolebinding pod-read -n app --role=pod-read --serviceaccount=app:api
kubectl auth can-i list pods -n app --as=system:serviceaccount:app:api
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-read
namespace: app
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-read
namespace: app
subjects:
- kind: ServiceAccount
name: api
namespace: app
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-read
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-read
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pod-read
subjects:
- kind: ServiceAccount
name: api
namespace: app
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-read
Fields
- verbs
- get, list, watch, create, update, patch, delete. list is not get.
- resources
- pods, not Pod. pods/log and pods/status are subresources.
- roleRef
- kind is Role or ClusterRole. name must exist. apiGroup is rbac.authorization.k8s.io.
- subjects
- kind ServiceAccount needs name and namespace. User and Group do not.
- kubectl create role
- --verb and --resource. Then bind. The Role alone does nothing.
- kubectl auth can-i
- --as=system:serviceaccount:ns:sa. This is the check the exam wants.
Watch
- A Role is namespaced. A ClusterRole is cluster-wide. Binding kind must match the object you created.
- resources: ["pods"] — lowercase, plural. apiGroups: [""] for core. apps for Deployments.
- can-i without --as checks you, not the SA. Use --as=system:serviceaccount:<ns>:<sa>.
Official docs RBAC