How we managed to do it

Well, its time now for a short demonstration on how you can implement this. Let us start by issuing certificates to a Web Development Team member “Bob”. Then define the Role for the team, and Bind the Role to the “web-dev” group using a Role Binding. Finally, let’s do a quick smoke test to find out if Bob has the required access.

Issuing user certificates

Let us first start with issuing certificates to Bob. Ensure you connect to your Kubernetes cluster as a Cluster Admin.

Generate a key and a CSR for Bob

$ openssl req -new -newkey rsa:4096 -nodes -keyout bob-kubernetes.key -out bob-kubernetes.csr -subj "/CN=bob/O=web-dev" Generating a RSA private key

..............................................................................................................................................................................................................................++++

................++++

writing new private key to 'bob-kubernetes.key'

Create a Certificate Signing Request with Kubernetes

Base64 encode the generated CSR file.

$ cat bob-kubernetes.csr | base64 | tr -d '

'

Include the output in the below yaml

$ vim bob-kubernetes.csr

apiVersion: certificates.k8s.io/v1beta1

kind: CertificateSigningRequest

metadata:

name: bob-kubernetes-csr

spec:

groups:

- system:authenticated

request: <BASE64 encoded csr>

usages:

- client auth

Create the CSR using kubectl

$ kubectl create -f bob-kubernetes-csr.yaml certificatesigningrequest.certificates.k8s.io/bob-kubernetes-csr created

Check the CSR status.



NAME AGE REQUESTOR CONDITION

bob-kubernetes-csr 11m $ kubectl get csrNAME AGE REQUESTOR CONDITIONbob-kubernetes-csr 11m bharatmicrosystems@gmail.com Pending

Kubernetes has created the CSR and is now pending, and you would need to approve the CSR.

Approve the CSR

$ kubectl certificate approve bob-kubernetes-csr

certificatesigningrequest.certificates.k8s.io/bob-kubernetes-csr approved

Recheck the status, and you would see the CSR is approved and the certificate is issued



NAME AGE REQUESTOR CONDITION

bob-kubernetes-csr 11m $ kubectl get csrNAME AGE REQUESTOR CONDITIONbob-kubernetes-csr 11m bharatmicrosystems@gmail.com Approved, Issued

Retrieve Bob’s certificate

Retrieve Bob’s certificate and verify it to see if it is issued correctly.

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

$ cat bob-kubernetes-csr.crt

-----BEGIN CERTIFICATE-----

MIID6jCCAtKgAwIBAgIRANoImKoaCgLChvYWaxkvbt4wDQYJKoZIhvcNAQELBQAw

LzEtMCsGA1UEAxMkMTIyNWE4ZTMtYmYxOS00YmU1LTg0MzItMGNlODI4ODAxNTdh

yX98TghQAH6Sqz553UTDR2AMe4CvJEcVnBiPPf3X3qvYNA1vpCurQJsdBfnOURy9

6Zto2J3vTAj/qFSC9EGcV3Gi02i4ksSrHEH+TBX/admmJBtWUHiSmuQ3IjN5Nlj4

................truncated output................................

ebKliem++qo6aMrbKLQXXEcjxECzc6hOPWdQgAa8Pqe9YRGw4CUxTJ/mppE5PXjs

N/QERhNXZGwdCUgug1cUlOAa8YIMvvL9TA5ZaJ+oHskPlWejg4wRpkdlqce3jCx5

RSmlTnv3LN5qKTdt9TQCcB92YLC3NxaiQj0UcxSyMvAIcGS7e9duNyOZgIMuobF9

+AJMaUr1WRrgY+jF1G+aVpcuDYgZlhkCAShmQYUi4yUop5p3gnlHwl8359KCrw==

-----END CERTIFICATE-----

Get the Cluster CA Certificate

For Bob to authenticate with the cluster, Bob’s kubectl client needs to trust the server. To do so, we would require the Cluster CA certificate.

$ kubectl config view -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' --raw | base64 --decode - > kubernetes-ca.crt

Creating the Kubeconfig file for Bob

Now, as we have all the required artefacts in place, we would create a Kube-config file for Bob.

$ kubectl config set-cluster $(kubectl config view -o jsonpath='{.clusters[0].name}') --server=$(kubectl config view -o jsonpath='{.clusters[0].cluster.server}') --certificate-authority=kubernetes-ca.crt --kubeconfig=bob-kubernetes-config --embed-certs

Cluster "kubernetes" set.

Set the credentials and context

If you look at the bob-kubernetes-config, you find the contexts and users fields are empty. Let us set the relevant credentials and context to the user.

Let us start by setting the credentials.

$ kubectl config set-credentials bob --client-certificate=bob-kubernetes-csr.crt --client-key=bob-kubernetes.key --embed-certs --kubeconfig=bob-kubernetes-config

User "bob" set.

Since we want to provide access to Bob only on the web namespace, we need to set the web namespace in Bob’s context. That defaults the web namespace to Bob.

$ kubectl config set-context bob --cluster=$(kubectl config view -o jsonpath='{.clusters[0].name}') --namespace=web --user=bob --kubeconfig=bob-kubernetes-config

Context "bob" created.

The Kube-config file for Bob is now ready and can be distributed to Bob securely.

Testing the configuration

We are all set now and ready to test the configuration. Use Bob’s Kube-config file and switch context to it.

$ kubectl config use-context bob --kubeconfig=bob-kubernetes-config

Switched to context "bob".

Then run a kubectl version with Bob’s Kube-config file, and you should get the version details. That shows Bob can authenticate with the Kube API Server.

$ kubectl version --kubeconfig=bob-kubernetes-config

Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.9", GitCommit:"2e808b7cb054ee242b68e62455323aa783991f03", GitTreeState:"clean", BuildDate:"2020-01-18T23:33:14Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

Server Version: version.Info{Major:"1", Minor:"15+", GitVersion:"v1.15.11-gke.5", GitCommit:"a5bf731ea129336a3cf32c3375317b3a626919d7", GitTreeState:"clean", BuildDate:"2020-03-31T02:49:49Z", GoVersion:"go1.12.17b4", Compiler:"gc", Platform:"linux/amd64"}

Try to list pods using Bob’s Kube-config file.

$ kubectl get pods --kubeconfig=bob-kubernetes-config

Error from server (Forbidden): pods is forbidden: User "bob" cannot list resource "pods" in API group "" in the namespace "web"

What’s wrong? Well we have provided Bob access to the cluster, and the Kube API Server authenticates him, but he does not have any authority as we haven’t set up RBAC for his group.

Set up RBAC for Web Developers

Though we have issued the Kube-config file successfully to Bob, he does not have permissions to access the cluster. Though he was able to authenticate with the Kube API server successfully, he wasn’t able to perform any actions within the cluster. L now set up RBAC for Bob’s group.

Create a Namespace

Start by creating a namespace “web” for Web Developers to deploy and manage their workloads.

$ kubectl create ns web

namespace/web created

Create a Role

Create a Role for the web-dev group to access all web namespace resources.

$ vim web-dev-role.yaml

---

kind: Role

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

name: web-dev

namespace: web

rules:

- apiGroups: ["", "extensions", "apps"]

resources: ["*"]

verbs: ["*"]

- apiGroups: ["batch"]

resources:

- jobs

- cronjobs

verbs: ["*"] $ kubectl apply -f web-dev-role.yaml

role.rbac.authorization.k8s.io/web-dev created

Create a Role Binding

Bind the “web-dev” group with the “web-dev” role using a RoleBinding.