Skip to main content

Command Palette

Search for a command to run...

Kubernetes-part-9

Updated
10 min read
Kubernetes-part-9

Understanding Role-Based Access Control (RBAC) in Kubernetes

Role-Based Access Control (RBAC) is a way to manage who can do what in a system by assigning roles to users. So, instead of giving each user individual access permissions, you give them a role, and the role controls what they can or can't do. This makes it easier to manage security in big systems since you only need to change the permissions for a role, not every user.

Roles and RoleBindings are key components of the RBAC system. They control access to resources based on user roles. There are two main types of Roles and RoleBindings

Defining Roles in Kubernetes: Role vs. ClusterRole

1. Role

  • Limited to a specific namespace

  • Used to define permissions (like read, write, update, delete) on resources within a specific namespace.

  • Example: A role that allows access to resources like Pods, Services, and ConfigMaps within the dev namespace.

Example Role YAML

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

In this example, the pod-reader role allows the user to get, list, and watch Pods within the dev namespace.

2. ClusterRole

  • It defines permissions across the entire cluster

  • Used for cluster-wide resources like nodes or persistentvolumes, it can also be used within specific namespaces if bound with a RoleBinding

  • Example: A role that gives access to cluster-level resources such as nodes, storage, or the ability to manage namespaces.

Example ClusterRole YAML

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-admin
rules:
- apiGroups: [""]
  resources: ["nodes", "namespaces"]
  verbs: ["get", "list", "watch", "create", "delete"]

In this example, the cluster-admin role allows access to nodes and namespaces across the entire cluster.

1. RoleBindings: Assigning Permissions in Kubernetes

  • Namespaced

  • A RoleBinding grants a Role's permissions to users, groups, or service accounts within a specific namespace. It binds a Role to a user or group in that namespace.

  • Example: Bind the pod-reader role to a specific user or service account in the dev namespace.

Example RoleBinding YAML

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: dev
subjects:
- kind: User
  name: praduman
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

In this example, the RoleBinding grants the user praduman the pod-reader role's permissions within the dev namespace.

2. ClusterRoleBindings: Cluster-Wide Permission Management

  • Cluster-wide

  • A ClusterRoleBinding grants a ClusterRole's permissions to users, groups, or service accounts across the entire cluster or across all namespaces.

  • Example: Bind the cluster-admin role to a user or group across the whole cluster.

Example ClusterRoleBinding YAML

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-binding
subjects:
- kind: User
  name: praduman
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

In this example, the ClusterRoleBinding grants the user john the cluster-admin permissions across the entire cluster.


  • Create a service account (sa.yaml)

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: deployment-manager
    
      kubectl apply -f sa.yaml
    

  • Create a Role (role.yaml)

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        namespace: default
        name: deployment-creator
      rules:
      - apiGroups: ["apps"]        # mention the group of resource
        resources: ["deployments"]
        verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
    

    verbs define what user can do

      kubectl apply -f role.yaml
    

To list all the resource types that are available in the cluster

kubectl api-resources

To see the groups & version of a specific resource

kubectl explain <resource-name>

  • Create RoleBinding (rb.yaml)

      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: deployment-manager-binding
        namespace: default
      subjects:
      - kind: ServiceAccount
        name: deployment-manager
        namespace: default
      roleRef:
        kind: Role
        name: deployment-creator
        apiGroup: rbac.authorization.k8s.io
    
      kubectl apply -f rb.yaml
    

    To see about how a specific resource is defined

    kubectl explain <resource-name>
    

    Example: To see what we can fill inside kind section of rolebinding

    kubectl explain RoleBinding.subjects.kind
    

  • Create a deployment using the service account that is created (deploy.yaml)

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx-deployment
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          spec:
            serviceAccountName: deployment-manager
            containers:
            - name: nginx
              image: nginx
              ports:
              - containerPort: 80
    
      kubectl apply -f deploy.yaml
    

  • Try to create the service or pod using the service account

      kubectl expose deployment nginx-deployment --port=80 --as=system:serviceaccount:default:deployment-manager
    
      kubectl run nginx --image=nginx --as=system:serviceaccount:default:deployment-manager
    

    This will not created as we didn’t give that user permission to do this

  • To check if a service account can perform a task

      kubectl auth can-i create deployments --as=system:serviceaccount:default:deployment-manager
      kubectl auth can-i create secrets --as=system:serviceaccount:default:deployment-manager
      kubectl auth can-i list services --as=system:serviceaccount:default:deployment-manager
    

