Breaking News
Home / How To / Role-based access control (RBAC) in Kubernetes

Role-based access control (RBAC) in Kubernetes



Role-Based Access Control (RBAC) is used to assign access to a computer or network resource in the Kubernetes cluster.

In this article, we will understand the basics of RBAC and create Role, ClusterRole, RoleBinding and ClusterRoleBinding Objects.

We then create a cube config file to grant restricted access to a specific user in a selected namespace.

But before we proceed, let us first understand the basics.

  1. A role or ClusterRole contains a set of permissions.
  2. A role specifies permissions within a specific namespace and ClusterRole is a non-naming resource.
  3. A role binding provides the permissions defined in a role to a user or set of users while ClusterRoleBinding grants access to cluster widths
  4. A role binding can refer to all roles in the same namespace. Alternatively, a RoleBinding can reference a ClusterRole and bind that ClusterRole to the RoleBindin namespace
  5. A kubeconfig file is a file used to configure access to Kubernetes from the command line tool kubectl.

To understand RBAC in detail, visit the official documentation for Kubernetes here.

Note: Refer screenshots to avoid any confusion before executing the commands. ( [email protected] = master node and [email protected] = user machine)

Conditions

  1. Kubernetes Cluster with at least 1 working node.
    Click here to learn how to create a Kubernetes cluster. This guide will help you create a Kubernetes cluster with 1 Master and 2 Nodes on AWS Ubuntu 18.04 EC2 instances.

What should we do?

  1. Create role, role binding, cluster role, cluster role binding object files.
  2. Create role, role binding, cluster role, cluster role binding objects in the cluster.
  3. Grant access to users using the cube-config file.
  4. Summary of the creation of cube-config files.

Create a role, role binding, cluster role, cluster role binding object files.

Create a file to create a role in the “default” namespace that can be used to give goat, watch and list access to podcasts.

vim my-role.yml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

my role

Create a new file to create a RoleBinding that allows the “pod-reader” role for the “jane” user within the “default” namespace.

vim my-role-binding.yml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

my-role-binding

Create a file to create a ClusterRole that can be used to give goat, watch and list access to secrets in any namespace, or in any namespace depending on how it is bound.

vim my-cluster-role.yml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

my-cluster-role

Create a new file to create a ClusterRoleBinding that allows all users in the “manager” group to read secrets in any namespace.

vim my-cluster-role-binding.yml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

my-cluster-role binding

Create a role, role binding, cluster role, cluster role binding object.

Obtain a list of existing roles and ClusterRoles from the cluster.

kubectl  get roles
kubectl  get clusterroles

goat-default-role-cluster role

Obtain a list of existing RoleBindings and ClusterRoleBindings from clusters.

kubectl  get rolebinding
kubectl  get clusterrolebinding

get-default-role-binding clusterrole binding

Now create a Role, RoleBinding and ClusterRole ClusterRoleBinding with the files we created in the steps above.

kubectl create -f my-role.yml
kubectl create -f my-role-binding.yml
kubectl create -f my-cluster-role.yml
kubectl create -f my-cluster-role-binding.yml

create-role-and-binding objects

Use the following commands to verify that the objects have been created.

kubectl  get roles | grep pod-reader
kubectl  get rolebinding | grep read-pods
kubectl  get clusterroles | grep secret-reader
kubectl  get clusterrolebinding | grep read-secrets-global

get-role-and-binding objects

In the screenshot above you can see that Role, RoleBinding and ClusterRole, ClusterRoleBinding have been created.

Provide access to users who use the kubeconfig (config) file.

In this section, we will now create a configuration file that can be shared with a user. To test this scenario, we create a “bob” on the Linux server and share this configuration file with the “bob” user. We then try to perform operations that are permissible and permissible for that user. We will bind an admin ClusterRole to the “bob” user which gives access to all objects within the “bob” namespace.

Create a key and certificate signing request (CSR) on the master nodes using openssl.advertisement

pwd
mkdir user-bob
cd user-bob/
openssl req -new -newkey rsa:4096 -nodes -keyout bob-k8s.key -out bob-k8s.csr -subj "/CN=bob/O=devops"
cat bob-k8s.csr | base64 | tr -d 'n'

Create a CertificateSigningRequest object definition file that contains the CSR we generated in the step above. In the file below, add the output from the “cat bob-k8s.csr | base64 | tr -d ‘ n'” command to the “request” property.

vim k8s-csr.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: bob-k8s-access
spec:
  groups:
  - system:authenticated
  request: # replace output of: cat bob-k8s.csr | base64 | tr -d 'n'
  usages:
  - client auth
cat k8s-csr.yaml

create-key-and-create-certificate-signing-request-object-file

Create a CertificateSigningRequest object within Kubernetes that contains CSR that we generated in the step above.

kubectl  get csr
kubectl  create -f k8s-csr.yaml
kubectl  get csr

Now we want to approve the CSR (CertificateSigningRequest) object that we created in the step above.

kubectl  get csr
kubectl certificate approve bob-k8s-access
kubectl  get csr

approve-certificate signing-request

In the screenshot above you can see that CSR has been approved, issued.

Retrieve the certificate located in the ‘status.certificate’ field of the CSR object.

ls -lt
kubectl get csr bob-k8s-access -o jsonpath="{.status.certificate}" | base64 --decode > bob-k8s-access.crt
ls -lt
cat bob-k8s-access.crt

