Note trans. : The article was written by Javier Salmeron, an engineer from Bitnami’s well-known Kubernetes community, and was posted on the CNCF blog in early August. The author talks about the very basics of the RBAC mechanism (role-based access control), which appeared in Kubernetes a year and a half ago. The material will be especially useful for those who are familiar with the device of the key components of the K8s (see links to other similar articles at the end).
Slide from a presentation made by a Google employee on the occasion of the release of Kubernetes 1.6Many experienced Kubernetes users may recall the release of Kubernetes 1.6 when authorization based on Role-Based Access Control (RBAC) received beta status. This is how an alternative authentication mechanism appeared, which complemented the existing, but difficult to manage and understand, Attribute-Based Access Control (ABAC). Everyone enthusiastically welcomed the new feature, but at the same time countless users were disappointed. StackOverflow and GitHub were full of messages about RBAC restrictions, because most of the documentation and examples did not take into account RBAC (but now everything is in order). The reference example was Helm: the simple launch of
helm init
+
helm install
no longer worked. Suddenly, we needed to add “weird” elements like
ServiceAccounts
or
RoleBindings
even before deploying a chart with WordPress or Redis (for more details, see the
instructions ).
')
Leaving these unsuccessful first attempts aside, one cannot deny the enormous contribution that RBAC has made to turning Kubernetes into a production-ready platform. Many of us managed to play with Kubernetes with full administrator privileges, and we are well aware that in a real environment it is necessary:
- Have a lot of users with different properties that provide the necessary authentication mechanism.
- Have complete control over what operations can be performed by each user or group of users.
- Have complete control over what operations each process in the hearth can perform.
- Restrict the visibility of certain resources in namespaces.
In this respect, RBAC is a key element providing much-needed opportunities. In the article we will quickly go through the basics
(for details, see this video ; follow the link for 1-hour webinar from Bitnami in English - approx. Transl. ) And dive a bit into the most confusing moments.
The key to understanding RBAC in Kubernetes
To fully understand the idea of RBAC, you need to understand that three elements are involved in it:
- Subjects (subjects) - a set of users and processes that want to have access to the Kubernetes API;
- Resources - a collection of Kubernetes API objects available in a cluster. Their examples (among others) are Pods , Deployments , Services , Nodes , PersistentVolumes ;
- Verbs (verbs) - a set of operations that can be performed on resources. There are various verbs (get, watch, create, delete, etc.), but all of them are ultimately CRUD (Create, Read, Update, Delete) operations.

If you keep these three elements in mind, the key idea of RBAC is:
“We want to connect actors, API resources, and operations.” In other words, we want to specify for a given
user what
operations can be performed on a variety of
resources .
Understanding RBAC objects in the API
In the combination of these three types of entities, RBAC objects that are available in the Kubernetes API become clear:
Roles
connect resources and verbs. They can be reused for different subjects. They are attached to the same namespace (we cannot use patterns that represent more than one [namespace], but we can deploy the same role object into different namespaces). If you want to apply a role to the entire cluster, there is a similar ClusterRoles
object.RoleBindings
connect the remaining entity-subjects. Having specified the role that already links API objects with verbs, we now select the subjects who can use them. The equivalent for the cluster level (i.e., without reference to namespaces) is ClusterRoleBindings
.
In the example below, we give the user
jsalmeron the right to read, retrieve a list, and create pods in the
test namespace. This means that
jsalmeron will be able to execute such commands:
kubectl get pods --namespace test kubectl describe pod --namespace test pod-name kubectl create --namespace test -f pod.yaml
... but not like this:
kubectl get pods --namespace kube-system

