K8s - Creating a User and Group

 

In the previous blog we saw about role and role binding. In this post, we will see how to create a user and group. Technically, there is no concept called "User" and "Group" in K8s. 

But, K8s provides ways to authenticate an external user/group with K8s. In this blog, we will see how to use certificate based authentication.

Below are steps to onboard a user:

1) Create a private key.

2) Create a certificate signing request (CSR) using the above private key.

3) Generate a CSR request.

4) Approve the CSR request.

5) Extract the approved CRT file from the approved CSR request.

6) Build the config file.

When we create a CSR, we mention the USERNAME and GROUPNAME.

Let's see practically.

Generating a private key. I am going to create a user called "demouser".


Now, we have the private key. Using that we are going to create a CSR.

Note the highlighted portion, which is the subject where CN(Common Name) refers to username and O(Organization) refers to group name.

Re-iterating, the users and groups are not K8s resources like pod, deployment, secrets. These are just a subject which uses certificate to authenticate with K8s API server to perform some actions.

Next, we will create a CSR objects and get it approved. 

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: demouser
spec:
  request: <cat readodemouser.csr | base64 | tr -d '\n'>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

Under request: we need to use base64 to encode the CSR.


Final csr yaml file looks like the below:


Now, we should see a CSR submitted and it is in pending state.


We need approve CSR. I am approving the CSR with my "default" credentials.


How, who approves the CSR? It is approved by Kubernetes Certificate Authority.

In Kubernetes cluster setup with kubeadm, the Kubernetes root CA certificate and its corresponding private keys are typically stored in the control plane /etc/kubernetes/pki/ca.crt and /etc/kubernetes/pki/ca.key

Now, we will extract the client certificate data from approved CSR.

CLIENT_CERTIFICATE_DATA - kubectl get csr demouser -o jsonpath='{.status.certificate}'


Now, we have client private key, client certificate data and we need K8s Public Key of Certificate Authority. 

Where do I get Public Key of Certificate Authority K8s CLUSTER_CA ?

We can get it from kubeconfig file, else we can get it from $ kubectl config view --raw command. 


We are almost done. We need to build "config" file. I am using environmental variable to simplify the process.

The config file needs K8S CLUSTER_NAME, CLIENT_CERTIFICATE_DATA, CLIENT_KEY_DATA, CLUSTER_CA and CLUSTER_ENDPOINT.

CLUSTER_NAME=`kubectl config view --minify -o jsonpath={.clusters[*].name}`
CLIENT_CERTIFICATE_DATA=`kubectl get csr demouser -o jsonpath='{.status.certificate}'`
CLIENT_KEY_DATA=`cat demouser.key | base64 | tr -d '\n'`
CLUSTER_CA=`kubectl config view --raw -o json | jq -r '.clusters[] | select(.name == "'kubernetes'") | .cluster."certificate-authority-data"'`
CLUSTER_ENDPOINT=`kubectl config view --raw -o json | jq -r '.clusters[] | select(.name == "'kubernetes'") | .cluster."server"'`

USERNAME=demouser
NAMESPACE=test-namespace

We are set to build our config file.


apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: ${CLUSTER_CA}
    server: ${CLUSTER_ENDPOINT}
  name: ${CLUSTER_NAME}
users:
- name: ${USERNAME}
  user:
    client-certificate-data: ${CLIENT_CERTIFICATE_DATA}
    client-key-data: ${CLIENT_KEY_DATA}
contexts:
- context:
    cluster: ${CLUSTER_NAME}
    user: ${USERNAME}
    namespace: ${NAMESPACE}
  name: ${USERNAME}-${CLUSTER_NAME}
current-context: ${USERNAME}-${CLUSTER_NAME}
EOF

Now, we have the kubeconfig file called "demouser.config". Let use this file for performing Kubernetes operations.

KUBECONFIG=./demouser.config -> Refers to use the said config file for authentication to connect to the clusters under said namespace.

Since we don't have namespace called "test-namespace" it failed. Let's create one:


This time error is different. It says "pod if forbidden", which is definitely access issue.

Our user is assigned to a group called "demogroup", this is as per CSR subject.

Now, we need to create  a role and bind that role to the group "demogroup".





Above commands are namely for creating a role and binding to the group "demogroup". NOTE: Role and Rolebinding are namespace scoped. So, they are under "test-namespace".




Let's test it now.


It works. Let's try to create a pod.


It fails, which is expected. Because the role has only "list,get,watch" permissions.

Comments

Popular posts from this blog

K8s - ETCD

SRE/DevOps Syllabus

K8s - Deployment and HPA replicas