Admission Controllers: Ensuring Security and Compliance in Kubernetes

It validate and mutate the request coming to the API server. It is important for keeping security, rules and operations in check. They work like gatekeepers, making sure that any changes to the cluster follow the rules, whether it's about security, limits on resources, or specific business guidelines. You can use the built-in admission controllers or create custom ones with webhooks to fit your needs.

Types of Admission Controllers: Validating vs. Mutating

  1. Validating Admission Controllers:

    • These controllers are used to validate incoming requests. If a request fails validation, it is rejected.

    • Example: You might use a validating admission controller to ensure that all Pods have certain labels or annotations.

  2. Mutating Admission Controllers:

    • These controllers can modify incoming requests before they are stored. For instance, they can add default values or modify fields in the request.

    • Example: A mutating admission controller might automatically add resource limits to containers if they are not specified.

On creating a namespace a service account with default name is created

  • To create a token for a service account

    before kubernetes V1.24 a token get automatically generated when we create a service account. but now we need to create it manually. For pod the token get generated automatically with the validation for 1 hour by default

      kubectl create token <service-account-name>
    

    You can check the Token validity on jwt.io


Practical Demo: Implementing RBAC in Kubernetes

  • Create a namespace

      kubectl create ns praduman
    
  • Create a ServiceAccount

      kubectl create sa my-sa -n praduman
    
  • Create a Role

      kubectl create role my-role --verb=create --resource=deployments.apps -n pradumankubectl create role my-role --verb=create --resource=deployments.apps -n praduman
    
  • Create a RoleBinding

      kubectl create rolebinding my-rolebinding --role=my-role --serviceaccount=praduman:my-sa -n praduman
    

  • Check the permission

  • Create a token for the ServiceAccount

      kubectl create token my-sa -n praduman
    

Authenticating with Kubernetes: A Step-by-Step Demo

  • View Kubernetes Configuration

      kubectl config view
    
  • Find the Cluster Name from Kubeconfig

      export CLUSTER_NAME=<your-cluster-name>
    
  • Get the API Server Endpoint

      export APISERVER=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}')
    

    This retrieves the URL of the Kubernetes API server from your kubeconfig file and stores it in the APISERVER environment variable.

  • Make a Request to the API Server

      curl --cacert /etc/kubernetes/pki/ca.crt $APISERVER/version
    

    This curl command attempts to query the API server for its version, using the CA certificate to verify the server's identity. The --cacert option points to the CA certificate used by the Kubernetes control plane to authenticate requests.

  • Attempts to get a list of deployments

      curl --cacert /etc/kubernetes/pki/ca.crt $APISERVER/apis/apps/v1/deployments
    

    However, this request will likely fail without proper authentication, as the Kubernetes API requires either a client certificate, a bearer token, or some other authentication method.

  • Using Client Certificates for Authentication

    Extract and decode the client certificate and key

    These are base64-encoded, so they need to be decoded using base64 -d

      echo "<client-certificate-data_from kubeconfig>" | base64 -d > client
      echo "<client-key-data_from kubeconfig>" | base64 -d > key
    
  • Use the certificate and key with curl to make the request

      curl --cacert /etc/kubernetes/pki/ca.crt --cert client --key key $APISERVER/apis/apps/v1/deployments
    

    This authenticates the request using the client certificate and key, allowing you to retrieve a list of deployments.

Validating Admission Policies with CEL in Kubernetes

Validation Admission Policies are like rules for your Kubernetes cluster. They decide if changes to the cluster are okay or not. CEL(Common Expression Language) is a special language used to write these rules. It's like a recipe book for the policy. You can customize these rules a lot. You can make them specific to certain things in your cluster or even change them based on different situations. You can use CEL to create rules that control what can and can't be done in your Kubernetes cluster. These rules can be very flexible and tailored to your specific needs.

  • Create a validating admission policy and validating admission policy binding
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: "demo-policy.example.com"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas <= 5"

