Overview #
RBAC regulates access to Kubernetes resources based on the roles of individual users within a Kubernetes cluster.
RBAC Objects #
Role:
Scope: Namespaced
-
The permissions apply within a specific namespace that the Role belongs to
-
Defines actions like (get, list, create, update, delete,…) on a defined set of Kubernetes resources like (Pods, Deployments,…)
ClusterRole:
Scope: Cluster-wide
-
Similar to a Role, but it applies cluster-wide rather than being limited to a specific namespace
-
Rules in a ClusterRole can apply to any resource in any namespace or to cluster-scoped resources like nodes
RoleBinding:
Scope: Namespaced
- Associates a Role with one or more users, groups, or service accounts within a specific namespace, this grants permissions within a single namespace to specific users or service accounts
ClusterRoleBinding:
Scope: Cluster-wide
- Equivalent to RoleBinding, but targets ClusterRole resources instead of Roles
Users & Service Accounts #
Users:
-
Represents a human who authenticates to the cluster using an external service
-
Can use private keys (default method), a list of usernames and passwords, or an OAuth service such as Google accounts
-
Users are not managed by Kubernetes.
Service Accounts:
-
Service Accounts are token values that can be used to grant access to namespaces in the cluster
-
Designed for use by applications and system components
-
Service Accounts are backed by Kubernetes objects and can be managed using the API
Verify RBAC is enabled #
If the rbac.authorization.k8s.io
API exists, RBAC is ready to use:
# Verify RBAC is enabled
kubectl api-versions | grep rbac
# Shell output:
rbac.authorization.k8s.io/v1
Service Accounts #
Create Service Account #
Create a Service Account to bind a role to it:
# Create a service account with the name "example-user"
kubectl create serviceaccount example-user
# Shell output:
serviceaccount/example-user created
Create Authorization Token #
The token value will be saved to the $TOKEN environment variable in the terminal:
# Create an authorization token for your Service Account
TOKEN=$(kubectl create token example-user)
# Verify the token:
echo $TOKEN
# Shell output:
eyJhbGciOiJSUzI1NiIsImtpZCI6Iml2eE9DSW9INjVvRzhlTi1kOWdsS1ZPelBzLUJUQkd3anJNMm1zbkcteVEifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzI0MTYyODA0LCJpYXQiOjE3MjQxNTkyMDQsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiNmIxMDM1ZTgtYWY5OS00NDAxLTliZWUtMWNlNzFjZmI3NGRmIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImV4YW1wbGUtdXNlciIsInVpZCI6ImZkZWZiZjI4LTQwMDItNGM1NS1iOTVlLWRkMDQ0MTA2ZjljMCJ9fSwibmJmIjoxNzI0MTU5MjA0LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpleGFtcGxlLXVzZXIifQ.IchdW2ibEQcS4wzMrem_WGx9c9W1mtAWe0QWTabdmkWchsw4yhVFSJ8LbVGRiJCy1aLKrDA1Sc_eKhenH9ug-mXgUuGFuTsaDPTAt_puobV5dFEBm1cExqcVLPSlTPpnrerapL50zux10gH1SoBWLgQpZt3d7RtLmF9_3jHaT5wir2ayEgAkcJ7DQzDFDcF1qOzGeMKEtkN1eWp7rU8OMlogc3RauO2sRriHrUKI1hVBz_x-zhyFHuaFALNU_rH0c4Yg6dkVW46S0Hn62c01HnX4uHOi1KzcncSDay8i84AiOvywRthPasehIQr_oqUSeUhOjRJ6mam1Lb-WAFIcKA
Configure Kubectl for Service Account #
# Add the Service Account as a credential in the Kubeconfig file
sudo kubectl config set-credentials example-user --token=$TOKEN
# Shell output:
User "example-user" set.
Verify Current Cluster & Context #
# Check the name of your current context
kubectl config current-context
# Shell output:
default
# List all contexts configured in the kubeconfig file
kubectl config get-contexts
# Shell output:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* default default default
Add New Context #
# Add the new context
sudo kubectl config set-context example-user-context --cluster=default --user=example-user
# Shell output:
Context "example-user-context" created.
Verify New Context #
# List all contexts configured in the kubeconfig file
kubectl config get-contexts
# Shell output:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* default default default
example-user-context default example-user
Switch to the new Context #
# Switch to new "example-user-context" conext
sudo kubectl config use-context example-user-context
Verify Permissions of new Context #
Run a Kubectl to command to verify the lack of permissions of the new context:
# List pods
kubectl get pods
# Shell output:
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:example-user" cannot list resource "pods" in API group "" in the namespace "default"
A “Forbidden” error is returned because the Service Account has no RBAC roles assigned, that include the “get pods” permission.
Example Role & RoleBinding #
Switch to the Default Context #
# Switch to default context
sudo kubectl config use-context default
# Shell output
Switched to context "default".
Create a Role #
vi example-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: example-role
namespace: default # Define namespace
rules:
- apiGroups:
- "" # Refers to the core API group (for resources like pods, services, etc.)
resources:
- pods
verbs:
- get
- list
- create
- update
# Add the role to the cluster
kubectl apply -f example-role.yaml
# Shell output:
role.rbac.authorization.k8s.io/example-role create
Create a RoleBinding #
Create a RoleBinding to assign the Role to the Service Account:
vi example-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: example-role-binding
namespace: default # Same namespace as the Role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: example-role # Name of the Role to bind
subjects:
- kind: ServiceAccount
name: example-user # Name of the service account
namespace: default # Namespace of the service account
# Bind the role to the service account
kubectl apply -f example-role-binding.yaml
# Shell output:
rolebinding.rbac.authorization.k8s.io/example-role-binding created
Verify Service Account Role / Permissions #
Switch to the new Context #
# Switch to new "example-user-context" conext
sudo kubectl config use-context example-user-context
Verify Permissions #
Create an example pod and list the pods in the “default” namespace:
# Create an example pod in the "default" namespace
kubectl run pod1 --image nginx:latest -l app=pod1
# List pods in "default" namespace
kubectl get pods
# Shell output:
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 5s
Try to delete the example pod:
# Try to delete the example pod
kubectl delete pod pod1
# Shell output:
Error from server (Forbidden): pods "pod1" is forbidden: User "system:serviceaccount:default:example-user" cannot delete resource "pods" in API group "" in the namespace "default"
It’s not possible to delete the pod, because the Role does not include the required “delete” action.