Experimenting with Kubernetes RBAC on Windows 10 with docker desktop

This started as a dump of my notes exploring this but thought it might be useful for others.

Docker desktop is a quick and easy way to run a Kubernetes cluster locally on Windows 10 allowing Windows users to experiment with Kubernetes. If you have Windows subsystem for Linux installed you can use this as the docker backend which provides better performance than Hyper-V.

Kubernetes RBAC (Role based access control) is a Kubernetes resource which allows us to define policies to determine which actions specific users are allowed to execute at cluster and namespace level. e.g pod creation.

If you are not familiar with RBAC there are many fantastic resources which explain RBAC fundamentals which are worth reading via a quick Google.

Setting up a user and authenticating with Kubernetes

Users cannot be added to a cluster through an API call, so user accounts have to be externally managed and then authenticated by the cluster. There are a few methods available to authenticate with the cluster.

I decided to focus on X509 client certificates. We first create the private key for a user and a certificate signing request. We ask the cluster's CA to certify the certificate. We then authenticate using the signed certificate.

Create the certificate signing request

I did this in Ubuntu via WSL2.

openssl genrsa -out myuser.key 2048  
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser/O=myusergroup"  

Next we ask the Kubernetes API to sign the CSR.

Create a cert-sign-request.yaml

kind: CertificateSigningRequest  
metadata:  
  name: myuser
spec:  
  request: <TO REPLACE>
  usages: ['digital signature', 'key encipherment',
    'client auth']

Head back into Linux (WSL) to create the Request string (< TO REPLACE>). There are presumably methods to do this all in windows but this was easiest for me.

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

Back in windows:

kubectl apply -f .\cert-sign-request.yml  
kubectl certificate approve myuser  

Next we need to extract the base64 encoded signed certificate from the Kubernetes API.

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

In windows copy this into a txt file and generate the crt.

certutil -decode cerbase64.txt myuser.crt  

To authenticate with Kubernetes as myuser we need 2 things, the crt we generated above and also the key file which if you did the same as me was created on Linux. If using WSL2 you can locate the key file easily enough here: \\wsl$\<distro>\home\<me>

Impersonating our new user

kubectl config view will show we are currently authenticated as admin the docker-desktop user.

To add the new user we add a new context with the credentials.

kubectl config set-credentials myuser --client-key myuser.key --client-certificate myuser.crt --embed-certs

kubectl config set-context myuser --cluster docker-desktop --user myuser  

We can now run commands as our user to test RBAC:

kubectl --context=myuser get pods  

You will see an error - as the user has no permissions.

Creating RBAC policies

To test RBAC let's create a simple nginx pod definition ready for later - nginx-pod.yaml:

apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx-pod
  labels:
    name: nginx-pod
spec:  
  containers:
  - name: nginx-pod
    image: nginx
    ports:
    - containerPort: 8080

Running kubectl apply --context=myuser -f ./nginx-pod.yaml will throw a permissions error.

Let's create an editor role which will allow myuser permissions to create this pod - pod-editor-role.yaml

kind: Role  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
  name: pod-editor
rules:  
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create", "get", "list", "watch"]
kubectl apply -f pod-editor-role.yaml  

To assign the member to the role we create a role binding - myuser-editor-binding.yaml:

kind: RoleBinding  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
  name: myuser-editor
subjects:  
- kind: User
  name: myuser
  apiGroup: rbac.authorization.k8s.io
roleRef:  
  kind: Role
  name: pod-editor
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f myuser-editor-binding.yaml  

Now if we create the pod as myuser - success!

kubectl apply --context=myuser -f ./nginx-pod.yaml  

This is really scratching the surface of RBAC and not meant to be a complete overview. Again our friend Google produces many fantastic resources if you wish to get stuck in furthur.

Dave Leigh

Web, and long time Sitecore developer based in Bristol, UK, working at Valtech - valtech.co.uk - @valtech.
I occasionally do other things too.