How to Create New User in Kubernetes

Written by: Bagus Facsi Aginsa
Published at: 03 Feb 2023


Kubernetes is meant to be used together with your team. But of course, you don’t want to give the wrong permission to the team. Take it easy, this article, we will explain to you how you can create a user in Kubernetes as well as set up a role for the user so your team can access Kubernetes with the right access and permission.

Check Prerequisite

  1. Kubernetes Cluster that already running.
  2. You have Admin access to the Kubernetes API.

2 Types of User in Kubernetes

There are 2 types of users in Kubernetes:

  1. Token based user. It is created using a service account object. This user is expected to be an application that uses a bearer token to access the Kubernetes API.
  2. Certificate based user. It is created using a user certificate via a certificate signing request object. This user is expected to be a human that uses kubectl command to access the Kubernetes API.

Although the expected usage is different, you can use either type of user for anything.

Kubectl also supports a bearer token if you prefer using them. Some application library also supports user certificate & key to access the Kubernetes API.

The difference between the 2 types is only when we create the user. After we create the user, we will use the same step to create a Role, and RoleBinding Object to give the right permission to the user.

Create a User

You can choose to create a token-based or certificate-based user here.

Create Token-Based User

To create a token-based user, first, we must create a ServiceAccount object. To do that, create a file

nano ServiceAccount.yaml

Copy this code

apiVersion: v1
kind: ServiceAccount
metadata:
 name: mynewuser

Change the mynewuser to the user name that suits your need, and then save and exit.

Before we create the service account, create a Secret object that will store the Token for the service account, create a file

nano Secret.yaml

Copy this code

apiVersion: v1
kind: Secret
metadata:
 name: mynewuser-secret
 annotations:
 kubernetes.io/service-account.name: mynewuser
type: kubernetes.io/service-account-token

You can change the name that matches your ServiceAccount Object, in this case, I will use mynewuser, and then save and exit.

Now create the object by applying the configuration using kubectl

kubectl apply -f ServiceAccount.yaml
kubectl apply -f Secret.yaml

Create Certificate Based User

First, Generate a private key for the new user using OpenSSL:

openssl genrsa -out mynewuser.key 2048

You can match the user name on the marked text according to your need. After running the command, you will get mynewuser.key file.

Generate Certificate Signing Request (CSR) from the private key:

openssl req -new -key mynewuser.key -out mynewuser.csr