Examples of YAML files:
kind: Role apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: pod-read-create namespace: test rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "create"]
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: salme-pods namespace: test subjects: - kind: User name: jsalmeron apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-read-create apiGroup: rbac.authorization.k8s.io
Another interesting point in the following: now that the user can create scams, can we limit how much? This will require other objects that are not directly related to the RBAC specification and allow you to configure resource limits:
ResourceQuota
and
LimitRanges
. They are definitely worth exploring with the configuration of such an important component of the cluster [as the creation of pods].
Subjects: users and ... ServiceAccounts?
One of the difficulties that many Kubernetes users face in the context of subjects is the difference between regular users and
ServiceAccounts
. In theory, everything is simple:
Users
are global users, intended for people or processes outside the cluster;ServiceAccounts
- limited to the namespace and intended for processes within the cluster running on the pods.
The similarity of both types is the need to authenticate with the API to perform certain operations on a variety of resources, and their subject areas look very specific. They can also belong to groups, so
RoleBinding
allows
RoleBinding
to bind more than one subject (although only one group is allowed for
ServiceAccounts
system:serviceaccounts
). However, the main difference is the cause of the headache: users do not have corresponding objects in the Kubernetes API. It turns out that such an operation exists:
kubectl create serviceaccount test-service-account
... but this one is already gone:
kubectl create user jsalmeron
This situation has a serious consequence: if the cluster does not store information about users, the administrator will have to manage accounts outside the cluster. There are various ways to solve the problem: TLS-certificates, tokens, OAuth2, etc.
In addition, you will need to create
kubectl
contexts
kubectl
that we can access the cluster through these new accounts. To create files with them, you can use the
kubectl config
commands (which do not require access to the Kubernetes API, so they can be executed by any user). In the video above, there is an example of creating a user with TLS certificates.
RBAC in Deployments: an example
We have seen an example in which the specified user is granted rights to operations in the cluster. But what about
Deployments that require access to the Kubernetes API? Consider a specific scenario to get a better look.
Take for example the popular infrastructure application - RabbitMQ. We will use the
Helm-chart for RabbitMQ from Bitnami (from the official helm / charts repository), which uses the
bitnami / rabbitmq container . The container contains a plugin for Kubernetes, which is responsible for detecting other members of the RabbitMQ cluster. Because of this, the process inside the container requires access to the Kubernetes API, and we will need to configure
ServiceAccount
with the correct RBAC privileges.
When it comes to
ServiceAccounts
, follow this good practice:
- Customize
ServiceAccounts for each Deployment with a
minimum set of privileges .
In the case of applications that require access to the Kubernetes API, you may be tempted to create some kind of “privileged
ServiceAccount
” that can do almost everything in a cluster. Although this seems like a simpler solution, it can ultimately lead to security vulnerabilities allowing unwanted operations to be performed. (The video shows an example of Tiller [component Helm] and the consequences of having
ServiceAccounts
with high privileges.)
In addition, different
Deployments will have different needs in terms of accessing the API, so it is reasonable for each
Deployment to have different
ServiceAccounts
.
Without forgetting this, let's see which RBAC configuration will be correct for the case of
Deployment 's with RabbitMQ.
You can see in the
plug- in
documentation and
its source code that it requests the
Endpoints list from the Kubernetes API. This is how the remaining members of the RabbitMQ cluster are detected. Therefore, the RabbitMQ Chart from Bitnami creates:
- ServiceAccount for hearths with RabbitMQ:
{{- if .Values.rbacEnabled }} apiVersion: v1 kind: ServiceAccount metadata: name: {{ template "rabbitmq.fullname" . }} labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" {{- end }}
- Role (we assume that the entire RabbitMQ cluster is deployed in a single namespace) resolving the get verb for the Endpoint resource:
{{- if .Values.rbacEnabled }} kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" rules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get"] {{- end }}
- RoleBinding , connecting
ServiceAccount
with the role:
{{- if .Values.rbacEnabled }} kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ template "rabbitmq.fullname" . }}-endpoint-reader labels: app: {{ template "rabbitmq.name" . }} chart: {{ template "rabbitmq.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}" subjects: - kind: ServiceAccount name: {{ template "rabbitmq.fullname" . }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ template "rabbitmq.fullname" . }}-endpoint-reader {{- end }}

The diagram shows that we have allowed processes running in RabbitMQ to perform
get operations on
Endpoint objects. This is the minimum set of operations required for everything to work. At the same time, we know that the expanded chart is safe and will not perform unwanted actions within the Kubernetes cluster.
Final thoughts
To work with Kubernetes in production, RBAC policies are not optional. They should not be treated as a set of API objects that only administrators should know. They are actually needed by developers to deploy secure applications and take full advantage of the potential offered by the Kubernetes API for cloud (cloud native) applications. More information on RBAC is available at these links:
PS from translator
Read also in our blog: