Create users on Kubernetes cluster and assign permissions

When using Kubernetes cluster in teams, we need to distribute the access to the Kubernetes admins/developers.

Obviously, In k8s world RBAC is the preferred way to authenticate and authorize users.

But, there are different ways of doing it.

  • You can either use bearer token and use your Kubernetes clients.
  • Or create users by cooking bash script with serviceaccounts, roles, clusterroles and rolebindings.
  • Using LDAP and other third-party add-ons. e.g Gangway.

Apart from this if you are on the cloud using managed Kubernetes clusters. Everyone has their way of providing authentication.

Today, we are going to see how we can create a user with minimal efforts and assign them privileges to access the resources.

This guide assumes you have a basic understanding of Kubernetes and its basic resources.

We can use tools like Klum,Kiosk and many more.

In this tutorial, we will use Klum and perform the following tasks.

  • Create namespaces.
  • Use Klum to create users and grant permission to the user to a namespace.

Pre-requisite:

  • Kubernetes cluster: If you don’t have one you can quickly spin up one using Minikube, Kind or use one from Katakoda.

  • Kubectl.

  • jq.

We will use one with Katakoda.

Step 1. Verify you have access to create a cluster using kubectl cluster-info

$ kubectl cluster-info
Kubernetes master is running at https://172.17.0.36:8443
KubeDNS is running at https://172.17.0.36:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Step 2. Create namespaces: earth mars and moon using command kubectl create ns

$ kubectl create ns earth
namespace/earth created
$ kubectl create ns moon
namespace/moon created
$ kubectl create ns mars
namespace/mars created

Step 3. Deploy Klum which creates custom resource definition for the user and kubeconfig of the resource.

kubectl apply -f https://raw.githubusercontent.com/ibuildthecloud/klum/master/deploy.yaml
namespace/klum created
deployment.apps/klum created
serviceaccount/klum created
clusterrolebinding.rbac.authorization.k8s.io/klum-cluster-admin created

Step 4. Create a user human using the below template which has access to the earth namespace.

kind: User
apiVersion: klum.cattle.io/v1alpha1
metadata:
  name: human
spec:
  roles:
  - namespace: earth
    clusterRole: admin

Create it.

$ kubectl apply -f user-human.yml
user.klum.cattle.io/human created

Step 5. Create a user alien who has access to all the 3 namespaces.

kind: User
apiVersion: klum.cattle.io/v1alpha1
metadata:
  name: alien
spec:
  roles:
  - namespace: earth
    clusterRole: admin
  - namespace: moon
    clusterRole: admin
  - namespace: mars
    clusterRole: admin
$ kubectl apply -f user-alien.yml
user.klum.cattle.io/alien created

Step 6. Check users and get the kubeconfigs for both the users using the command.

kubectl get users and kubectl get kubeconfig human

$ kubectl get users
NAME    AGE
alien   60s
human   6m57s

$ kubectl get kubeconfigs
NAME    AGE
alien   73s
human   7m10s

Get the kubeconfigs in the json format.

$ kubectl get kubeconfig human -o json | jq .spec > humankubeconfig
$ kubectl get kubeconfig alien -o json | jq .spec > alienkubeconfig

Step 7. Verify the access and permissions.

Scenario 1. Let’s explore the permissions for the user human across the cluster.

Create Nginx deployment in earth namespace using kubectl -n earth create deployment --image=nginx nginx-app

$ kubectl -n earth --kubeconfig=humankubecofig  create deployment --image=nginx nginx-app
deployment.apps/nginx-app created
$ kubectl -n earth --kubeconfig=humankubecofig get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx-app-9964799-b29zh   1/1     Running   0          3m23s

Now, using the same kubeconfig of user human let’s try to create an app in namespace mars and moon.

$ kubectl -n mars --kubeconfig=humankubecofig  create deployment --image=nginx nginx-app
Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:klum:human" cannot create resource "deployments" in API group "apps" in the namespace "mars"

Same for namespace moon.

$ kubectl -n moon --kubeconfig=humankubecofig  create deployment --image=nginx nginx-app
Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:klum:human" cannot create resource "deployments" in API group "apps" in the namespace "moon"

So, here we have restricted access for user human which cannot create or update resources other than the earth namespace.

Scenario 2. Let’s explore the permissions for the user alien across the cluster.

Create deployment in mars namespace.

$ kubectl -n mars --kubeconfig=alienkubeconfig  create deployment --image=nginx nginx-app
deployment.apps/nginx-app created
$ kubectl -n mars  --kubeconfig=alienkubeconfig  get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx-app-9964799-d4vrh   1/1     Running   0          39s

It works!

Now let’s create deploys in the moon namespace and earth namespace.

$ kubectl -n moon --kubeconfig=alienkubeconfig  create deployment --image=nginx nginx-app
deployment.apps/nginx-app created
$ kubectl -n moon  --kubeconfig=alienkubeconfig  get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx-app-9964799-q98lp   1/1     Running   0          13s
$ kubectl -n earth  --kubeconfig=alienkubeconfig  get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx-app-9964799-kndhv   1/1     Running   0          7m

It works here too :)

So, user human has permissions to create resources in earth namespace. While user alien has permissions to create resources in all the 3 namespaces i.e earth, mars, and moon.

In this way using Klum we can quickly create users and assign permissions to them on kubernetes clusters.

Also, we can create cluster-admin users with full access on the kubernetes cluster.

Happy Kubernauting! :)