Day 23/24 of 40 Days of K8s: RBAC in Kubernetes !! ☸️

Day 23/24 of 40 Days of K8s: RBAC in Kubernetes !! ☸️

In the previous day we learnt how to create a private key for the user and create CSR using private key and then sign and issue certificate for the client and now client was able to authenticate with cluster.

Problem: Authenticated but Unauthorized

  • After authentication, the client is unable to access resources.

  • Reason: Lack of permissions to perform actions in the cluster.

Solution: Role-Based Access Control (RBAC)

❇ RBAC(Role Based Access Control)

ROLE:

  • Assign permissions to the users or groups to perform actions on the cluster objects using Roles.

  • we create role which has resources and permissions.

  • Roles are Namespace scoped(resources like pods,deploy,svc,rs..etc) and Users will be associated wth Roles using RoleBinding.

  • To know the resources at the namespace level use the command

      kubectl api-resources --namespaced=true
    

ROLE-BINDING:

  • where we have list of roles and subject of kind as user or group or service account defined.

  • We bind Roles to users/groups/Service account using RoleBinding.

❇ TASK

  1. I created a new user named gopi and issued a certificate. I then created a new context and switched to the kind-cluster-gopi context, following the guide from the previous day..

     kubectl auth whoami
    

  2. I wanted to create a new pod, but let's check if I have permission to do that using command

     kubectl auth can-i create pod
    

  3. Switch back to the original context with admin permissions.

     kubectl config use-context kind-kind
    

    As you can see, now we are admin user as we switched to the context kind-kind

  4. Create a new Role named pod-reader. The Role should grant permissions to get, watch and list Pods.

    Here is Role yaml with pods as resources and permissions set to get,watch,list for pods

     apiVersion: rbac.authorization.k8s.io/v1
     kind: Role
     metadata:
       namespace: default
       name: pod-reader
     rules:
     - apiGroups: [""] # "" indicates the core API group
       resources: ["pods"]
       verbs: ["get", "watch", "list"]
    

    After role creation, this means whoever associated with this Role using RoleBinding will have get,watch,list permissions on all pods.

  5. Create a new RoleBinding named read-pods. Map the user gopi to the Role named pod-reader.

    Here is RoleBinding yaml with roleref and subjects as user gopi

     apiVersion: rbac.authorization.k8s.io/v1
     # This role binding allows "jane" to read pods in the "default" namespace.
     # You need to already have a Role named "pod-reader" in that namespace.
     kind: RoleBinding
     metadata:
       name: read-pods
       namespace: default
     subjects:
     # You can specify more than one "subject"
     - kind: User
       name: gopi # "name" is case sensitive
       apiGroup: rbac.authorization.k8s.io
     roleRef:
       # "roleRef" specifies the binding to a Role / ClusterRole
       kind: Role #this must be Role or ClusterRole
       name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
       apiGroup: rbac.authorization.k8s.io
    

  6. Now, let's switch to the context named kind-cluster-gopi and Create a new Pod named nginx with the image nginx

    After switching the context, when i tried to create a pod named nginx it shows forbidden error as I don't have create permissions on the pods but just get,watch,list permissions.

  7. Let's verify if that is true or not by checking get pods

  8. Try creating deployment of nginx now and verify the status

    This shows that the user gopi is unable to create deployment but admin user has permissions to do so.

    As an admin in the cluster, we can check the permissions of other users using the kubectl auth can-i command like below

     kubectl auth can-i create deploy --as gopi
    

    In Kubernetes, we've explored authorization using RBAC, which utilizes Role and RoleBinding resources that are limited to a specific namespace. This approach works well for granting permissions to users, groups, and service accounts such as developers, database administrators, and testers etc...

    However, if we need to grant cluster-level admin access, we should use a ClusterRole instead of a Role. Similarly, we would replace RoleBinding with ClusterRoleBinding to apply permissions across the entire cluster.

❇ CLUSTER ROLE

  • Assign permissions to the users or groups to perform actions on the cluster objects using Roles.

  • we create Cluster Role which has resources and permissions.

  • ClusterRoles are Cluster wide(resources like Nodes,Namespaces,SC,CRD's..etc) and Users/groups/service account will be associated wth ClusterRole using ClusterRoleBinding.

To know the resources at the cluster level use the command

kubectl api-resources --namespaced=false

❇ CLUSTER ROLE BINDING

  • where we have list of Cluster Roles and subject of kind as user or group or service account defined.

  • We bind Cluster Roles to users/groups/Service account using ClusterRoleBinding.

Commands to create cluster role and cluster role binding Imperatively

kubectl create clusterrole node-reader --verb=get,list,watch --resource=nodes
kubectl create clusterrolebinding node-reader-binding --clusterrole=node-reader --user=gopi

❇ TASK

  1. Create a new Cluster Role named node-reader. The ClusterRole should grant permissions to get, watch and list nodes.

    Here is Cluster Role yaml with nodes as resources and permissions set to get,watch,list for nodes

     apiVersion: rbac.authorization.k8s.io/v1
     kind: ClusterRole
     metadata:
       # "namespace" omitted since ClusterRoles are not namespaced
       name: node-reader
     rules:
     - apiGroups: [""]
       #
       # at the HTTP level, the name of the resource for accessing nodes
       # objects is "nodes"
       resources: ["nodes"]
       verbs: ["get", "watch", "list"]
    

    Make sure to switch the context to kind-kind before heading to create ClusterRole else you will find the error as seen below since user gopi doesnt have permissions to create ClusterRole.

  2. Now, switch the context to kind-kind context then create ClusterRole object

    This shows that though we created a ClusterRole with permissions to access nodes, the user gopi is still unable to get node information. To grant gopi the necessary access, we must bind the ClusterRole using a ClusterRoleBinding.

    Once this binding is in place, gopi will have permissions to get, watch, and list all nodes across all namespaces.

    In this context, resources refers to the type of resource, while resource names specifies the names of those resources.

  3. Let's create a ClusterRolebinding now to bind these ClusterRole to the user named gopi

    Here is ClusterRoleBinding yaml with roleref named node-reader and subjects set to user gopi

     apiVersion: rbac.authorization.k8s.io/v1
     # This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
     kind: ClusterRoleBinding
     metadata:
       name: node-reads-global
     subjects:
     - kind: User
       name: gopi # Name is case sensitive
       apiGroup: rbac.authorization.k8s.io
     roleRef:
       kind: ClusterRole
       name: node-reader
       apiGroup: rbac.authorization.k8s.io
    

This means, ClusterRole named node-reader is binded for User named gopi using ClusterRoleBinding. Now, User gopi will have access to get,list,watch nodes.

  1. Let's verify if the user gopi has these permissions or not

This shows that the user gopi has permissions to get, watch, and list the nodes across all namespaces in the cluster, but does not have permissions to delete or describe the nodes.

#Kubernetes #RBAC #Authorization #Role #RoleBinding #ClusterRole #ClusterRoleBinding #40DaysofKubernetes #CKASeries