Kubernetes RBAC and Service Account - CKA

Kubernetes RBAC and Service Account - CKA

In our previous blog, we covered Authentication and Authorization in Kubernetes. Authentication refers to "who you are," and we also issued a certificate for a new user (harshit). Authorization refers to "what you can do in a Kubernetes cluster," and we discussed four methods of authorization: ABAC, RBAC, Node, and Webhook. In this blog, we will explore how we can authorize our new user (harshit) to interact with cluster resources using RBAC, with hands-on examples. Let's get started.

What is RBAC?

Role-Based Access Control (RBAC) in Kubernetes is a method for regulating access to the Kubernetes API. It allows you to specify who can access what resources within a Kubernetes cluster, and what actions they can perform on those resources.

Key Concepts in Kubernetes RBAC:

  1. Role: Defines a set of permissions within a namespace. It contains rules that represent allowed operations on Kubernetes resources.

  2. RoleBinding: Grants the permissions defined in a Role to a user, group, or service account within a specific namespace.

  3. ClusterRole: Similar to a Role, but it is cluster wide. It can be used to define permissions across all namespaces or for cluster-scoped resources.

  4. ClusterRoleBinding: Similar to RoleBinding, but it grants the permissions of a ClusterRole to a user, group, or service account across the entire cluster.

How RBAC Works in Kubernetes:

  • Roles and RoleBindings are typically used to control access within a single namespace like pods, deployments,etc.

  • ClusterRoles and ClusterRoleBindings are used for granting access to resources across the entire cluster or for non-namespaced resources like nodes.

Before starting with examples, please set an alias for kubectl:

alias 'k=kubectl'

Example: Role & RoleBinding

  1. First, check who the current user is and whether they have access to Pods:

      kubectl auth whoami
      kubectl auth can-i get pod
    

    You'll see that the current user is kubernetes-admin, who can access Pods. However, the user harshit doesn't have access. To grant harshit access, we'll create a Role and assign it to the user.

  2. Creating a Role (pod-reader) and Granting Permissions to Get, List, and Watch 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"]
    

    apiVersion: rbac.authorization.k8s.io/v1

    • This specifies that the object is using the RBAC (Role-Based Access Control) API version v1.

kind: Role

  • Indicates the type of Kubernetes object being created, which is a Role.

  • A Role in Kubernetes defines permissions (rules) for resources within a specific namespace.

metadata

  • namespace: default

    • Specifies the namespace where the Role applies.

    • This Role is limited to the default namespace.

  • name: pod-reader

    • The name of the Role. Here, the Role is called pod-reader.

rules

  • Defines the permissions granted by the Role.

  • The rules are a list of API groups, resources, and allowed verbs.

apiGroups: [""]

  • The apiGroups field specifies which API group the rules apply to.

  • [""] (an empty string) refers to the core API group, which includes core Kubernetes resources such as Pods, Nodes, Services, etc.

  • For apiVersion, like apps/v1 and other we mention Named API Group as per the apiVersion group.

resources: ["pods"]

  • This Role applies to the Pods resource within the namespace.

verbs: ["get", "watch", "list"]

  • These are the actions permitted for the specified resource (pods):

    • get: Allows reading the details of a pod.

    • watch: Allows watching for changes to pods.

    • list: Allows listing all pods in the namespace.

Apply this file to create the Role.

Imperative Way of creating Role

    kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
  1. Creating a RoleBinding (read-pods) and Mapping the User harshit to the Role pod-reader

      apiVersion: rbac.authorization.k8s.io/v1
      # This role binding allows "harshit" 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: harshit # "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 you wish to bind to
        apiGroup: rbac.authorization.k8s.io
    

    Apply this file to bind the harshit user to the pod-reader Role.

    Imperative way of creating Role-binding

     kubectl create rolebinding read-pods --role=pod-reader --user=harshit
    
  2. Accessing the Pod as harshit

  3. Log in as harshit in the cluster. Add the harshit’s certificate and private key to the config file using:

      kubectl config set-credentials harshit --client-key=harshit.key --client-certificate=harshit.crt --embed-certs=true
    

    Now, set the context:

      kubectl config set-context harshit --cluster=kind-cka-cluster --user=harshit
    

    Switch to the harshit context:

      kubectl config use-context harshit
    

    Verify the context with:

    The harshit user now has permissions to get, list, and watch Pods, but cannot create them.

    You can see that user harshit has no permission for resource deployment and creating pods.

    For viewing the config file u can use kubectl config view

    we can see that our user harshit is added in config file.

For more details, read this Kubernetes Doc from the heading How to issue a certificate for a user.

Important Commands

  • To see the all roles: kubectl get role -A

  • To count all the roles in all namespaces: kubectl get role -A --no-headers | wc -l

  • To check the validity of certificates: openssl x509 -noout -dates -in <file.crt>

  • To search any command from reverse in history press Ctrl+R and then type few letters of it

Example: ClusterRole & ClusterRoleBinding

Before starting this example, switch back to the kubernetes-admin user.

Also, Check by kubectl auth whoami

