Lab 1: RBAC - Users, Roles and RoleBindings
RBAC policies are vital for the correct management of your cluster, as they allow you to specify which types of actions are permitted depending on the user and their role in your organization. Examples include:
Secure your cluster by granting privileged operations (accessing secrets, for example) only to admin users. Force user authentication in your cluster. Limit resource creation (such as pods, persistent volumes, deployments) to specific namespaces. You can also use quotas to ensure that resource usage is limited and under control. Have a user only see resources in their authorized namespace. This allows you to isolate resources within your organization (for example, between departments).
RBAC Roles
Rbac Roles are composed of
-
RBAC API objects
- Pods
- PersistentVolumes
- ConfigMaps
- Deployments
- Nodes
- Secrets
- Namespaces
-
Possible operations over these resources are:
- create
- get
- delete
- list
- update
- edit
- watch
- exec
RBAC Elements
-
Rules: A rule is a set of operations (verbs) that can be carried out on a group of resources which belong to different API Groups.
-
Roles and ClusterRoles: Both consist of rules. The difference between a Role and a ClusterRole is the scope: in a Role, the rules are applicable to a single namespace, whereas a ClusterRole is cluster-wide, so the rules are applicable to more than one namespace. ClusterRoles can define rules for cluster-scoped resources (such as nodes) as well. Both Roles and ClusterRoles are mapped as API Resources inside our cluster.
-
RoleBindings and ClusterRoleBindings: Just as the names imply, these bind subjects to roles (i.e. the operations a given user can perform). As for Roles and ClusterRoles, the difference lies in the scope: a RoleBinding will make the rules effective inside a namespace, whereas a ClusterRoleBinding will make the rules effective in all namespaces.
-
Subjects: These correspond to the entity that attempts an operation in the cluster. There are three types of subjects:
- User Accounts: These are global, and meant for humans or processes living outside the cluster. There is no associated resource API Object in the Kubernetes cluster.
- Service Accounts: This kind of account is namespaced and meant for intra-cluster processes running inside pods, which want to authenticate against the API.
- Groups: This is used for referring to multiple accounts. There are some groups created by default such as cluster-admin (explained in later sections).
You can get more detailed information in the official Kubernetes documentation here.
Create user with limited namespace access
In this example, we will create a user with limited namespace access.
The following User Account will be created:
- Username: demo
- Group: demogroup
We will add the necessary RBAC policies so this user can fully manage deployments (i.e. use kubectl run
command) only inside the rbactest
namespace. At the end, we will test the policies to make sure they work as expected.
Create the rbactest namespace
-
Execute the
kubectl create
command to create the namespace (as the admin user):kubectl create namespace rbactest
Create the user credentials
Kubernetes does not have API Objects for User Accounts. Of the available ways to manage authentication (see Kubernetes official documentation for a complete list), we will use OpenSSL certificates for their simplicity.
Create the certificate
-
Create a private key for your user. In this example, we will name the file
demo.key
.Go to a temporary working directory in your terminal.
mkdir rbacdemo cd rbacdemo
openssl genrsa -out demo.key 2048 > Generating RSA private key, 2048 bit long modulus (2 primes) ...
The private key file
demo.key
has been created:ls > demo.key
-
Create a certificate sign request
demo.csr
using the private key you just created (demo.key
in this example). Make sure you specify your username and group in the -subj section (CN is for the username and O for the group). As previously mentioned, we will usedemo
as the name anddemogroup
as the group
openssl req -new -key demo.key -out demo.csr -subj "/CN=demo/O=demogroup"
The certificate sign request `demo.csr` has been created:
```bash
ls
> demo.csr demo.key
```
- We will use the Kubernetes cluster certificate authority (CA) for approving the request and generating the necessary certificate to access the cluster API.
Its location usually is /etc/kubernetes/pki/
.
But in our case (for Minikube), it would be ~/.minikube/
.
![](../images/cloud.png) **Cloud/Standalone**
> If you are **NOT** using the training VM, you have to use your own certificates.
-
Generate the final certificate
demo.crt
by approving the certificate sign request,demo.csr
, you made earlier. In this example, the certificate will be valid for 500 days:openssl x509 -req -in demo.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out demo.crt -days 500 > key -CAcreateserial -out demo.crt -days 500 > Signature ok > subject=CN = demo, O = demogroup > Getting CA Private Key
``
The final certificate
demo.crt
has been created:ls > demo.crt demo.csr demo.key
``
-
In a real world example you would now save both
demo.crt
anddemo.key
in a safe location.
Create the context
Add a new context with the new credentials for your Kubernetes cluster. This example is for a Minikube cluster but it should be similar for others:
-
Set credentials
kubectl config set-credentials demo --client-certificate=./demo.crt --client-key=./demo.key > User "demo" set.
``
-
Create context
kubectl config set-context demo-context --cluster=minikube --namespace=rbactest --user=demo > Context "demo-context" created.
``
Cloud/Standalone
If you are NOT using the training VM, you have to use your own cluster name instead of
--cluster=minikube
You should be able to get it withkubectl config current-context
. -
Check configuration
kubectl config view
``
We can see that we now have a context demo-context
and a user demo
in our configuration that will be used to access the Kubernetes API via kubectl
.
You should get an access denied error when using the kubectl
CLI with this configuration file. This is expected as we have not defined any permitted operations for this user.
kubectl --context=demo-context get pods
> No resources found.
> Error from server (Forbidden): pods is forbidden: User "demo" cannot list resource "pods" in API group "" in the namespace "rbactest"
Create the role for viewing deployments
We are creating the Rule
that allows a user to execute several Read Only
operations on Deployments, Pods and ReplicaSets, which belong to the core
(expressed by “” in the yaml
file), apps
, and extensions
API Groups:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: deployment-viewer
namespace: rbactest
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["get", "list"] # You can also use ["*"]
Create the Role
in the cluster using:
kubectl create -f ~/training/rbac/deployment-viewer.yaml
Bind the viewer role to the demo user
In this step we are creating the RuleBinding
that binds the deployment-viewer
Role
to the User Account demo
inside the rbactest
namespace:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: deployment-viewer-binding
namespace: rbactest
subjects:
- kind: User
name: demo
apiGroup: ""
roleRef:
kind: Role
name: deployment-viewer
apiGroup: ""
Create the Role in the cluster using:
kubectl create -f ~/training/rbac/deployment-viewer-binding.yaml
Test the RBAC viewer rule
Now you should be able to execute the following command without any issues:
kubectl --context=demo-context get pods
> No resources found.
No resources found.
simply means that we don’t have any Pods
deployed in this Namespace
.
If you run the same command for the default namespace with the --namespace=default
argument, it will fail, as the demo
user does not have access to this namespace.
kubectl --context=demo-context get pods --namespace=default
> No resources found.
> Error from server (Forbidden): pods is forbidden: User "demo" cannot list resource "pods" in API group "" in the namespace "default"
Also you still don’t have the rights to create or delete Deployments
:
kubectl --context=demo-context run --image alpine alpine
> Error from server (Forbidden): deployments.apps is forbidden: User "demo" cannot create resource "deployments" in API group "apps" in the namespace "rbactest"
Now you have created a user with limited Read Only permissions in your cluster.
Create the role for managing deployments
We are creating the Rule
that allows a user to execute several Read and Write
operations on Deployments, Pods and ReplicaSets, which belong to the core
(expressed by “” in the yaml
file), apps
, and extensions
API Groups:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: deployment-manager
namespace: rbactest
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["deployments", "replicasets", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # You can also use ["*"]
Create the Role
in the cluster using:
kubectl create -f ~/training/rbac/deployment-manager.yaml
Bind the Manager role to the demo user
In this step we are creating the RuleBinding
that binds the deployment-manager
Role
to the User Account demo
inside the rbactest
namespace:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: deployment-manager-binding
namespace: rbactest
subjects:
- kind: User
name: demo
apiGroup: ""
roleRef:
kind: Role
name: deployment-manager
apiGroup: ""
Create the Role in the cluster using:
kubectl create -f ~/training/rbac/deployment-manager-binding.yaml
Test the RBAC manager rule
Now you should be able to execute the following commands without any issues:
kubectl --context=demo-context run --image alpine alpine
> deployment.apps/alpine created
Check that the alpine Pod is running
kubectl --context=demo-context get pods
> NAME READY STATUS RESTARTS AGE
> alpine-7f866557df-dkmks 0/1 Completed 0 6s
However if you run the same command for the default namespace with the --namespace=default
argument, it will still fail, as the demo
user still does not have access to this namespace.
kubectl --context=demo-context get pods --namespace=default
> No resources found.
> Error from server (Forbidden): pods is forbidden: User "demo" cannot list resource "pods" in API group "" in the namespace "default"
Now you have created a user with limited permissions in your cluster but with full Management rights for Deployments in the rbactest
namespace.
Congratulations!!!
This concludes Lab 1 on RBAC and Roles/RoleBindings.