---
title: "Kubernetes Dashboard on ARM with RBAC"
source: "https://www.tigera.io/blog/kubernetes-dashboard-on-arm-with-rbac/"
---

[Technical Blog](https://www.tigera.io/category/technical-blog/)

# Kubernetes Dashboard on ARM with RBAC

By [Martin Jensen](https://www.tigera.io/blog/author/martin-jensen/) on Jan 07, 2019 • 5 min read

In the guide about setting up Kubernetes 1.9.0 using kubeadm on Raspberry Pis, RBAC was enabled by default. This blog post will show how to run the Kubernetes dashboard with RBAC enabled.

## Prerequisites

- Kubernetes cluster up and running (see [blog post](http://kubecloud.io/setup-a-kubernetes-1-9-0-raspberry-pi-cluster-on-raspbian-using-kubeadm-f8b3b85bc2d1))

- [kubectl](http://kubernetes.io/docs/tasks/tools/install-kubectl/) v. 1.9.0 on your local machine

 

## Setting up kubeconfig

Let’s configure your local machine to communicate with your cluster using *kubectl*when your cluster from the previous guide has been set up.

Download the config from your master node using scp

```
`$ scp pi@master.local:/home/pi/.kube/config ./config`
```

Copy the config into your local machine’s *~/.kube* directory.

**NOTICE!** If you already have a cluster configuration, this will overwrite that configuration! In that case you can use the double dash — kubeconfig flag instead of copying the file or merging the configs.

```
`$ cp config ~/.kube/config`
```

Test the configuration by listing the cluster nodes:

```
`$ kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready master 27m v1.9.0 worker-01 Ready <none> 25m v1.9.0 worker-02 Ready <none> 25m v1.9.0 worker-03 Ready <none> 25m v1.9.0`
```

 

## Creating the dashboard

The Kubernetes source creates several resources in the *kube-system*namespace: secret, service account, role, rolebinding, deployment, and service.

```
`$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard-arm.yaml secret "kubernetes-dashboard-certs" created serviceaccount "kubernetes-dashboard" created role "kubernetes-dashboard-minimal" created rolebinding "kubernetes-dashboard-minimal" created deployment "kubernetes-dashboard" created service "kubernetes-dashboard" created`
```

Afterwards, you will be able to start a proxy from your local machine to access the service you just created.

```
`kubectl proxy`
```

The dashboard is accessible at [http://localhost:8001/ui](http://localhost:8001/ui). Since *kubectl*handles the proxy to the API Server and binds to port 8001 (default) on your host machine, the url points to localhost.

You should see a lot of errors if you skip the sign in dialog such as:

```
`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"`
```

But we will fix that.

![A Kubernetes dashboard screenshot with multiple warnings: "kubernetes-dashboard" service account lacks permissions to list various resources in the "default" namespace.](https://cdn-images-1.medium.com/max/1600/1*VgKWKIc4_84ZBXLSPu9JKQ.png)

Dashboard errors when skipping sign in

 

The following will create a service account in the *default* namespace and make a *clusterrolebinding* to allow you to use the dashboard.

```
`$ kubectl create serviceaccount dashboard -n default serviceaccount "dashboard" created`
```

 

```
`$ kubectl create clusterrolebinding dashboard-admin -n default --clusterrole=cluster-admin --serviceaccount=default:dashboard clusterrolebinding "dashboard-admin" created`
```

Read more about the *clusterrole* and its finer-grained options [from the documentation](http://kubernetes.io/docs/admin/authorization/rbac/#user-facing-roles). Your could e.g. make a *view* or *edit* clusterrolebinding for readonly access or users who aren’t allowed to change roles and rolebindings.

The following command outputs the token of your serviceaccount in a format ready to be copied into the *sign in dialog* by entering the outputted token (the trailing ‘%’ is NOT a part of the token).

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

 

```
`eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRhc2hib2FyZC10b2tlbi03ZHB2MiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkYXNoYm9hcmQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiYTVmNDlhZi0xMDM4LTExZTgtYTc1ZS1iODI3ZWI5ZmU3ZGIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkYXNoYm9hcmQifQ.wDEn348dWbIGFFXx1dujn2nksJk607UrmVfXomPPwjH22idq0ktoy65UlQYQyHW5igsP36eoyJF3fWAsC-URaMZ8bGIDKV9at4Lt0BrKSAr9V3eD0dE7uIvtyZrbT7_BERGB-RTZhXMa1WUTWeuvwWLBzCxIUClDhub9c9CAPmsaU3OrdzF9aGW8LV6F-4ALYAhpr48ez-0PpjofTPEr_x4luDd37Owi8oUffzFoaZhjVCoUP4MjERN8zMSlAPm6GLYbxWWSsI_WZ-fix2gY6iHfWeHskSIWz77yNx9pnxcPBfA6zpyU8_Q5tJ3j3G6Vv4TLEikFV8FqsLI0WqAWYw%`
```

The command consists of multiple parts in order to make it easy to get the token, which will be explained in the end of the post.

![Kubernetes dashboard displaying cluster metrics, workloads, and resource usage in a user-friendly interface.](https://cdn-images-1.medium.com/max/1600/1*YhinaiSE_-f5L9qirqT65A.png)

Sign in

![A dashboard displaying various data types, including charts, graphs, and metrics for analysis and decision-making.](https://cdn-images-1.medium.com/max/1600/1*Cewl4uR4rOeabli-zfN7NA.png)

Dashboard overview

Now the dashboard is able to perform requests without filling your screen with permission errors. For a local cluster cluster-admin is fine, I would though consider using the more restricted roles for other use cases. The *edit*role seems to have most of what the dashboard needs from my poking around.

 

## Command explanation

The token is located in a secret that belongs to a service account. Furthermore, it is encoded as base64, which is how Kubernetes does with secrets.

The first command finds the ***secretname*** of the secret by printing its name from the service account’s jsonpath. This is substituted in the full command.

```
`$ kubectl get serviceaccount dashboard -o jsonpath="{.secrets[0].name}"`
```

The outer command prints the base64 token using its jsonpath in the secret.

```
`$ kubectl get secret secretname -o jsonpath="{.data.token}"`
```

The last part pipes the base64 encoded token into a decoder that outputs the token.

```
`... | base64 --decode`
```

This article originated from [http://kubecloud.io/kubernetes-dashboard-on-arm-with-rbac-61309310a640](http://kubecloud.io/kubernetes-dashboard-on-arm-with-rbac-61309310a640)

Martin Jensen is a Tigera guest blogger and is a Web Architect at Lunar Way.

————————————————-

[**Free Online Training**](https://www.tigera.io/events/)

Access Live and On-Demand Kubernetes Tutorials

[**Calico Enterprise – Free Trial**](https://www.calicocloud.io/home)

Solve Common Kubernetes Roadblocks and Advance Your Enterprise Adoption

[How-To](https://www.tigera.io/tags/how-to/)[Open Source](https://www.tigera.io/tags/open-source/)

## Related posts

[![From Merged PR to Governed Pod: Automating AI Agent Deployment on Kubernetes](https://www.tigera.io/app/uploads/2026/10/From-Merged-PR-to-Governed-Pod-featured.png)](https://www.tigera.io/blog/from-merged-pr-to-governed-pod-automating-ai-agent-deployment-on-kubernetes/)

#### [From Merged PR to Governed Pod: Automating AI Agent Deployment on Kubernetes](https://www.tigera.io/blog/from-merged-pr-to-governed-pod-automating-ai-agent-deployment-on-kubernetes/)

By [Alister Baroi](https://www.tigera.io/blog/author/alister-baroi/)
on Oct 13, 2026

In short, automating the AI agent lifecycle is this year’s pitch: Google Cloud’s walkthrough of 30th July 2026 turns the whole thing into a conversation with a coding agent. On Kubernetes the deploy half of...

[Read more](https://www.tigera.io/blog/from-merged-pr-to-governed-pod-automating-ai-agent-deployment-on-kubernetes/)

[![Save the Address, Save the Cloud: A Hands-on KubeVirt Live Migration Workshop](https://www.tigera.io/app/uploads/2026/07/Save-the-Address-Save-the-Cloud-A-Hands-on-KubeVirt-Live-Migration-Workshop.png)](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

#### [Save the Address, Save the Cloud: A Hands-on KubeVirt Live Migration Workshop](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

By [Reza Ramezanpour](https://www.tigera.io/blog/author/rezar/)
on Jul 9, 2026

In the previous post in this series, we covered why Virtual Machine (VM) Live Migration in Kubernetes is difficult: a VM’s IP is its identity, and the “new” VM on the destination node has to...

[Read more](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

[![What’s new in Calico: Spring 2026 Release](https://www.tigera.io/app/uploads/2026/06/Whats-New-in-Calico-NEW-TEMPLATE-2026.png)](https://www.tigera.io/blog/whats-new-in-calico-spring-2026-release/)

[Company Blog](https://www.tigera.io/category/company-blog/)

#### [What’s new in Calico: Spring 2026 Release](https://www.tigera.io/blog/whats-new-in-calico-spring-2026-release/)

By [Veronika Smolik](https://www.tigera.io/blog/author/veronika-smolik/)
on Jun 2, 2026

Kubernetes has come a long way since its debut in 2014. It’s gone from running a couple of containerized microservices to orchestrating fleets of production workloads spanning everything from AI agents to full scale VMs...

[Read more](https://www.tigera.io/blog/whats-new-in-calico-spring-2026-release/)

<!-- plugin=object-cache-pro client=phpredis metric#hits=6180 metric#misses=17 metric#hit-ratio=99.7 metric#bytes=2262718 metric#prefetches=0 metric#store-reads=411 metric#store-writes=15 metric#store-hits=424 metric#store-misses=6 metric#sql-queries=32 metric#ms-total=1131.57 metric#ms-cache=65.75 metric#ms-cache-avg=0.1547 metric#ms-cache-ratio=5.8 sample#redis-hits=89638661 sample#redis-misses=9527733 sample#redis-hit-ratio=90.4 sample#redis-ops-per-sec=213 sample#redis-evicted-keys=0 sample#redis-used-memory=120818112 sample#redis-used-memory-rss=100139008 sample#redis-memory-fragmentation-ratio=0.8 sample#redis-connected-clients=1 sample#redis-tracking-clients=0 sample#redis-rejected-connections=0 sample#redis-keys=45991 -->
