Protecting your cluster with RBAC
One of the reasons people will use an application is knowing it’s safe. Once an application becomes compromised, its usage will drop drastically. This is more reason security is of utmost importance when building an application. We understand that Kubernetes host most application we use today, this is a reason we will be examining ways we can protect our cluster, and one of those ways is through RBAC.
Role-Based Access control
Role-Based Access Control (also known as RBAC) is a security mechanism used in controlling access into a Kubernetes cluster. RBAC allows administrators to define access policies that grant access or limit users or system access to our Kubernetes.
RBAC is implemented using a set of Kubernetes objects, including roles, role bindings, and service accounts.
A role is a set of rules that define what actions can be performed on a specific resource, a role binding is used to bind a role to a user or group of users, while a service account represents an identity that can be used by pods running in a Kubernetes cluster.
Working with RBAC
Role and Role Binding
We will be illustrating the usage of an RBAC in a cluster. We will first start with roles and role-binding.
Before we get our hands dirty, we have to understand that role-binding work within a namespace. What is a namespace? A namespace can be described as a way to organize clusters into virtual sub-clusters — they can be helpful when different teams or projects share a Kubernetes cluster.
Normally, when you deploy your cluster and pods and don’t define a namespace, Kubernetes creates a namespace by default for you, and any pod you deploy will be found in the default namespace, but this is not the best practice, as your resources are vulnerable to anyone that has access to your cluster. So, it’s advised your resources are placed within a namespace, so you can control access with the developers that have access to it.
To create a namespace, we use this command:
kubectl create namespace development
We called our namespace development
To view our namespace and others created alongside our cluster, we use this command:
kubectl get namespaces
To describe our newly created, we use this command:
kubectl describe namespace development
After creating our namespace, let’s assume we want to grant a user named Frank access to our resources as one of our engineers, we will then create a role that allows Frank to view and work with our pods (where our application), and also create a role binding that binds the role to Frank
For our Role, we use this Kubernetes object:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-reader
namespace: development
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
The kind
is called role, apiVersion
is from Kubernetesrbac authorization
, our created namespace
development as we created (it is important to indicate our namespace in our manifest file), then we describe the rules; that it can interact with our pods, and do the following activities like get, watch and list
.
We create the role on the terminal with this command:
kubectl apply -f </path-to-role-manifest-file.yaml>
Next, we create our role binding, which binds our user Frank to our pods/resources and gives him access:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: frank
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
You will note in our manifest file that our kind
is now RoleBinding
which means we are now binding our user to our pods in our development. What this means is that Frank has access to all pods in our created development
namespace. You will observe that frank’s name was indicated in our manifest file.
We create our role binding with the command below on our terminal:
kubectl apply -f </path-to-role-binding-manifest-file.yaml>
Doing this protects your application and gives you an idea of to has access to your pods, avoiding security breaches.
To check our created role, we use the command:
kubectl get roles <role-name> -n <namespace>
To check the status of the role binding, we use this command:
kubectl get rolebindings <role-binding-name> -n <namespace>
Cluster role and its binding.
While role binding protects against or limits usage to just a namespace, cluster binding has to do with all information to the cluster. This means if a cluster binding is in place, even with your configuration credentials you won’t still have access to the cluster. With the cluster role and its binding in place, you can have access to all namespaces in the cluster.
We will still be using Frank as our user in this scenario, to create the cluster role we will use the Kubernetes object below:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pod-manager
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "watch", "list", "update", "patch", "delete"]
Our kind
in this scenario is called ClusterRole
and the rule is to have access to all pods within the cluster. The actions it can carry out within the cluster are to create, get, watch, list, update, patch, and delete.
To create the cluster role, we use the command below on our terminal:
kubectl apply -f </path-to-cluster-role-manifest-file.yaml>
With this created, we can create the Cluster role binding:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: manage-pods
subjects:
- kind: User
name: frank
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-manager
apiGroup: rbac.authorization.k8s.io
With this in place, if we configure our cluster, only frank will have access to it even though others have the Kubernetes credentials.
To create our cluster role binding, we use this command:
kubectl apply -f </path-to-cluster-role-binding-manifest-file.yaml>
To check our created cluster role, we use this command:
kubectl get roles <cluster-role-name> -n <namespace>
To get the status of our cluster role binding, we use this command:
kubectl get clusterrolebindings <cluster-role-binding-name>
Summary
We have seen one of the ways we can limit access to both our cluster and our application. This is one measure that guarantees safety and reduces security breaches.