Kubernetes in Action RBAC

Kubernetes offers a plethora of plugins that are used throughout your orchestration needs however natively speaking on security we have to consider RBAC and roles that are needed or used to access the resources in our cluster.

For today’s demo I’m going to go through some CLI of creating a role, deciphering the YAML, and exploring the cluster. This is Kubernetes running on Azure Kubernetes Service (AKS), I typically prefer either GKE or AKS but if you want to use your own cluster by all means this is universal.

So we are all on the same page I deployed a cluster with a A2 image on Azure and operating exclusively through the cloud shell.

Let’s explore our cluster for roles by running the following code

kubectl get roles -A

So we can see that we have a few running out of the box in kube-system and kube-public respectively now let’s explore some RBAC roles in YAML (I’ll be referencing the official kubernetes documentation)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 namespace: default
 name: test-role
rules:
- apiGroups: [""] # "" indicates the core API Group
  resources: ["pods"]
  verbs: ["get", "watch", "list"] # this gives the action of what the role can do

After you define your yaml file in your terminal whether you run nano, vi, vim save this file under “role.yaml” or whatever you see fit we then will apply this role that will send to the Kubernetes API Server

So what just happened? From the abstract, we’ve defined a role that we want to create and send that request in yaml format to the Kube API Server if it didn’t accept this request we’d get a different message but it’s response shows that this role has been created noticed the role.rbac.authorization.k8s.io/test-role reference as when we wrote the apiVersion in YAML this is defined as “rbac” so it annotates the request kind role in front of the rbac after the request is sent.

So now we run a “kubectl get roles” this sends to the API Server the request and since this was created in the default namespace we will only see “test-role”

For most of the interaction of the CLI you’ll face with Kubernetes it’s best to use the “describe” command to gather more context as the example.

kubectl describe roles test-role | more
kubectl describe roles test-role | more

Looks similar to our YAML file we’ve defined earlier? This is essentially that displayed to you from the terminal so you can gain more context on the specific role.

So now that we’ve defined a role now we have to bind that role this is where some familiarity to those familiar to with IAM will see the nuances.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: test-role #you can name this as you wish
 namespace: default #this namespace is defined if we want to scope to specific
subjects:
- kind: User
  name: steven # field is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role #can be Role or ClusterRole
  name: test-role #make sure this matches the role we've defined earlier
  apiGroup: rbac.authorization.k8s.io

Similarly we will run the similar command on this yaml file to apply to the API Server

kubectl apply -f rolebinding.yaml

While it’s great to understand YAML for initially using this or exploring the section you’ll want a fast way to run this so lets explore the magic of kubectl

kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods

The same goal is achieved just without opening up a YAML file or navigating the editor you can declare this quickly.

kubectl create rolebinding pod-reader-bind --clusterrole=view --user=steven --namespace=default

So now that we have the roles lets break down what exactly we’re trying to achieve, we want least privilege yet we don’t want our users to not be able to use our application. So how are we going to distribute our application?

An idea is a separate namespace if it requires isolation but also by good practice you shouldn’t just rely on the “default” namespace.

Roles and ClusterRoles are two different concepts

Cluster Roles are a non-namespaced resource, think of Kubernetes differentiating the objects of roles and cluster roles in Kubernetes it has to be either a namespaced resource or non-namespaced resource. Think of it like this in our previous example we’ve created a “role” think of it in the terms of a “what” this can be defined however you deem such as developers, then add the permissions you’ll want that specific role tied to. Consider does this role need access to various apigroups? Or just limited to pods in the production namespace? As you scope these roles that you’re going to use always consider least privilege but also have this documented and mapped in a diagram for later reference as you’re roles will likely change.

If your running Kubernetes its likely you’ll want some permissions scoped cluster-wide or maybe certain roles will only need to access certain nodes (workers) for maintenance/troubleshooting. So let’s see what is the difference in YAML for Cluster Roles you’ll see familiarity of the rbac.authorization.k8s.io/v1

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole #<----notice the only change of the kind to let the API know
metadata:
  name: cluster-developer
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get","watch","list"]

Where to go from here?

It’s no secret security is paramount and as the use and adoption of microservices increase, the awareness of various concepts that are applicable natively are going to be needed and specifically around authorization. As access and control to your cluster you should always scope roles down to a small amount but also keep in mind that this is just scratching the surface on creating Kubernetes securely.

For instance just take a look at the default roles that are in your cluster by running the following

kubectl get clusterroles

As you can see we have quite a few already defined in our cluster as you can see you have the admin, aks-service and a numerous amount of others that are all a part of our cluster.

Let’s explore some of these by running the following

kubectl describe clusterroles omsagent-reader

This is a great example of the resources with as you can see the actions of what is just needed going across multiple resources with the list (essentially being a viewer role).

To discover what permissions you have as a user/admin you can run the kubectl auth CLI as shown above.

That’s a small snapshot of what is a part of RBAC feel free to discover this area further as this is covered in the CKA Objectives.

Reference: https://kubernetes.io/docs/reference/access-authn-authz/rbac/