A Practical Approach to Understanding Kubernetes Authentication

Understanding Kubernetes Authentication – By Janakiram MSV

In a production environment, Kubernetes administrators use namespaces to isolate resources and deployments. Namespaces act as a logical boundary to enforce basic access control.

Let’s say we have Bob, new admin that joined the DevOps team to manage the Kubernetes deployments for the engineering group. We now have to provide him with just enough access to manage the engineering namespace. Assuming you are the cluster administrator with permissions to manage global resources and objects, you would onboard Bob and help him with the credentials needed to access Kubernetes cluster.

NOTE: Click on the LAB SETUP button on the right-hand side to get the lab-ready for performing hands-on. This will set up a terminal and an IDE to perform the lab.

Run the he below commands to generate a private key for Bob.

openssl genrsa -out bob.key 2048

We also need a Certificate Signing Request which can be generated from the key.

openssl req -new -key bob.key -out bob.csr -subj "/CN=bob/O=eng"\n

encode that in Base64

cat bob.csr | base64 | tr -d '\n'

We need to embed the generated base64-encoded string in a YAML file and submit that to Kubernetes as a Certificate Signing Request. This step will essentially associate Bob’s private key with Kubernetes cluster.

vim signing-request.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: cy-user-csr
spec:
  groups:
  - system:authenticated
  request: 
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

In the signing-request.yamlfile, update the request field with the encoded CSR, we got from earlier step. So It would look like something like following:-

.............
 groups:
  - system:authenticated
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1lqQ0NBVW9DQVFBd0hURU1NQW9HQTFVRUF3d0RZbTlpTVEwd0N3WURWUVFLREFSbGJtZHVNSUlCSWpBTgpCZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUEzSU9oUTArMFJUakpqZjBKTkd2Rmo0YWFlN1hYCkkrZWkzTzZWTEpqMHNKNDBvengyUTVndXBmeFc5b0lEYTJETnhVZjZkNHVMOUJ3V2lhdFdQdnBDNm80MHJQc2EKTjBUdEhEekFYeWppc0E5VXVRMVNKMWg5Mkg0TU9XWEpWNWJWaTlXYjBKU3hLbXVrSUVtaERJcW9TcEh6MU5xaApQMWNXOFFpNXpoVVBmWlpnOUhSaWVUQ2xEMmR3bWRtS1JjbU9uenNGVWhJWmZWanVZNzZJUm9KbksyaHNzVjZoCmMyY1JNTVNEdFA0ZDArYkxOY1BKdExpS3JjQkdwUGxLUEdrSHovM2NNbVhpVi8wY2xqUlppMzJCb3B4NlI1NUIKc0Z6cXZwcWgzNWxLNUVOUGxPZy9sdURFdllGeUtzOUY2aERBRFhDNzQxU0ZCQTI0TERzcTFiWWtVUUlEQVFBQgpvQUF3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUxTejgxL2N3bjQxbVRrUDhabWhhUUx3MkpIRkN4ZUlaOFdpCkZOV0U1cnRVd3hrSjJGWVJKRlFUL1hJN0FoL0pXTkhqeHlhOUNyN3c0OThmanN3bDF2ZzQ1QUgrR29DeVEwTWkKOU1MMHl0WmZyaG5jYmtpRG9oSUpuaWhJTjlCUGpHVkw2SG1USytGc0sybG1ZZ1JDdk9Cclg3Rkh6ZjgwM0ZFNAp4ZkgrZlFsdGxDdEZTSEhuaUlzZTFEQ2J4cFVTdnRISXpYMFcyb2hXV3RPVkRpOTAzOW8zY2VaWmdVK3VRYno0Cmp2djJoeVdRNDhORFl3RWF1UUU2S3NBQTFLT0IyUkI2dE45bjFTVWoxU1B2WnBsQkVieDZ5MTkzaUJSVFJRM2wKM2JhdFRNUUEzelBsdk01ZEE2Vy8rQWcwVm0xMk1SR091VFRLSEU2bE5INE1DbHQvRGZZPQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
  signerName: kubernetes.io/kube-apiserver-client
 ........

Apply the signing-request YAML file. 

kubectl create -f signing-request.yaml

Verify the CSR with the below kubectl command:

kubectl get csr

Notice that the request is still pending. The cluster admin has to approve it before it becomes active.

kubectl certificate approve bob-csr

Now that the certificated has been approved and issued, we need to get the signed certificate from the cluster. This is the most critical step in onboarding Bob.

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

The file, bob.crt is the client certificate that’s used to authenticate Bob. We now have the combination of the private key (bob.key) and the approved certificate (bob.crt) from Kubernetes. As long as Bob has these two assets, he can get authenticated with the cluster.

It’s time to add Bob as a user to Kubernetes.

kubectl config set-credentials bob --client-certificate=bob.crt --client-key=bob.key

Open ~/.kube/config file to verify that the credentials are set.

cat ~/.kube/config 

Let’s also create a new namespace called engineering for which Bob is the administrator.

kubectl create namespace engineering
kubectl get namespaces

The kubectl CLI has a very useful switch in the form of auth which can verify the permissions for a specific user. Let’s check if the current user who is the admin has access to the engineering namespace. Given that you are the cluster admin, it’s not surprising to see the output.

kubectl auth can-i list pods --namespace engineering

We can also check if Bob has got access to the engineering namespace.

kubectl auth can-i list pods --namespace engineering --as bob

It’s obvious that Bob doesn’t have access to the namespace. That’s because we have created the credentials but not explicitly authorized Bob for any specific action on any object.

In the next part of this tutorial series, I will walk you through the steps involved in authorizing Bob. It would also give us an opportunity to learn about roles and role bindings. Stay tuned!

Janakiram MSV’s Webinar series, “Machine Intelligence and Modern Infrastructure (MI2)” offers informative and insightful sessions covering cutting-edge technologies. Sign up for the upcoming MI2 webinar at http://mi2.live.

Join Our Newsletter

Share this article:

Table of Contents