Video Thumbnail for Lesson
4.14: Role Based Access Control

Role Based Access Control (RBAC)

Kubernetes uses RBAC to regulate which users or service accounts may perform specific actions on resources. Permissions are granted by binding a role (defined either at the namespace or cluster level) to a subject such as a service account.

Official docs: https://kubernetes.io/docs/reference/access-authn-authz/rbac/

Hands-On: Working with RBAC

We will allow a Job running kubectl to read pods. First we will see the failure case, then grant namespace-scoped permissions, and finally grant cluster-scoped permissions.

1. Create a Namespace for the Examples

First, create a namespace for these examples and set it as the default.

# task 01-create-namespace
# - Create a namespace for these examples and set as default
kubectl apply -f Namespace.yaml
kubens 04--rbac

2. Job without Permissions

A job that attempts to list pods without any service account configured will fail because the default service account has no API permissions.

# Job.no-permissions.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: no-permissions
spec:
  template:
    spec:
      containers:
        - name: kubectl
          image: cgr.dev/chainguard/kubectl
          args: ["get", "pods", "-A"]
      restartPolicy: Never
  backoffLimit: 1
# task 02-apply-job-no-permissions
# - Apply the Job without any ServiceAccount or permissions
kubectl apply -f Job.no-permissions.yaml

3. Grant Namespace-Scoped Permissions

Next we will create a service account, role, and role binding that grants the job permission to read pods only within the namespace.

# ServiceAccount.namespaced-pod-permissions.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: namespaced-pod-reader
# Role.pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
# RoleBinding.pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
  - kind: ServiceAccount
    name: namespaced-pod-reader

We create two jobs using this service account. One lists pods in the namespace (success) and one attempts to list pods cluster-wide (failure).

# Job.namespaced-pod-reader-succeed.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: namespaced-pod-permissions-succeed
spec:
  template:
    spec:
      automountServiceAccountToken: true
      containers:
        - name: kubectl
          image: cgr.dev/chainguard/kubectl
          args: ["get", "pods", "-n", "04--rbac"]
      serviceAccountName: namespaced-pod-reader
      restartPolicy: Never
  backoffLimit: 1
# Job.namespaced-pod-reader-fail.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: namespaced-pod-permissions-fail
spec:
  template:
    spec:
      automountServiceAccountToken: true
      containers:
        - name: kubectl
          image: cgr.dev/chainguard/kubectl
          args: ["get", "pods", "-A"]
      serviceAccountName: namespaced-pod-reader
      restartPolicy: Never
  backoffLimit: 1
# task 03-apply-namespace-scoped-permissions
# - Apply the configuration for a ServiceAccount, Role, and RoleBinding
kubectl apply -f ServiceAccount.namespaced-pod-permissions.yaml
kubectl apply -f Role.pod-reader.yaml
kubectl apply -f RoleBinding.pod-reader.yaml
kubectl apply -f Job.namespaced-pod-reader-succeed.yaml
kubectl apply -f Job.namespaced-pod-reader-fail.yaml

4. Grant Cluster-Scoped Permissions

To read pods across all namespaces we need a ClusterRole and ClusterRoleBinding.

# ServiceAccount.cluster-pod-permissions.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cluster-pod-reader
# ClusterRole.pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
# ClusterRoleBinding.pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: pod-reader
subjects:
  - kind: ServiceAccount
    name: cluster-pod-reader
    namespace: 04--rbac
# Job.cluster-pod-reader.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: cluster-pod-permissions
spec:
  template:
    spec:
      automountServiceAccountToken: true
      containers:
        - name: kubectl
          image: cgr.dev/chainguard/kubectl
          args: ["get", "pods", "-A"]
      serviceAccountName: cluster-pod-reader
      restartPolicy: Never
  backoffLimit: 1
# task 04-apply-cluster-scoped-permissions
# - Apply the configuration for a ServiceAccount, ClusterRole, and ClusterRoleBinding
kubectl apply -f ServiceAccount.cluster-pod-permissions.yaml
kubectl apply -f ClusterRole.pod-reader.yaml
kubectl apply -f ClusterRoleBinding.pod-reader.yaml
kubectl apply -f Job.cluster-pod-reader.yaml

5. Delete the Namespace to Clean Up

Finally, remove the namespace to delete all resources created during this lesson.

# task 05-delete-namespace
# - Delete the namespace to clean up
kubectl delete -f Namespace.yaml