Kubernetes RBAC: Basics and Advanced Patterns
Lukas Gentele
Posted on June 8, 2022
By Harshit Mehndiratta
Kubernetes has modernized how organizations build, test, and deploy their software. Thanks to its modularity, open-source framework, and role-based access control (RBAC), companies can create a highly scalable and reliable enterprise-grade cluster while meeting strict security and governance requirements.
The RBAC framework implements access controls for different members to ensure every user holds the right amount of access to valuable resources based on their responsibilities in an organization.
While RBAC comes built into Kubernetes, its implementation can be tricky and confusing. In this article, we will cover the basics of RBAC, how it works, and how it can be implemented within a Kubernetes cluster.
What Is Kubernetes RBAC?
RBAC is an authorization mechanism that enables fine-grained access for users and applications interacting with Kubernetes objects in a cluster. There are several ways to manage Kubernetes authorization requests, such as attribute-based access control (ABAC) or webhooks, but RBAC is mainly used for production-grade deployments.
With RBAC, cluster admins can specify application access, add/remove permissions, and limit resource visibility depending upon their role in a hierarchy. Kubernetes RBAC is enabled by default (in Kubernetes version 1.6 and above). Permissions are granted to a user through manual declaration definitions, which are stored and managed as roles in the cluster.
A role can represent a set of permissions on certain API objects, like pods, nodes, deployments, and ConfigMaps, and identify actions on them by users and processes through API groups. RBAC authorization uses the rbac.authorization.k8s.io API group, which determines API authorizations to simplify authentication and allows dynamic configuration of policies on the fly.
How Does RBAC Work?
There are three major elements involved in RBAC:
1. Subjects
Clients, processes, and users call the Kubernetes API to perform operations on cluster objects. They are divided into three categories: users, groups, and service accounts.
- Users and Groups: these subjects are not stored in the Kubernetes database and are meant for processes outside the cluster.
- ServiceAccounts: these subjects exist as API objects in the Kubernetes cluster and are used for intracluster processes.
2. Verbs
The operations executed on available Deployments, Services, and Pods in a Kubernetes cluster are called verbs. Examples are Create, Read, Update, or Delete (CRUD) operations. The verbs are sent to the API via HTTP, which Kubernetes translates based on the REST API URL.
3. Resources
These are the available API objects in a Kubernetes cluster, such as Deployments, Services, Pods, and PersistentVolumes. Rules on these API objects are expressed as ClusterRoles/Roles that can be defined as Kubernetes subjects (users, groups, or service accounts) through RoleBinding and ClusterRoleBinding.
A role is a set of permissions that can be used across different subjects. Roles are usually bound to one namespace but can be used to represent more than one through wildcards.
Default Roles in Kubernetes
While Kubernetes allows you to configure custom roles, these roles are available by default:
* cluster-admin: this role allows super-user access to perform actions on any cluster resource. It gives full control in all the namespaces.
- admin: this role allows admin access, which permits unlimited read/write permissions within a namespace.
- edit: this role allows read/write access to some objects in a namespace.
- view: this role allows read-only access to view objects in a namespace.
These are the different sets of permissions:
- ClusterRole: this is a role object applied cluster-wide. Granting a user a ClusterRole provides view and edit access across all the namespaces, resource quotas, and nodes of the cluster.
- RoleBinding: a RoleBinding binds API objects and operations that can be executed on them by subjects. It also handles operations for a particular namespace.
- ClusterRoleBinding: a ClusterRoleBinding manages operations executions by subjects across the entire cluster.
Implementing RBAC in a Kubernetes Cluster
Following are step-by-step instructions for implementing basic Kubernetes RBAC. You will be able to implement users, service accounts, roles, and role bindings in your Kubernetes cluster.
These steps have been tested in minikube, but they can be applied to any Kubernetes cluster.
Here is what you need to begin:
- Kubernetes cluster running
- Kubernetes CLI kubectl installed
- Basic understanding of Kubernetes pods, namespaces, and service accounts
- A client certificate (CRT) and private key generated using OpenSSL
Creating a User
Kubernetes can authenticate and authorize users with CRT, but it does not provide an API for creating users. To configure access for the Kubernetes cluster, a client certificate file (.crt) and private key (.key) file must be generated using OpenSSL.
Once you have the .key and the .crt files, we can set a user entry in kubeconfig using this command:
kubectl config set-credentials user1 --client-certificate=user1.crt --client-key=user1.key
In the above command, we are setting the user named user1.
Response:
You should see that the user is set for access in the Kubernetes cluster:
User "user1" set.
Set a context element for the created user to check its access privileges for a Kubernetes cluster. To set a context entry in kubeconfig, use this command:
kubectl config set-context user1-context --cluster=minikube --user=user1
Response:
Context "user1-context" created.
Switch to user1-context using this command:
kubectl config use-context user1-context
Now you can check permissions for user1 and create roles to provide resource access.
Creating a Service Account
Service accounts in Kubernetes are used for identity authentication and authorization by pods. Pods are assigned automatically to the “default” service account in your Kubernetes cluster, and applications share this account.
Use the following command to create a service account:
kubectl create serviceaccount podreader
Response:
serviceaccount/pod-reader created
You can also list other ServiceAccount resources in the namespace with the command:
kubectl get serviceaccounts
Response:
NAME SECRETS AGE
admin 1 5h25m
default 1 6h13m
pod-reader 1 5m35s
Creating a Role
A role object configuration file in Kubernetes defines what you can do to users, groups, or service accounts. The configuration is expressed as a YAML file and has a particular schema:
kind:
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace:
name:
rules:
apiGroups: [""]
resources: []
verbs: []
kind
: this specifies the kind of role. It can be of two types—role or cluster role. A role will typically provide access to resources bound to one namespace, while the cluster role provides access to resources across the cluster.
namespace
: this specifies the namespace to which a role is bound. With ClusterRoles, the namespace
variable is omitted since ClusterRoles are not namespaced.
name
: this is the name of the role.
apiGroups
: this indicates the core API groups used.
resources
: these are the resources that a user wants to access. Examples include pods, deployments, services, namespaces, or ConfigMaps.
verbs
: these are actions that a subject can execute on resources, including list, delete, create, watch, update, or edit.
To create a role, specify the configuration in the YAML file. Here is a sample role configuration for allowing the particular user to list pods.
#role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: get-pods
rules:
apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
To match the user to the above role, use get-pods
.
Next, create a RoleBinding.
Creating a RoleBinding
A RoleBinding object configuration file would look similar to this:
#rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "user1" to read pods in the "default" namespace.
kind: RoleBinding
metadata:
name: user-get-pods
namespace: default
subjects:
kind: User # Here ServiceAccounts can also be specified instead of user
name: user1 # "name" is case sensitive. Specify the name of the user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: get-pods # this must match the name of the Role you wish to bind to
apiGroup: rbac.authorization.k8s.io
Apply the RBAC Settings
Create the RBAC role by using the following command:
kubectl create -f <PATH to Role.yaml file>
Create the RBAC role binding by using the following command:
kubectl create -f <PATH to role-binding yaml file>
Note that if role and RoleBindings are implemented correctly, subjects will be able to perform specified operations on cluster objects.
Conclusion
Kubernetes RBAC offers a simplified way to manage access to resources, but it does require manual configuration to apply roles across the cluster. This can be mitigated by adopting third-party tools, such as Loft, which provides an automated way to manage Kubernetes RBAC.
Loft offers an easy-to-use interface that makes it easy to deploy, update, and audit RBAC configurations. It runs as a lightweight controller in your Kubernetes cluster to manage namespaces, user limits, and more. To learn more, have a look at the docs or schedule a personalized demo.
Posted on June 8, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.