In our previous blog, we covered Authentication and Authorization in Kubernetes. Authentication refers to "who you are," and we also issued a certificate for a new user (harshit
). Authorization refers to "what you can do in a Kubernetes cluster," and we discussed four methods of authorization: ABAC, RBAC, Node, and Webhook. In this blog, we will explore how we can authorize our new user (harshit
) to interact with cluster resources using RBAC, with hands-on examples. Let's get started.
What is RBAC?
Role-Based Access Control (RBAC) in Kubernetes is a method for regulating access to the Kubernetes API. It allows you to specify who can access what resources within a Kubernetes cluster, and what actions they can perform on those resources.
Key Concepts in Kubernetes RBAC:
Role: Defines a set of permissions within a namespace. It contains rules that represent allowed operations on Kubernetes resources.
RoleBinding: Grants the permissions defined in a Role to a user, group, or service account within a specific namespace.
ClusterRole: Similar to a Role, but it is cluster wide. It can be used to define permissions across all namespaces or for cluster-scoped resources.
ClusterRoleBinding: Similar to RoleBinding, but it grants the permissions of a ClusterRole to a user, group, or service account across the entire cluster.
How RBAC Works in Kubernetes:
Roles and RoleBindings are typically used to control access within a single namespace like pods, deployments,etc.
ClusterRoles and ClusterRoleBindings are used for granting access to resources across the entire cluster or for non-namespaced resources like nodes.
Before starting with examples, please set an alias for kubectl
:
alias 'k=kubectl'
Example: Role & RoleBinding
First, check who the current user is and whether they have access to Pods:
kubectl auth whoami kubectl auth can-i get pod
You'll see that the current user is
kubernetes-admin
, who can access Pods. However, the userharshit
doesn't have access. To grantharshit
access, we'll create a Role and assign it to the user.Creating a Role (pod-reader) and Granting Permissions to Get, List, and Watch Pods
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
- This specifies that the object is using the RBAC (Role-Based Access Control) API version
v1
.
- This specifies that the object is using the RBAC (Role-Based Access Control) API version
kind: Role
Indicates the type of Kubernetes object being created, which is a Role.
A Role in Kubernetes defines permissions (rules) for resources within a specific namespace.
metadata
namespace: default
Specifies the namespace where the Role applies.
This Role is limited to the
default
namespace.
name: pod-reader
- The name of the Role. Here, the Role is called
pod-reader
.
- The name of the Role. Here, the Role is called
rules
Defines the permissions granted by the Role.
The rules are a list of API groups, resources, and allowed verbs.
apiGroups: [""]
The
apiGroups
field specifies which API group the rules apply to.[""]
(an empty string) refers to the core API group, which includes core Kubernetes resources such as Pods, Nodes, Services, etc.For apiVersion, like
apps/v1
and other we mention Named API Group as per the apiVersion group.
resources: ["pods"]
- This Role applies to the Pods resource within the namespace.
verbs: ["get", "watch", "list"]
These are the actions permitted for the specified resource (
pods
):get
: Allows reading the details of a pod.watch
: Allows watching for changes to pods.list
: Allows listing all pods in the namespace.
Apply this file to create the Role.
Imperative Way of creating Role
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
Creating a RoleBinding (read-pods) and Mapping the User
harshit
to the Rolepod-reader
apiVersion: rbac.authorization.k8s.io/v1 # This role binding allows "harshit" to read pods in the "default" namespace. # You need to already have a Role named "pod-reader" in that namespace. kind: RoleBinding metadata: name: read-pods namespace: default subjects: # You can specify more than one "subject" - kind: User name: harshit # "name" is case sensitive apiGroup: rbac.authorization.k8s.io roleRef: # "roleRef" specifies the binding to a Role / ClusterRole kind: Role #this must be Role or ClusterRole name: pod-reader # this must match the name of the Role you wish to bind to apiGroup: rbac.authorization.k8s.io
Apply this file to bind the
harshit
user to thepod-reader
Role.Imperative way of creating Role-binding
kubectl create rolebinding read-pods --role=pod-reader --user=harshit
Accessing the Pod as
harshit
Log in as
harshit
in the cluster. Add the harshit’s certificate and private key to the config file using:kubectl config set-credentials harshit --client-key=harshit.key --client-certificate=harshit.crt --embed-certs=true
Now, set the context:
kubectl config set-context harshit --cluster=kind-cka-cluster --user=harshit
Switch to the
harshit
context:kubectl config use-context harshit
Verify the context with:
The
harshit
user now has permissions to get, list, and watch Pods, but cannot create them.You can see that user
harshit
has no permission forresource deployment
and creating pods.For viewing the config file u can use
kubectl config view
we can see that our user
harshit
is added in config file.
For more details, read this Kubernetes Doc from the heading How to issue a certificate for a user.
Important Commands
To see the all roles:
kubectl get role -A
To count all the roles in all namespaces:
kubectl get role -A --no-headers | wc -l
To check the validity of certificates:
openssl x509 -noout -dates -in <file.crt>
To search any command from reverse in history press
Ctrl+R
and then type few letters of it
Example: ClusterRole & ClusterRoleBinding
Before starting this example, switch back to the kubernetes-admin
user.
Also, Check by kubectl auth whoami
ClusterRoles are powerful roles that can access resources across cluster level or all namespaces, including managing nodes, persistent volumes (PVs), certificate signing requests (CSRs), and even namespaces.
Command to See Cluster-Scoped Resources
kubectl api-resources --namespace=false
Command to See Namespace-Scoped Resources
kubectl api-resources --namespace=true
That’s check whether user harshit
has permission to get nodes
kubectl auth can-i get nodes --as harshit
Creating a ClusterRole (
node-reader
)kubectl create clusterrole node-reader --verb=get,list,watch --resource=node
For more details of clusterrole, run
kubectl create clusterrole --help
Creating a ClusterRoleBinding (node-reader-binding) and Mapping the User
harshit
to the ClusterRolenode-reader
kubectl create clusterrolebinding reader-binding --clusterrole=node-reader --user=harshit
Now, the
harshit
user can get, watch, and list nodes but cannot delete them.
Or
Service account in Kubernetes
A Service Account in Kubernetes is an identity used by processes running in pods to authenticate and interact with the Kubernetes API. Unlike regular user accounts meant for humans, Service Accounts are intended for system components, like pods, to perform actions on the cluster. When a pod needs to interact with the Kubernetes API—like listing resources, creating or modifying resources—it does so under the identity of a Service Account.
By default, when a pod is created, Kubernetes automatically assigns it a default Service Account from the same namespace unless specified otherwise. This Service Account allows the pod to authenticate and gain access to the cluster's resources according to the permissions granted to it.
Authentication in Kubernetes Service Accounts
Authentication in Kubernetes involves validating the identity of the entity (human user, pod, etc.) making a request to the API server. For Service Accounts, Kubernetes uses tokens that are automatically generated when the account is created.
Note: Kubernetes also creates a default service account in each namespace, such as kube-system
, kube-node-lease
, etc.
Example: Creating a Service Account with RBAC
We'll create a service account named build-sa
, grant it permissions to read Pods, and create a RoleBinding to attach the service account to the Role.
Creating a Service Account (build-sa)
kubectl create sa build-sa
Let’s check if our service account has permissions or not
kubectl get pod --as build-sa kubectl auth can-i get pod --as build-sa
Creating a Role to Read Pods
kubectl create role build-role --verb=list,get,watch --resource=pod
Creating a RoleBinding
kubectl create rolebinding build-rb --role=build-role --user=build-sa
Now, our service account
build-sa
can watch, list, and get Pods with read-only access.kubectl get pod --as build-sa kubectl auth can-i get pods --as build-sa
To Delete the Service Account
kubectl delete sa build-sa
Manually Creating a Long-Lived API Token for a Service Account
Sometimes, you might need a long-lived API token for a Service Account, especially for non-interactive processes or external systems that need to access the Kubernetes API. To manually create a long-lived token, follow these steps:
Create the Service Account:
kubectl create serviceaccount <service-account-name>
Create a Secret to Hold the Token:
apiVersion: v1 kind: Secret metadata: name: <secret-name> annotations: kubernetes.io/service-account.name: "<service-account-name>" type: kubernetes.io/service-account-token
Associate the Secret with the Service Account: This step is usually handled automatically by Kubernetes, where it binds the token secret to the Service Account. You can verify this by describing the Service Account:
kubectl describe serviceaccount <service-account-name>
Retrieve the Token: Finally, you can retrieve the token from the secret:
kubectl get secret <secret-name> -o jsonpath='{.data.token}' | base64 --decode
This token can now be used to authenticate against the Kubernetes API.
Notes and key takeaways from the video
Roles & Role Bindings: Granting Permissions
Think of roles as job descriptions defining user or group actions. Role bindings link these roles to specific users or groups, granting them those permissions.
Roles: Define permissions within a namespace.
- Example: A "developer" role might allow getting, viewing, and deleting pods, as well as creating and viewing secrets.
Role Bindings: Connect roles to users or groups.
Cluster Roles: Expanding Permissions Beyond Namespaces
Cluster roles are like superpowered roles that can access resources across all namespaces. This includes powerful stuff like managing nodes, persistent volumes (PVs), certificate signing requests (CSRs), and even namespaces.
- Check Available Resources: Use
kubectl api-resources namespaced=false
to see cluster-scoped resources. Replacefalse
withtrue
to check the namespace-scoped resources.
Cluster Role Bindings: Linking Users to Cluster Roles
Like role bindings, cluster role bindings connect users or groups to cluster roles, granting cluster-wide permissions.
Commands to create cluster role and cluster role binding
https://kubernetes.io/docs/reference/access-authn-authz/rbac/
kubectl create clusterrole node-reader --verb=get,list,watch --resource=nodes
kubectl create clusterrolebinding node-reader-binding --clusterrole=node-reader --user=harshit
Key Points:
Roles are namespace-scoped, while cluster roles are cluster-wide.
Use role bindings and cluster role bindings to assign permissions to users or groups.
Carefully manage permissions to ensure security and prevent unauthorized access.
Finally, we’ve covered RBAC with examples. Thank you for reading my blog! For better understanding, I encourage you to try these hands-on exercises yourself.