What is Kubernetes RBAC, and why do we need it?
RBAC is an authorization model that enables fine-grained control over who can access what resources in a Kubernetes cluster. With RBAC, you can define roles that specify a set of permissions and assign those roles to users or service accounts. This allows you to tightly control which users or services have access to which parts of the cluster. Additionally, RBAC can be used to enforce security best practices, such as least privilege and separation of duties. For example, you could create a role that allows a user to read from the Kubernetes API but not write to it. Using RBAC, you can help ensure that your cluster is secure and that only authorized users have access to the resources they need.
So why do we need RBAC in Kubernetes?
As the number of applications and actors in your cluster increase, you might want to review and restrict their actions. There are a few reasons why you need RBAC,
To provide more fine-grained control over who has access to what resources in a Kubernetes cluster. For example, you might want to restrict access to your production systems to only a few people.
To allow for the enforcement of security best practices, such as least privilege and separation of duties. You might want to give a limited set of permissions to someone responsible for running your cluster.
To make it easier to manage access control in a Kubernetes cluster, RBAC can be used to centrally manage permissions for multiple users and service accounts.
The RBAC framework in Kubernetes allows you to control which users have access to which resources in your cluster.
Authentication and Authorization are different
Before we continue, let's ensure we understand the difference between authentication and authorization.
Authentication is verifying that a user is who they claim to be. This is typically done by checking their username and password against a database of users.
Authorization is determining whether a user has permission to act. This is typically done by checking whether the user has the proper Role or group membership.
In Kubernetes, there is the various way you can authenticate; some of them are,
Static Password File: You can create a static password file that contains the username and password for each user that should have access to the cluster. When a user attempts to authenticate, their username and password are checked against the contents of this file. If the username and password match an entry in the file, the user is considered authenticated.
Static Token File: You can create a static token file that contains a list of tokens, each of which can be used to authenticate a user. When a user attempts to authenticate, their token is checked against the contents of this file. If the token matches an entry in the file, the user is considered authenticated.
X509 Client Certificates: You can use X509 client certificates to authenticate users. When a user attempts to authenticate, their certificate is checked against a list of trusted certificates. If the certificate is on the list, the user is considered authenticated.
OpenID Connect Tokens: You can use OpenID Connect tokens to authenticate users. When a user attempts to authenticate, their token is checked against the OpenID Connect provider. If the token is valid, the user is considered authenticated.
Kubernetes also supports various forms of authorization:
Attribute-based access control: Attribute-based access control (ABAC) is a policy-based approach to authorization. ABAC defines how users can access resources based on their attributes, such as their Role or group membership.
Role-based access control: Role-based access control (RBAC) is a policy-based approach to authorization. RBAC defines how users can access resources based on their roles.
Node authorization: Node authorization is a policy-based approach to authorization. Node authorization defines the rules for how users can access resources based on their nodes.
In this tutorial, we will focus on role-based access control.
How does Kubernetes RBAC work?
Before we talk about more details in RBAC, let's see where the authorization model fits into the picture. Let's say you want to create this Pod pod.yaml
into a Kubernetes cluster:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: goglides
name: goglides
spec:
containers:
- image: goglides:v1.2.3
name: goglides
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
You can create this pod in the goglides namespace as follows,
kubectl create -f pod.yaml -n goglides
When you type kubectl create
a few things happen.
kubectl binary reads the pod.yaml
file and parses it in order to create the object on the server
Kubectl binary reads the configs from your KUBECONFIG
file which includes mostly cluster details, user details, and authentication mechanism. And send an authentication request to the cluster. If the validation fails, reject the request by returning 401 Unauthorized
. Otherwise, continue with the request.
Kubectl binary forwards the request to the Kubernetes API server. API server validates the object by checking if it is valid, well-formed, and does not violate any constraint. The API server checks if the user making the request has the required permissions to create the object. If not, reject the request by returning 403 Forbidden
. Otherwise, continue with the request.
API server persists the object in etcd by creating or updating the specified resource. API server returns a response to kubectl binary. Kubectl binary prints the object that was created or updated to stdout.
In the above example, kubectl binary makes a request to the Kubernetes API server. The request includes the following:
The type of object to be created (a
Pod
in this case)The name of the object to be created (
goglides
)The namespace in which to create the object (
goglides
)The API server looks up the object to be created (
Pod
), and checks if the user making the request has thecreate
verb on that object in thegoglides
namespace.The API server looks up the user making the request (in this case, it's the user mentioned in your kubeconfig file) to see if the user has the
create
verb onPod
objects in thegoglides
namespace.If the user has the
create
verb onPod
objects in thegoglides
namespace, the API server allows the request, and thePod
is created.
Explain Kubernetes Role And Role Binding
In Kubernetes, a role is a set of permissions that defines what can be done to Kubernetes resources. A role can contain one or more rules. Rules allow for specific permissions to be granted. Permissions are additive, which means that if multiple rules are granted for specific permission, the user has all the permissions granted by those rules. There are no deny rules in Kubernetes, so if a user has any permissions at all for a resource, they have complete access to that resource. Roles are namespace, which means that they only work within the constraints of a namespace. If no namespace is specified, the Role defaults to the default namespace.
A role binding is what ties a role to a user or group of users. By creating a role binding, you are assigning the Role to one or more users. This gives those users the permissions defined in the Role. Role bindings can be used to enforce security best practices, such as least privilege and separation of duties. For example, you could create a role binding that gives a user read-only access to the Kubernetes API. This would prevent the user from making any changes to the cluster, which could help to prevent accidental or malicious damage to the cluster.
Kubernetes RBAC is a powerful tool that can be used to secure your cluster and control access to its resources. By carefully defining roles and role bindings, you can ensure that only authorized users have access to the resources they need. This can help to prevent accidental or malicious damage to the cluster and can also help to enforce security best practices.
Now we understand the basics of RBAC, let's continue with some other concepts which are required to implement RBAC in your cluster.
Explain ClusterRole and ClusterRoleBinding
A ClusterRole is a set of permissions that can be assigned to a user or group of users. ClusterRole works like Role, but they are applied to the cluster as a whole. A ClusterRole can contain one or more rules. ClusterRoles don't have to be used in a specific namespace. You can use them to give access to multiple namespaces or all of them.
Rules allow for specific permissions to be granted. Permissions are additive, which means that if multiple rules are granted for specific permission, the user has all the permissions granted by those rules. There are no deny rules in Kubernetes, so if a user has any permissions at all for a resource, they have complete access to that resource.
A ClusterRoleBinding is what ties a ClusterRole to a user or group of users. By creating a ClusterRoleBinding, you are assigning the ClusterRole to one or more users. This gives those users the permissions defined in the ClusterRole. Role bindings can be used to enforce security best practices, such as least privilege and separation of duties. For example, you could create a ClusterRoleBinding that gives a user read-only access to the Kubernetes API. This would prevent the user from making any changes to the cluster, which could help to prevent accidental or malicious damage to the cluster.
In a nutshell, a ClusterRole defines the permissions that will be granted to a set of users, while a ClusterRoleBinding determines which users will be granted those permissions. For example, you could create a ClusterRole that gives users the ability to read and write secrets and then create a ClusterRoleBinding that gives that Role to the development team. This would give developers the ability to read and write secrets but not manage them. In order to use a ClusterRole, you must first create it and then bind it to one or more users.
Default ClusterRole:
cluster-admin: Full access to all resources in the cluster, including the ability to create and delete namespaces. This Role should be used sparingly, as it gives users broad permissions that could be abused.
admin: Full access to all resources in a namespace, including the ability to create and delete namespaces. This Role should be used sparingly, as it gives users broad permissions that could be abused.
edit: Read/write access to most resources in a namespace, including the ability to create and delete some resources. This Role is often used by developers who need to be able to modify the resources in their namespace.
view: Read-only access to most resources in a namespace. This Role is often used by operators who need to be able to monitor the resources in a namespace but don't need to modify them.
What does it mean that ClusterRole gives access across more than one namespace or all namespaces?
ClusterRole gives access across more than one namespace or all namespaces. This means that a user with a ClusterRole can access resources in any namespace that the ClusterRole has been given access to. For example, if you have a ClusterRole that gives users read-only access to secrets, then those users will be able to read secrets in any namespace that the ClusterRole has been given access to.
What are some of the benefits of using ClusterRole over Role?
There are several benefits of using ClusterRole over Role:
ClusterRole can be used to give access to multiple namespaces or all namespaces, while Role is namespace-specific.
ClusterRole can be used to control access to different kinds of resources than Role.
ClusterRole is typically used with service accounts, which are needed for many automated tasks such as CI/CD pipelines.
What are some of the benefits of using a ClusterRoleBinding over a RoleBinding?
There are several benefits of using a ClusterRoleBinding over a RoleBinding:
ClusterRoleBinding can be used to give access to multiple namespaces or all namespaces, while RoleBinding is namespace-specific.
ClusterRoleBinding can be used to control access to different kinds of resources than RoleBinding.
ClusterRoleBinding is typically used with service accounts, which are needed for many automated tasks such as CI/CD pipelines.
When would you use a ClusterRole vs. a Role?
A ClusterRole should be used when you need to give users access to resources across multiple namespaces or all namespaces. A Role should be used when you need to give users access to resources in a specific namespace.
When would you use a ClusterRoleBinding vs. a RoleBinding?
A ClusterRoleBinding should be used when you need to give users access to resources across multiple namespaces or all namespaces. A RoleBinding should be used when you need to give users access to resources in a specific namespace.
RBAC definition includes various elements
We have enough background to start using RBAC. As an example, let's look at the following YAML definition needed to give someone read access to Pods.
apiVersion: v1
kind: ServiceAccount
metadata:
name: goglides-serviceaccount
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-goglides-pods
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-goglides-pods
namespace: default
subjects:
- kind: ServiceAccount
name: goglides-serviceaccount
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: read-goglides-pods
apiGroup: rbac.authorization.k8s.io
The file is divided into three parts:
A Service Account: This defines a service account named goglides-serviceaccount
in the default
namespace. Service accounts are used to give processes running inside of containers permissions to access the Kubernetes API.
A Role: This defines a role named read-goglides-pods
in the default namespace. The role gives users to read, watch, and list access to Pods in the same namespace.
A RoleBinding: This defines a role binding named read-goglides-pods
in the default namespace. The role binding gives the goglides-serviceaccount
service account the read-goglides-pods
role. With this definition in place, any process running inside of a container with the goglides-serviceaccount
service account will have read access to Pods in the default
namespace. This is a very basic example, but it illustrates the core concepts of RBAC. You can use RBAC to give users granular permissions to specific resources in specific namespaces.
If you carefully evaluate all RBAC is compose of following,
-
Subjects: In Kubernetes, subjects are entities that are granted access to certain resources. Subjects can be users, groups, or service accounts. When configuring access control in Kubernetes, it is important to understand the distinction between subjects and objects. Objects are the resources that subjects are granted access to. For example, a user may be granted access to a particular pod. In this case, the user is the subject, and the pod is the object. Similarly, a group may be granted access to a namespace. In this case, the group is the subject, and the namespace is the object. Service accounts are also considered subjects in Kubernetes. A service account can be granted access to a secret. In this case, the service account is the subject, and the secret is the object. In about example
ServiceAccount
is the subject.
apiVersion: v1
kind: ServiceAccount
metadata:
name: goglides-serviceaccount
namespace: default
-
Resources: Resources are the objects that subjects are given access to. This can include pods, services, secrets, config maps, and more. All of these resources play an important role in keeping your cluster running smoothly. Pod resources, for example, allow you to manage and deploy your applications. Service resources provide you with a way to connect and expose your applications to the outside world. Secrets and config maps give you a way to store and manage sensitive data. In the above example
pods
is the resource. You can define multiple resources in the sameRole
definition.
resources: ["pods"]
-
API Groups: These are the different APIs that Kubernetes offers. For example, the core API group includes all of the resources that are part of the Kubernetes core, such as pods and services. The extensions API group includes resources that are part of Kubernetes extensions, such as deployments and ingresses. In the above example,
apiGroups: [""]
indicates the core API group.
apiGroups: [""]
- Verbs: In order to manage resources in a Kubernetes cluster, you use verbs. These are the actions that subjects can perform on resources. The most common verbs are created, get, update, patch, delete, and list. You use these verbs to manipulate objects in your clusters, such as pods and services. Each verb has a different purpose, and you must be careful when using them so that you do not accidentally delete or modify something that you did not mean to. With great power comes great responsibility, after all. When used correctly, however, these verbs can help you manage your Kubernetes resources in an efficient and safe manner. In the above example, we are providing read access as follows,
verbs: ["get", "watch", "list"]
Apart from these, we need an object which basically associates the subject with the role and that object is RoleBinding
in this case, which basically says associate ServiceAccount goglides-serviceaccount
with the Role read-goglides-pods
.
subjects:
- kind: ServiceAccount
name: goglides-serviceaccount
roleRef:
kind: Role
name: read-goglides-pods
Top comments (0)