Fill in the question according to your need:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields, there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []: ID
State or Province Name (full name) []: West Java
Locality Name (eg, city) []: Bandung
Organization Name (eg, company) []: facsiaginsa.com
Organizational Unit Name (eg, section) []: group of developer 
Common Name (eg, fully qualified host name) []: mynewuser
Email Address []: [email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:

After completing the question, you will get mynewuser.csr file. After that, run this command to encode the CSR file, you will need this later:

cat mynewuser.csr | base64 | tr -d "\n"

You will get encoded CSR like this:

LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQzZEQ0NBZEFDQVFBd2dhSXhDekFKQmdOVkJBWVRBa2xFTVJJd0VBWURWUVFJREFsWFpYTjBJRXBoZG1FeApFREFPQmdOVkJBY01CMEpoYm1SMWJtY3hHREFXQmdOVkJBb01EMlpoWTNOcFlXZHBibk5oTG1OdmJURWJNQmtHCkExVUVDd3dTWjNKdmRYQWdiMllnWkdWMlpXeHZjR1Z5TVJJd0VBWURWUVFEREFsdGVVNWxkMVZ6WlhJeElqQWcKQmdrcWhraUc5dzBCQ1FFV0UyMTVUbVYzVlhObGNrQm5iV0ZwYkM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3pYVGd1dWtHem5kOVdtZWZRSVhTR3dnRGhvazZJT0lvYnJGa2tXODVxCjRvKzdkUVN0OHpIcVk5Y3lkTFVWVy9uRmJ5LzZkK2Uxd3dVcVdSSStiMmxtTWxZWllReHRQOHlYT2kzcVBMM0wKUGxhMzg5VVpQUHlZaUE0QjhkWXV4eVZ1enFiRDVXUC9zRFFKbWZ2N1BzSG54Sk9xOFZURi83Y01ld3BWVGM3Ugo5dzlxS1lZZHUzN0s5QnpDajNTKzFrd2M1eUZtc2k3enRPZWVsVnJjenZNM1kyUjlmaFU4N0h3a25YQ0dCQUJWCjlZWDJKWlJXenJOS3pQMjNMd0QybWZNeFE2MVJPS0pQaGJaOUpuYjltNHo0cGdDMWpKcGdweTdYSUkyd1JWTkUKN3lsb2JTQmFlWW13dkxCaXJGaW5lb295R2xkaS9NUFR4aFZPR0NvZUp4d1JBZ01CQUFHZ0FEQU5CZ2txaGtpRwo5dzBCQVFzRkFBT0NBUUVBTHU1eGg0aFlFWUZ6TEM3MUpzOWhwbGdYeHhCS0ZaTllqd1pwUTlnTGcvOE9oOGFSCitkdktiQmNXak5rRDBOWTY4d0JuVEV3T0FDaXVtMU1FWnhZWXpOWkF2NkJPWEFUbFlKU0tqUU9UNWVxU21DM3gKQWtKcXBjU0F1cmJEUzBGYWxxelFLN3JycXdnVlByRHo1K21hR29QWEN2c2VHY3hUMWExZ3pSalZHb3hFQ0w0UQpYN3U2c1JUNHlUWmw0blhWOXdBTWdsR205RzUva2NvSElKaVBNVHRDR05VWm9saTVEMlRHcWFCbktLc2ZRMGFJCm1qZTVQemVWQUt2b05HM09oSEdNZEc0VmtSczRuRFR6ZXdpbnAxOXNYVWMyR0R4b0E2QUR2Z2Z0Sk1wYUFXekEKeGhMQnBHZVNLcTBtYzZ0UWZ6dE5NU002eGVMM0UyWVcrL1lnOUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K

Now create CertificateSigningRequest object in the Kubernetes. To do that, create a file

nano User.yaml

Copy this code

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
 name: mynewuser
spec:
 request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQzZEQ0NBZEFDQVFBd2dhSXhDekFKQmdOVkJBWVRBa2xFTVJJd0VBWURWUVFJREFsWFpYTjBJRXBoZG1FeApFREFPQmdOVkJBY01CMEpoYm1SMWJtY3hHREFXQmdOVkJBb01EMlpoWTNOcFlXZHBibk5oTG1OdmJURWJNQmtHCkExVUVDd3dTWjNKdmRYQWdiMllnWkdWMlpXeHZjR1Z5TVJJd0VBWURWUVFEREFsdGVVNWxkMVZ6WlhJeElqQWcKQmdrcWhraUc5dzBCQ1FFV0UyMTVUbVYzVlhObGNrQm5iV0ZwYkM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3pYVGd1dWtHem5kOVdtZWZRSVhTR3dnRGhvazZJT0lvYnJGa2tXODVxCjRvKzdkUVN0OHpIcVk5Y3lkTFVWVy9uRmJ5LzZkK2Uxd3dVcVdSSStiMmxtTWxZWllReHRQOHlYT2kzcVBMM0wKUGxhMzg5VVpQUHlZaUE0QjhkWXV4eVZ1enFiRDVXUC9zRFFKbWZ2N1BzSG54Sk9xOFZURi83Y01ld3BWVGM3Ugo5dzlxS1lZZHUzN0s5QnpDajNTKzFrd2M1eUZtc2k3enRPZWVsVnJjenZNM1kyUjlmaFU4N0h3a25YQ0dCQUJWCjlZWDJKWlJXenJOS3pQMjNMd0QybWZNeFE2MVJPS0pQaGJaOUpuYjltNHo0cGdDMWpKcGdweTdYSUkyd1JWTkUKN3lsb2JTQmFlWW13dkxCaXJGaW5lb295R2xkaS9NUFR4aFZPR0NvZUp4d1JBZ01CQUFHZ0FEQU5CZ2txaGtpRwo5dzBCQVFzRkFBT0NBUUVBTHU1eGg0aFlFWUZ6TEM3MUpzOWhwbGdYeHhCS0ZaTllqd1pwUTlnTGcvOE9oOGFSCitkdktiQmNXak5rRDBOWTY4d0JuVEV3T0FDaXVtMU1FWnhZWXpOWkF2NkJPWEFUbFlKU0tqUU9UNWVxU21DM3gKQWtKcXBjU0F1cmJEUzBGYWxxelFLN3JycXdnVlByRHo1K21hR29QWEN2c2VHY3hUMWExZ3pSalZHb3hFQ0w0UQpYN3U2c1JUNHlUWmw0blhWOXdBTWdsR205RzUva2NvSElKaVBNVHRDR05VWm9saTVEMlRHcWFCbktLc2ZRMGFJCm1qZTVQemVWQUt2b05HM09oSEdNZEc0VmtSczRuRFR6ZXdpbnAxOXNYVWMyR0R4b0E2QUR2Z2Z0Sk1wYUFXekEKeGhMQnBHZVNLcTBtYzZ0UWZ6dE5NU002eGVMM0UyWVcrL1lnOUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
 signerName: kubernetes.io/kube-apiserver-client
 expirationSeconds: 31536000 # 1 year
 usages:
 - client auth

Change the mynewuser to the user name according to your need, copy & paste the encoded CSR file to the request field to replace the marked text, and then save and exit.

Now create the object by applying the configuration using kubectl

kubectl apply -f User.yaml

After that, approve the Certificate Signing Request using this command

kubectl certificate approve mynewuser

Create Kubernetes Role

Right now, your user is already created on your Kubernetes cluster. But, it cannot do anything because we still do not give it any permission in the cluster. So now we will create a Role to define what can the user do in the cluster.

To do this, we have to make a Role Object. Create a file

nano Role.yaml

Copy & Paste this code:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 namespace: default
 name: developer
rules:
- apiGroups: ["", "apps", "networking.k8s.io"]
 resources: ["pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "deployments", "statefulsets", "ingresses"]
 verbs: ["get", "watch", "list", "update", "patch", "create", "delete"]

This role will satisfy all basic developer’s common needs to deploy their applications in k8s. Of course, you should modify the namespace to where the developer will deploy their apps.

You can also modify the rules further by editing the marked script according to your needs referring to the k8s documentation by running this command:

kubectl api-resources -o wide

For example, you want to add permission to cronjobs and jobs objects to the current Role. First, run this command:

kubectl api-resources -o wide | grep jobs 
NAME SHORTNAMES APIVERSION NAMESPACED KIND VERBS
cronjobs cj batch/v1 true CronJob [create delete deletecollection get list patch update watch]
jobs batch/v1 true Job [create delete deletecollection get list patch update watch]

Referring to this documentation, we can add some items to the previous role like this:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 namespace: default
 name: developer
rules:
- apiGroups: ["", "apps", "networking.k8s.io", "batch"]
 resources: ["jobs", "cronjobs", "pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "deployments", "statefulsets", "ingresses"]
 verbs: ["get", "watch", "list", "update", "patch", "create", "delete"]

If you are already satisfy with the role, you can execute this command:

kubectl apply -f Role.yaml

Create Kubernetes RoleBinding

In this step, we already have a user and a role object created. But the user still cannot do anything in the cluster because the user is not bound to the role. In this step, we will do exactly that by creating roleBinding object in our Kubernetes cluster.

To do this, we have to make a RoleBinding Object. Create a file

nano RoleBinding.yaml

Copy & Paste this code if you’re using Token Based User:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: myrolebinding
 namespace: default
subjects:
- kind: ServiceAccount
 name: mynewuser
roleRef:
 kind: Role
 name: developer
 apiGroup: rbac.authorization.k8s.io

Copy & Paste this code if you’re using Certificate Based User:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: myRoleBinding
 namespace: default
subjects:
- kind: User
 name: mynewuser
roleRef:
 kind: Role
 name: developer
 apiGroup: rbac.authorization.k8s.io

This script will bind the user with the role that was already created previously.

To apply the object, run this command:

kubectl apply -f RoleBinding.yaml

Get User Credential

You have created the user, role, and rolebinding object in Kubernetes. Now you can use the user credential to access the Kubernetes API.

If you create a token-based user, you can get the token by using this command:

kubectl get secret mynewuser-secret -o jsonpath="{.data.token}" | base64 -d

You will get a plain string of your token here.

If you create a certificate-based user, you can get the certificate file by using this command:

kubectl get csr mynewuser -o jsonpath='{.status.certificate}'| base64 -d > mynewuser.crt

You will get your user certificate stored in mynewuser.crt file.

That’s it, now you can use the token or the certificate to access your Kubernetes cluster.