Simplifying Access Control with RBAC in Kubernetes

How to control access, assign roles, and enforce security policies within your Kubernetes cluster.

Simplifying Access Control with RBAC in Kubernetes

RBAC (Role-Based Access Control) in Kubernetes lets you manage who can do what in your cluster. It’s like assigning roles in a team some people can only view files, while others can edit or delete them. As shown in below image.

Here’s how RBAC helps:

Refer this repository.

  1. Create a namespace & apply the changes:
# namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: apache-namespace
kubectl apply -f namespace.yml

kubectl get ns
  1. Create a user using Service account & apply the changes:

Note: A ServiceAccount is used to grant pods or workloads specific permissions to interact with the Kubernetes API securely.

#apache-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: apache-user
  namespace: apache-namespace
kubectl apply -f apache-serviceaccount.yml

kubectl get serviceaccount -n apache-namespace

  1. Create a deployment for apache & apply the changes:
# apache-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-deployment
  namespace: apache-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache
  template:
    metadata:
      labels:
        app: apache
    spec:
      containers:
      - name: apache
        image: httpd:2.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: apache-service
  namespace: apache-namespace
spec:
  selector:
    app: apache
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
kubectl apply -f apache-deployment.yml

kubectl get all -n apache-namespace

  1. Create a role for apache & apply:
# apache-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: apache-namespace
  name: apache-manager  #Role Name
rules:
- apiGroups: ["", "apps", "extensions"]   #Groups={("" blank " /v1"), (app/v1), (extension/v1)}
  resources: ["deployments", "services", "pods"] #Resources
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] #verbs which can perform with resources
kubectl apply -f apache-role.yml

Now role has been created to access the resources.

  1. Now perform Role binding:

A RoleBinding links a Role to a user, group, or ServiceAccount, granting them specific permissions within a namespace.

# apache-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: apache-manager-binding
  namespace: apache-namespace
subjects:
- kind: User
  name: apache-user # This should be replaced with the actual user name.  |  [This user will get the Role mentioned in roleRef]
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: apache-manager
  apiGroup: rbac.authorization.k8s.io

The user who receives access will be able to perform the actions specified in our apache-role.yml.

kubectl apply -f apache-rolebinding.yml
  1. Check the ServiceAccount and RoleBindings:
kubectl get serviceaccount -n apache-namespace -owide

kubectl get rolebinding -n apache-namespace -owide

  1. Test Apache User Permissions:
#Check the user
kubectl auth whoami

To access some resources with our user, follow these steps:

Note: You can find these commands in the repository.

kubectl auth can-i get pods -n apache-namespace --as=apache-user

These are some resources that our user can access, as specified in our file.

  1. Now, let's attempt to remove the deployment from our resources, as outlined in apache-role.yml:
# apache-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: apache-namespace
  name: apache-manager  #Role Name
rules:
- apiGroups: ["", "apps", "extensions"]   #Groups={("" blank " /v1"), (app/v1), (extension/v1)}
  resources: ["services", "pods"] #Resources
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] #verbs which can perform with resources
kubectl apply -f apache-role.yml

kubectl auth can-i get deployment -n apache-namespace --as=apache-user

If you remove deployment access from the apache-role.yml, you will no longer be able to access deployments.

  1. You can add “*” in resources so you’ll receive permission for all the resources:
# apache-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: apache-namespace
  name: apache-manager  #Role Name
rules:
- apiGroups: ["", "apps", "extensions"]   #Groups={("" blank " /v1"), (app/v1), (extension/v1)}
  resources: ["*"] #Resources
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] #verbs which can perform with resources

This is hoe RBAC works.


Happy Learning :)

Chetan Mohod ✨

For more DevOps updates, you can follow me on LinkedIn.