What is RBAC?
Kubernetes Role-Based Access Control or the (RBAC) system describes how we define different permission levels of unique, validated users or groups in a cluster. It uses granular permission sets defined within a .yaml file to allow access to specific resources and operations.
Starting with Kubernetes 1.6, RBAC is enabled by default and users start with no permissions, and as such, permissions must be explicitly granted by an admin to a specific service or resource. These policies are crucial for effectively securing your cluster. They permit us to specify what types of actions are allowed, depending on the user’s role and their function within the organization.
Prerequisites for using Role-Based Access Control
To take advantage of RBAC, you must allow a user the ability to create roles by running the following command:
root@test:~# kubectl create clusterrolebinding cluster-admin-binding
--clusterrole cluster-admin --user
Afterwards, to start a cluster with RBAC enabled, we would use the flag:
The RBAC Model
Basically, the RBAC model is based on three components; Roles, ClusterRoles and Subjects. All k8s clusters create a default set of ClusterRoles, representing common divisions that users can be placed within.
The “edit” role lets users perform basic actions like deploying pods.
The “view” lets users review specific resources that are non-sensitive.
The “admin” role lets a user manage a namespace.
The “cluster-admin” allows access to administer a cluster.
A Role consists of rules that define a set of permissions for a resource type. Because there is no default deny rules, a Role can only be used to add access to resources within a single virtual cluster. An example would look something like this:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"] verbs: ["get", "watch", "list"]
In this case, the role defines that a user (dev1) can use the “get”, “watch” or “list” commands for a set of pods in the “testdev” namespace.
A ClusterRole can be used to grant the same permissions as a Role but, because they are cluster-scoped, they can also be used to grant wider access to:
- cluster-scoped resources (like nodes)
- non-resource endpoints (like a folder named “/test”)
- namespaced resources (like pods) in and across all namespaces. We would need to run
kubectl get pods --all-namespaces
It contains rules that define a set of permissions across resources like nodes or pods.
An example would look something like this:
# "namespace" omitted since ClusterRoles are not namespaced
- apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"]
The default ClusterRole command looks like this:
root@test:~# kubectl create clusterrole [Options]
A command line example to create a ClusterRole named “pod“, that allows a user to perform “get“, “watch” and “list” on a pod would be:
root@test:~# kubectl create clusterrole pod --verb=get,list,watch --resource=pod
A RoleBinding is a set of configuration rules that designate a permission set. It binds a role to subjects (Subjects are simply users, a group of users or service accounts). Those permissions can be set for a single namespace (virtual cluster), with a RoleBinding or, cluster-wide with a ClusterRoleBinding.
Let’s allow the group “devops1” the ability to modify the resources in the “testdev” namespace:
root@test:~# kubectl create rolebinding devops1 --clusterrole=edit --group=devops1 --namespace=dev rolebinding "devops1" created
Because we used a RoleBinding, these functions only apply within the RoleBinding’s namespace. In this case, a user within the “devops1” group can view resources in the “testdev” namespace but not in a different namespace.
A ClusterRoleBinding defines which users have permissions to access which ClusterRoles. Because a “role” contains rules that represent a set of permissions, ClusterRoleBindings extend the defined permissions for:
- unique namespace in resources like nodes
- resources in all namespaces in a cluster
- undefined resource endpoints like ”/foldernames”
The default ClusterRoles (admin, edit, view) can be created using the command:
root@test:~# kubectl create clusterrolebinding [options]
An example of creating a ClusterRoleBinding for user1, user2,and group1 using the cluster-admin ClusterRole
root@test:~# kubectl create clusterrolebinding cluster-admin --clusterrole=cluster-admin --user=user1 --user=user2 --group=group1
What is a configMap?
A configMap is a resource that easily attaches configuration data to a pod. The information that is stored in a ConfigMap is used to separate config data from other content to keep images/pods portable.
How Do I Create A ConfigMap?
To create a configmap, we simply use the command:
kubectl create configmap <map-name> <data-source>
Let’s create a default.yaml file to create a ConfigMap:
kubectl create -f default.yaml /configmaps/location/basic.yaml
Basic RBAC Commands For Kubectl
kubectl get roles
kubectl get rolebindings
kubectl get clusterroles
kubectl get clusterrolebindings
kubectl get clusterrole system:node -o yaml
Namespaces are used to define, separate and identify a cluster of resources among a large number of users or spaces. You should only use namespaces when you have a very diverse set of clusters, locations or users. They are used in settings where companies have multiple users or teams that are spread across various projects, locations or departments. A Namespaces also provides a way to prevent naming
conflicts across a wide array of clusters.
Inside a Namespace, an object can be identified by a shorter name like ‘cluster1’ or it can be as complex as ‘US.MI.LAN.DC2.S1.R13.K5.ProdCluster1’ but, there can only be a single ‘cluster1’ or a ‘US.MI.LAN.DC2.S1.R13.K5.ProdCluster1’ inside of that namespace. So, the names of resources within a namespace must be unique but, not spanning namespaces. You could have several namespaces which are different, and they can all contain a single ‘cluster1’ object.
You can get a list of namespaces in a cluster by using this command:
root@test:~# kubectl get namespaces
NAME STATUS AGE
cluster2dev Active 1d
cluster2prod Active 4d
cluster3dev Active 2w
cluster3prod Active 4d
Kubernetes always starts with three basic namespaces:
- default: This is the default namespace for objects that have no specifically identified namespace (eg. the big barrel o’ fun).
- kube-system: This is the default namespace for objects generated by the Kubernetes system itself.
- kube-public: This namespace is created automatically and is world readable by everyone. This namespace is primarily reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement.
Finally, the essential concept of role-based access control (RBAC) is to ensure that users who require specific access to a resource can be assigned to those Roles, Clusterroles, and ClusterRolebindings as needed or desired. The granularity of these permission sets is structured and enabled to allow for increased security, ease of security policy modification, simplified security auditing, increased productivity (RBAC cuts down on onboarding time for new employees). Lastly, RBAC allows for increased cost reduction via removing unneeded applications and licensing costs for less used applications. All in all, RBAC is a needed addition to secure your Kubernetes infrastructure.