Kubernetes is the rocket fuel for your containerized applications! But wait, it’s not all about deployment and scaling. The security of your Kubernetes cluster is a top priority, and that’s where Role-Based Access Control (RBAC) comes to the rescue. In this thrilling guide, we’ll navigate the cosmos of Kubernetes RBAC, breaking down the essentials with vivid examples to supercharge your cluster’s security.
The Kubernetes API
Before discussing RBAC, let’s see where the authorization model fits into the picture.
Let’s imagine you wish to submit the following Pod to a Kubernetes cluster:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: sise
image: ghcr.io/learnk8s/app:1.0.0
ports:
- containerPort: 8080
You could deploy the Pod to the cluster with:
kubectl apply -f pod.yaml
When you type kubectl apply
, a few things happen.
The kubectl binary:
Reads the configs from your KUBECONFIG.
Discovers APIs and objects from the API.
Validates the resource client-side (is there any obvious error?).
Sends a request with the payload to the kube-apiserver.
When the kube-apiserver receives the request, it doesn’t store it in etcd immediately.
First, it has to verify that the requester is legitimate.
In other words, it has to authenticate the request.
Once authenticated, does the requester have permission to create the resource?
Identity and permission are not the same things.
Just because you have access to the cluster doesn’t mean you can create or read all the resources.
The authorization is commonly done with Role-Based Access Control (RBAC).
With Role-Based Access Control (RBAC), you can assign granular permissions and restrict what a user or app can do.
In more practical terms, the API server executes the following operations sequentially:
A. On receiving the request, authenticate the user.
When the validation fails, reject the request by returning 401 Unauthorized.
Otherwise, move on to the next stage.
B. The user is authenticated, but do they have access to the resource?
If they don’t, reject the request by returning 403 Forbidden.
Otherwise, continue.
In this article, you will focus on the authorization part.
Decoupling users and permission with RBAC roles
RBAC is a model designed to grant access to resources based on the roles of individual users within an organization.
To understand how that works, let’s take a step back and imagine you had to design an authorization system from scratch.
How could you ensure that a user has write access to a particular resource?
A simple implementation could involve writing a list with three columns like this:
In this example:
Bob has read & write access to app1 but has no access to app2.
Mo & Alice have only read access to app2 and have no access to app1.
The table works well with a few users and resources but shows some limitations as soon as you start to scale it.
Let’s imagine that Mo & Alice are in the same team, and they are granted read access to app1.
You will have to add the following entries to your table:
That’s great, but it is not evident that Alice and Mo have the same access because they are part of the same team.
You could solve this by adding a “Team” column to your table, but a better alternative is to break down the relationships:
You could define a generic container for permissions: a role.
Instead of assigning permissions to users, you could include them in the roles that reflect their role in the organisation.
And finally, you could link roles to users.
Let’s see how this is different.
Instead of having a single table, now you have two:
In the first table, permissions are mapped to roles.
In the second table, roles are linked to identities.
What happens when you want Mo to be an admin for app1?
You can add the role to the user like this:
You can already imagine how decoupling users from permissions with Roles can facilitate security administration in large organizations with many users and permissions.
Understanding RBAC in Kubernetes: 🛡️
RBAC, or Role-Based Access Control, in Kubernetes (K8s), is a security mechanism that allows you to define and enforce fine-grained access control policies for various resources within your Kubernetes cluster. It is a fundamental component for managing and securing access to the Kubernetes API server and cluster resources.
In RBAC, you define roles and role bindings to specify what actions (verbs) are allowed on specific Kubernetes resources (e.g., pods, services, config maps) and namespace levels. Here are some key concepts in RBAC:
Roles: A Role is a set of rules that define what actions are allowed on a specific resource within a particular namespace. For example, you can create a Role that allows read and list operations on pods in a specific namespace.
Role Bindings: A Role Binding associates a Role with one or more users, groups, or service accounts. It specifies who is allowed to perform the actions defined in the associated Role. For instance, you can bind a Role to a specific user or a group of users.
ClusterRoles: While Roles are limited to a single namespace, ClusterRoles are not namespace-specific. ClusterRoles define what actions are allowed on cluster-level resources, like nodes or PersistentVolumes.
ClusterRoleBindings: ClusterRoleBindings associate ClusterRoles with users, groups, or service accounts, similar to Role Bindings. They determine who has access to cluster-level resources across all namespaces.
By using RBAC, you can create a granular access control system that aligns with your organization’s security requirements. This ensures that users, applications, and services have the right level of access to perform their tasks while maintaining the overall security of your Kubernetes cluster.
Role-Based Access Control is your shield against unauthorized access! This security mechanism allows you to create super-detailed access policies for Kubernetes resources. Imagine granting just the right permissions to your users, applications, and services while keeping your cluster locked down.
Roles and Role Bindings: 🛡️
Roles allow you to sculpt your access policies for specific resources in a namespace. Role Bindings establish the connections between your Roles and your users, groups, or service accounts. It’s like assembling your own superhero team.
Example: Let’s sculpt a Role named “pod-reader” and bind it to the user “john” within the “myapp” universe.
# 🚀 Example Role: pod-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: myapp
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
Explanation: 🕵️
The power-packed YAML file unveils a Role named “pod-reader.” It’s specialized for the “myapp” namespace and authorizes “get” and “list” operations on “pods.”
# 🚀 Example Role Binding: read-pods-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: myapp
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Explanation: 🔓
The YAML file creates a Role Binding named “read-pods-binding.” It unites the “pod-reader” Role with the mighty user “john” within the “myapp” domain. “John” now wields the power of “pod-reader.”
ClusterRoles and ClusterRoleBindings: 🌐
Step into the big leagues with ClusterRoles and ClusterRoleBindings! They extend RBAC to the entire cluster, letting you govern the cosmos of cluster-level resources.
# 🚀 Example ClusterRole: node-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
Explanation — Understanding ClusterRoles: 🌟
The provided YAML file defines a ClusterRole named “node-reader.” ClusterRoles are like superpowers for cluster-wide access control, granting permissions to perform actions on resources across the entire Kubernetes cluster. This “node-reader” ClusterRole allows “get” and “list” actions on the “nodes” resource.
# 🚀 Example ClusterRoleBinding: node-reader-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-reader-binding
subjects:
- kind: User
name: admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: node-reader
apiGroup: rbac.authorization.k8s.io
Explanation — ClusterRoleBindings: 💪
In this epic YAML file, the ClusterRoleBinding named “node-reader-binding” associates the “node-reader” ClusterRole with the valiant user “admin” at the cluster level. This binding grants the user “admin” the powers defined in the “node-reader” ClusterRole, enabling them to command nodes across the entire cosmos.
Checking Access: 🕵️
Configured RBAC but need to double-check access?
The kubectl auth can-i
command is your secret agent for mission verification. Let's make sure your heroes have the right powers!
Example:
Verify if “john” can list pods in the “myapp” universe with
kubectl auth can-i list pods --as=john -n myapp
Securing Your Kubernetes Cluster: 🛡️
RBAC is the ultimate shield for your Kubernetes environment. Crafting finely tuned access control policies ensures your cluster stays safe from unauthorized access and security threats. Regularly inspect and audit your RBAC configurations to keep your fortress secure.
Conclusion🌟
Kubernetes RBAC is your trusty sidekick for access control within your cluster. By understanding and wielding Roles, Role Bindings, ClusterRoles, and ClusterRoleBindings, you can strike the perfect balance between user access and security. Regularly test and verify access permissions to maintain the fortitude of your Kubernetes environment. 💥🚀