---

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "demo-binding-test.example.com"
spec:
  policyName: "demo-policy.example.com"
  validationActions: [Deny]
  matchResources:
    namespaceSelector:
      matchLabels:
        environment: test

  • Lable the namespace

      kubectl label ns default environment=test
    
  • Try to run replicas

      kubectl create deploy nginx --image=nginx --replicas=6
    

Enforcing Image Policies with ImagePolicyWebhook in Kubernetes

The ImagePolicyWebhook is an admission controller that inspects image metadata when a pod is being created. It checks the image being used in the pod, evaluates it against predefined rules, and decides whether to allow or deny the image. This is useful for enforcing security policies and ensuring that only authorized images are used in the cluster

  • Clone the GitHub Repository

      git clone https://github.com/saiyam1814/imagepolicy.git
    

    This repository contains a sample implementation of the ImagePolicyWebhook

  • Create a Directory for the Demo

      mkdir /etc/kubernetes/demo
    

    creates a directory at /etc/kubernetes/demo where you will store the ImagePolicyWebhook configuration and file

  • Copy Files to the Demo Directory

      cp -r imagepolicy/ /etc/kubernetes/demo
    

    This command copies the imagepolicy directory to the /etc/kubernetes/demo directory. The -r flag ensures that everything inside the imagepolicy folder is copied

  • Navigate to the Demo Directory

      cd /etc/kubernetes/demo
    
  • Move Files to Parent Directory

      cd imagepolicy
      mv * ..
      cd ..
    

    moving all files from the imagepolicy folder into the /etc/kubernetes/demo directory, then returning to the parent directory

  • View the admission.json File

      cat admission.json
    

    This JSON file defines how the webhook interacts with the Kubernetes API server

  • View the Configuration File

      cat config
    
  • Edit the kube-apiserver.yaml File

      vi /etc/kubernetes/manifests/kube-apiserver.yaml
    
  • Add New Settings to Enable ImagePolicyWebhook

    You need to add the following lines to the kube-apiserver.yaml file to enable the ImagePolicyWebhook

      - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
      - --admission-control-config-file=/etc/kubernetes/demo/admission.json
    
    • The first line enables the ImagePolicyWebhook admission plugin along with NodeRestriction.

    • The second line specifies the path to the admission.json file you created earlier, which contains webhook rules.

  • Configuring Volume Mounts

      volumeMounts:
        - mountPath: /etc/kubernetes/demo
          name: admission
          readOnly: true
    
  • Adding the Volume

      volumes:
      - hostPath:
          path: /etc/kubernetes/demo
        name: admission
    
  • Run an Nginx Pod to Test the Policy

      kubectl run nginx --image=nginx
    

    If the ImagePolicyWebhook is working, it will inspect the nginx image to see if it meets the defined policies. Based on the policy logic, it will either allow or deny the creation of the pod

Conclusion

In this article, we explored the intricacies of Role-Based Access Control (RBAC) in Kubernetes, delving into the definitions and differences between Roles and ClusterRoles, as well as RoleBindings and ClusterRoleBindings. We also examined the importance of Admission Controllers in maintaining security and compliance within a Kubernetes cluster, highlighting the roles of Validating and Mutating Admission Controllers. Additionally, we discussed the implementation of RBAC through practical demos, including creating namespaces, service accounts, roles, and role bindings. Finally, we touched on advanced topics like Validating Admission Policies with CEL and enforcing image policies using ImagePolicyWebhook. By understanding and implementing these concepts, you can significantly enhance the security and manageability of your Kubernetes environments


💡 Let’s connect and discuss DevOps, cloud automation, and cutting-edge technology

🔗 LinkedIn | 💼 Upwork | 🐦 Twitter | 👨‍💻 GitHub

More from this blog

P

Praduman's blog

22 posts

Hi, I'm learning DevOps tools and concepts. I enjoy sharing my learning experiences and projects through blogs to help others who are on a similar journey.