download-the-certificates

Download cluster CA certificate which is the next requirement for Bob’s cube config file and save it in “k8s-ca.crt” file.

ls -lt
kubectl config view -o jsonpath="{.clusters[0].cluster.certificate-authority-data}" --raw | base64 --decode - > k8s-ca.crt
ls -lt
cat k8s-ca.crt

goat cluster-CA certificateadvertisement

Set the cluster configuration in the Bob cube config file. All these details will be added from our existing cube config with the command below.

ls -lt
kubectl config set-cluster $(kubectl config view -o jsonpath="{.clusters[0].name}") --server=$(kubectl config view -o jsonpath="{.clusters[0].cluster.server}") --certificate-authority=k8s-ca.crt --kubeconfig=bob-k8s-config --embed-certs
ls -lt
cat bob-k8s-config

set-up-the-cluster configuration-for-bob

Set the user who will import Bob’s key and certificate in the configuration file.

ls -lt
kubectl config set-credentials bob --client-certificate=bob-k8s-access.crt --client-key=bob-k8s.key --embed-certs --kubeconfig=bob-k8s-config
ls -lt
cat bob-k8s-config

set-up-the-user-bob configuration

Create a context for the “Bob” configuration file with the following command.

ls -lt
kubectl config set-context bob --cluster=$(kubectl config view -o jsonpath="{.clusters[0].name}") --namespace=bob --user=bob --kubeconfig=bob-k8s-config
ls -lt
cat bob-k8s-config

set-up-the-Contex-for-bob-configuration

Create a namespace for Bob

kubectl  get ns
kubectl create ns bob
kubectl  get ns -o wide
kubectl label ns bob user=bob env=sandbox
kubectl  get ns -o wide

Create-A-namespace-and-label-it

Specify the context that Bob will use for his kubectl commands.

cat bob-k8s-config
kubectl config use-context bob --kubeconfig=bob-k8s-config
cat bob-k8s-config

setting current context

Copy “bob-k8s-config” from the master node to the “.kube / config” file in Bob’s home directory and test Bob’s cube config by running the “kubectl version”.

vim .kube/config #All the output of "cat bob-k8s-config" command ran on the master node and save it to /home/bob/.kube/config on the user machine.
kubectl version #Execute this on the user machine

share-the-config-file-with-bob users

Test permissions by executing the following commands from the user machine.

kubectl  get nodes
kubectl  get pods
kubectl  get ns
kubectl  get deployments
kubectl  get all

bob-do-not-have-permissions-even

In the screenshot above you can see that the “Bob” user cannot perform any action because no access has been granted to it.

Assign Bob’s default cluster role to create most types of Kubernetes objects in his namespace. This “bob-admin” role gives admin access to “Bob” users in the “bob” namespace with “admin” ClusterRole.

Run the following command on the main node.

kubectl create rolebinding bob-admin --namespace=bob --clusterrole=admin --user=bob 
kubectl  get rolebinding
kubectl  get clusterrole | grep  admin

create-rolebinding-with-admin-cluster role-for-Bob-namespace-only

Few namespaces created for Bob.

Now run all of the following commands from the user machine.

kubectl  get ns
kubectl  get ns bob

validate-access-on-bob-namespace

In the screenshot above you can see the “Bob” user can not list “namespace” resources.

Create a Pod in the “bobs” namespace as the default namespace in Bob’s cube config file.

kubectl  run nginx --image=nginx
kubectl  get pods
kubectl  get pods -o wide

Check the current namespace as the default namespace

kubectl config get-contexts

create-pod-in-permitted namespace

In the screenshot above, you can see that “Bob” can create a Pod in the “bob” namespace because we have bound the “admin” role to the “Bob” user for the “bob” namespace.

Try creating a pod in a “default” namespace where Bob has no privileges. Because we have allowed the “Bob” user to create objects only in the “bob” namespace, the Bob user will not be able to create any of the resources in any namespace other than “bob”.

kubectl  run nginx-2 --image=nginx --namespace=default

pod-creation-failed-the-other-namespace

Check the namespace as the default namespace in the cube config file. This indicates that the “bob” namespace is set as the default namespace in the configuration file.

kubectl config view --minify | grep namespace:

check-current namespace set-as-default namespace-in-config-file

Summary of the creation of Kubeconfig files

  1. Create a key and certificate signing request (CSR) using openssl.
  2. Create a CertificateSigningRequest object definition file.
  3. Create a CertificateSigningRequest object.
  4. Approve CSR (CertificateSigningRequest).
  5. Retrieve the certificate for the CSR object.
  6. Retrieve CA certificate for clusters.
  7. Set the cluster configuration in cube config file.
  8. Set the user.
  9. Create a context.
  10. Create a namespace for the user.
  11. Enter the context in the cube config file.
  12. Forward cube config to the user.
  13. Test the permissions with the user’s configuration file
  14. Assign the role to the user
  15. Test the permissions again with the user’s configuration file.

Conclusion

In this article we saw the basics of Role, RoleBinding and ClusterRole, ClusterRoleBinding, we also created these objects in our cluster. We then created a configuration file that allows a specific user to perform operations in a specific namespace. We saw how RBAC can help us restrict access to the Kubernetes cluster.


Source link