Access dashboard on AKS with RBAC enabled

AKS supports RBAC since its General Available.

After visiting the Dashboard of Kubernetes in AKS you will get warnings because the user visiting the dashboard does not have enough rights. This post tells you how to solve this. But let’s create a RBAC enabled cluster first.

Creating an AKS cluster with RBAC

RBAC is not switched on by default. Since Azure CLI version 2.0.40 RBAC is enabled by default. RBAC is enabled during the creation of the cluster.

Create an AKS cluster with RBAC and HTTP application routing with the CLI:

az aks create --resource-group clouddemo --name democluster --kubernetes-version 1.11.1 --max-pods 100 --enable-addons http_application_routing --ssh-key-value "C:\repos\pascal\subscription\ssh\" --service-principal abcdef-1234-4bf5-b140-8a37729da10e --client-secret yRXSaXMZqV46nawU

I prefer to create a service principal myself on forhand. Use this PowerShell script to create one

I pass a ssh key which is being created on forhand also. Read here how to create one with Puttygen:

Besides the CLI, it’s also possible to create an AKS cluster with an ARM template:

Trying to access the dashboard

You have provisioned a RBAC enabled AKS cluster. When you create a proxy to the dashboard. You will see the following errors :

configmaps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list configmaps in the namespace "default"
persistentvolumeclaims is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list persistentvolumeclaims in the namespace "default"
secrets is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list secrets in the namespace "default"
services is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list services in the namespace "default"
ingresses.extensions is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list ingresses.extensions in the namespace "default"
daemonsets.apps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list daemonsets.apps in the namespace "default"
pods is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list pods in the namespace "default"
events is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list events in the namespace "default"
deployments.apps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list deployments.apps in the namespace "default"
replicasets.apps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list replicasets.apps in the namespace "default"
jobs.batch is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list jobs.batch in the namespace "default"
cronjobs.batch is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list cronjobs.batch in the namespace "default"
replicationcontrollers is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list replicationcontrollers in the namespace "default"
statefulsets.apps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list statefulsets.apps in the namespace "default"

This looks like this:dashboard errors

The ServiceAccount used by the dashboard has not enough rights to access all resources.

Solving the problem

It is possible to give the ServiceAccount, which is being used by the dashboard more rights. This is not considered as a best practice. If you like this approach, here you can read how to do this:

The best solution is to create a specific user/serviceaccount which has the rights to access the dashboard. Here are the steps to configure this:

1. Create a ServiceAccount for the dashboard:
in the mean time Microsoft has added a service account already for this. So service account kubernetes-dashboard exists already.

kubectl create serviceaccount kubernetes-dashboard -n kube-system

2. Create a ClusterRoleBinding which gives the role dashboard-admin to the ServiceAccount created above.

kubectl create clusterrolebinding kubernetes-dashboard -n kube-system --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard

3. Get the Token of the ServiceAccount.
To access the dashboard we need the token of the ServiceAccount.

This can be done with the following line, which doesn’t work on a Windows CLI:

kubectl get secret $(kubectl get serviceaccount kubernetes-dashboard -n kube-system -o jsonpath="{.secrets[0].name}") -n kube-system -o jsonpath="{.data.token}" | base64 --decode

Personally I’ve installed the Ubuntu Linux Subsystem and installed the Azure CLI and configured kubectl on it. An alternative is to execute it in Powershell:

$data = kubectl get secret $(kubectl get serviceaccount kubernetes-dashboard -n kube-system -o jsonpath="{.secrets[0].name}") -n kube-system -o jsonpath="{.data.token}"
[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($data)) | clip

(Thank you for the clip addition Amanda Debler)

There are 2 ways to authenticate to the Dashboard. Both ways use the token.
The first way shows how to authenticate with the login view.
The second way shows how to authenticate with an added Bearer token to the request header.

4. Login with the Token into the dashboard.
4a. Start a proxy to the dashboard:

kubectl proxy

4b. Access the dashboard in your browser on:

You will see the warnings as can be seen in the screenshot above. You need to login using the login view, but the login view is not shown by default.

4c. Navigate to the login view:

k8s login

Choose for token and enter the token you gathered with step 3.
Now you have the functionality in the dashboard you expected.

5. Add an Bearer token to authenticate
It is possible to add the needed Bearer token to each request using an addin of Chrome.

5a. Start a tunnel to the Dashboard.
This is an alternative to the login-view approach.
You are used to start the dashboard with kubectl proxy. But this doesn’t work well with  adding headers to a request. Therefor you need to use port-forward:
You will need the name of the Pod of the Dashboard:

kubectl -n kube-system get pods

Find the name of the Pod of the Dashboard and use this name in the port-forward command:

kubectl port-forward kubernetes-dashboard-5ffc5c5558-t2ngc 9090:9090 -n kube-system

5b. Install and configure an extension in Chrome to add request headers for each request to the Dashboard.
For example ModHeader or Requestly are extension which offer this functionality.

Configure the extension with value:
Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRhc2hib2FyZC10b2tlbi02d3RxYiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2Vyd

When you access the portal you are authenticated right away.

The configuration of the extensions looks like the following:


7 gedachtes over “Access dashboard on AKS with RBAC enabled

  1. Do you think rbac should still be enabled when using a ‘jumpbox’ in your vnet and only cluster admins use it?

    Why didn’t you choose to add a service to expose the Dashboard (or use an ingress)?


    • I think RBAC will be enabled by default in the near future on AKS. RBAC can make your cluster more secure. When your admins use a jumpbox to access the dashboard or the cluster with kubectl, then the cluster is still not as secure as with RBAC enabled. With RBAC, you can have fine grained control over what users can do on the cluster and reduces the chances of an intrusion.

      When I would have chosen a service (or ingress) to expose the dashboard, then my accesspoint to maintain the whole cluster is accessible for the world. Even with RBAC enabled this is a security risk and considered as a bad practice.

      Liked by 1 persoon

  2. You can send output in PowerShell to the Windows Clipboard by piping it to “clip”, which will ensure that you didn’t miss anything or get extra spaces/returns from copying from the screen:

    $data = kubectl get secret $(kubectl get serviceaccount dashboard -o jsonpath=”{.secrets[0].name}”) -o jsonpath=”{.data.token}”
    [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($data)) | clip


  3. In step “3. Get the Token of the ServiceAccount.” there should be one more “-n kube-system” in the “kubectl get secret” call:

    kubectl get secret $(kubectl get serviceaccount kubernetes-dashboard -n kube-system -o jsonpath=”{.secrets[0].name}”) -n kube-system -o jsonpath=”{.data.token}” | base64 –decode


  4. I think they’ve recently fixed even more Azure AD to K8s RBAC stuff, because I got the usual errors when I ran kubectl proxy on a new cluster, but after running Step 2 (kubectl create clusterrolebinding kubernetes-dashboard …), I clicked the link in 4b (http://localhost:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/), and it went straight to the full dashboard, no need to login with the token from Step 3!

    K8s version of cluster: 1.11.2


Geef een reactie

Vul je gegevens in of klik op een icoon om in te loggen. logo

Je reageert onder je account. Log uit /  Bijwerken )

Google+ photo

Je reageert onder je Google+ account. Log uit /  Bijwerken )


Je reageert onder je Twitter account. Log uit /  Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit /  Bijwerken )

Verbinden met %s