ClusterRoles are powerful roles that can access resources across cluster level or all namespaces, including managing nodes, persistent volumes (PVs), certificate signing requests (CSRs), and even namespaces.

Command to See Cluster-Scoped Resources

kubectl api-resources --namespace=false

Command to See Namespace-Scoped Resources

 kubectl api-resources --namespace=true

That’s check whether user harshit has permission to get nodes

kubectl auth can-i get nodes --as harshit

  1. Creating a ClusterRole (node-reader)

      kubectl create clusterrole node-reader --verb=get,list,watch --resource=node
    

    For more details of clusterrole, run kubectl create clusterrole --help

  2. Creating a ClusterRoleBinding (node-reader-binding) and Mapping the User harshit to the ClusterRole node-reader

      kubectl create clusterrolebinding reader-binding --clusterrole=node-reader --user=harshit
    

  3. Now, the harshit user can get, watch, and list nodes but cannot delete them.

Or

Service account in Kubernetes

A Service Account in Kubernetes is an identity used by processes running in pods to authenticate and interact with the Kubernetes API. Unlike regular user accounts meant for humans, Service Accounts are intended for system components, like pods, to perform actions on the cluster. When a pod needs to interact with the Kubernetes API—like listing resources, creating or modifying resources—it does so under the identity of a Service Account.

By default, when a pod is created, Kubernetes automatically assigns it a default Service Account from the same namespace unless specified otherwise. This Service Account allows the pod to authenticate and gain access to the cluster's resources according to the permissions granted to it.

Authentication in Kubernetes Service Accounts

Authentication in Kubernetes involves validating the identity of the entity (human user, pod, etc.) making a request to the API server. For Service Accounts, Kubernetes uses tokens that are automatically generated when the account is created.

Note: Kubernetes also creates a default service account in each namespace, such as kube-system, kube-node-lease, etc.

Example: Creating a Service Account with RBAC

We'll create a service account named build-sa, grant it permissions to read Pods, and create a RoleBinding to attach the service account to the Role.

  1. Creating a Service Account (build-sa)

      kubectl create sa build-sa
    

  2. Let’s check if our service account has permissions or not

     kubectl get pod --as build-sa
     kubectl auth can-i get pod --as build-sa
    

  3. Creating a Role to Read Pods

      kubectl create role build-role --verb=list,get,watch --resource=pod
    

  4. Creating a RoleBinding

      kubectl create rolebinding build-rb --role=build-role --user=build-sa
    

  5. Now, our service account build-sa can watch, list, and get Pods with read-only access.

     kubectl get pod --as build-sa
     kubectl auth can-i get pods --as build-sa
    

  6. To Delete the Service Account

      kubectl delete sa build-sa
    
Manually Creating a Long-Lived API Token for a Service Account

Sometimes, you might need a long-lived API token for a Service Account, especially for non-interactive processes or external systems that need to access the Kubernetes API. To manually create a long-lived token, follow these steps:

  1. Create the Service Account:

     kubectl create serviceaccount <service-account-name>
    
  2. Create a Secret to Hold the Token:

      apiVersion: v1
      kind: Secret
      metadata:
        name: <secret-name>
        annotations:
          kubernetes.io/service-account.name: "<service-account-name>"
      type: kubernetes.io/service-account-token
    
  3. Associate the Secret with the Service Account: This step is usually handled automatically by Kubernetes, where it binds the token secret to the Service Account. You can verify this by describing the Service Account:

     kubectl describe serviceaccount <service-account-name>
    
  4. Retrieve the Token: Finally, you can retrieve the token from the secret:

      kubectl get secret <secret-name> -o jsonpath='{.data.token}' | base64 --decode
    

This token can now be used to authenticate against the Kubernetes API.

Notes and key takeaways from the video

Roles & Role Bindings: Granting Permissions

Think of roles as job descriptions defining user or group actions. Role bindings link these roles to specific users or groups, granting them those permissions.

  • Roles: Define permissions within a namespace.

    • Example: A "developer" role might allow getting, viewing, and deleting pods, as well as creating and viewing secrets.
  • Role Bindings: Connect roles to users or groups.

Cluster Roles: Expanding Permissions Beyond Namespaces

Cluster roles are like superpowered roles that can access resources across all namespaces. This includes powerful stuff like managing nodes, persistent volumes (PVs), certificate signing requests (CSRs), and even namespaces.

  • Check Available Resources: Use kubectl api-resources namespaced=false to see cluster-scoped resources. Replace false with true to check the namespace-scoped resources.

Cluster Role Bindings: Linking Users to Cluster Roles

Like role bindings, cluster role bindings connect users or groups to cluster roles, granting cluster-wide permissions.

Commands to create cluster role and cluster role binding

https://kubernetes.io/docs/reference/access-authn-authz/rbac/

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

Key Points:

  • Roles are namespace-scoped, while cluster roles are cluster-wide.

  • Use role bindings and cluster role bindings to assign permissions to users or groups.

  • Carefully manage permissions to ensure security and prevent unauthorized access.

Finally, we’ve covered RBAC with examples. Thank you for reading my blog! For better understanding, I encourage you to try these hands-on exercises yourself.