ENGINEERING NOTES / KUBERNETES

Migrate Off the Kubernetes Dashboard: A Step-by-Step Guide

How to replace the archived Kubernetes Dashboard without losing access or leaving cluster-admin bindings behind: inventory, install Headlamp or Berth beside it, verify, remove, and clean up.

Migrate Off the Kubernetes Dashboard: A Step-by-Step Guide

The Kubernetes Dashboard is archived, so a cluster that still runs it is running a web UI that will not get security fixes. Moving off it is a small job if you do it in the right order: find out what the Dashboard can do, run the replacement beside it, check the replacement works for your team, and only then remove the old one and its leftovers.

This guide uses Headlamp, the project the Kubernetes Dashboard repository recommends, and shows where Berth fits for single-cluster teams. We make Berth, and the comparison says which is the better fit for which team. Commands were checked against each project’s documentation on 5 October 2026.

Before you start

Pick the replacement first. The decision list has the short version: Headlamp if you need multi-cluster views, SSO or per-user permissions, Berth if you run one cluster and mostly troubleshoot endpoints and capacity.

Also decide who needs access. The Dashboard login is a bearer token, so “who has access” in practice means “who holds a token.” Write that list down, because the replacement should give each person only what they need.

Step 1: Inventory what is installed and what it can do

Find the release and how it is exposed:

helm list -A | grep -i dashboard
kubectl get httproute,ingress,svc -A | grep -i dashboard

Save the release’s values now, so you can recreate it if you need to roll back:

helm get values kubernetes-dashboard -n kubernetes-dashboard > dashboard-values.yaml

(kubernetes-dashboard is the release and namespace name in the project’s own installation instructions. Yours may differ.)

Then look at what the Dashboard’s accounts can do:

kubectl get serviceaccounts -n kubernetes-dashboard
kubectl get clusterrolebindings -o wide | grep -i -E "dashboard|admin-user"

Pay particular attention to a binding called admin-user. The Dashboard’s own “creating a sample user” guide creates a service account with that name and binds it to the cluster-admin role, and that guide has been copied into countless runbooks. If your cluster has it, anyone holding a token for that account has full control of the cluster, and it will still be there after you uninstall the Dashboard unless you remove it yourself.

Step 2: Install the replacement beside the Dashboard

Do not remove anything yet. Running both lets you compare behaviour.

Option A: Headlamp. From Headlamp’s in-cluster documentation:

helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/
helm install my-headlamp headlamp/headlamp --namespace kube-system

Headlamp’s documentation says that once it is running you enable access by creating a service account or by setting up OIDC. Its example creates a service account and binds it to cluster-admin, with a tip to check the RBAC documentation for more restrictive permissions. Take the tip. A reasonable starting point is the built-in view role, adding permissions only when someone needs them:

kubectl -n kube-system create serviceaccount headlamp-viewer
kubectl create clusterrolebinding headlamp-viewer \
  --serviceaccount=kube-system:headlamp-viewer --clusterrole=view
kubectl create token headlamp-viewer -n kube-system

For a team, OIDC is the better answer, because it ties access to people instead of to a shared token. Headlamp’s installation documentation has tutorials for Dex, Keycloak, Cognito and Entra ID.

Option B: Berth. From Berth’s installation instructions:

helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth \
  --namespace berth --create-namespace
kubectl -n berth get secret berth-secrets -o jsonpath='{.data.AUTH_TOKEN}' | base64 -d ; echo
kubectl -n berth port-forward svc/berth 8081:8081

Berth is single-cluster and has no per-user permissions: everyone who signs in shares the permissions of the account Berth runs as. That is the right trade for a small team that already trusts everyone with the token, and the wrong one if you need to separate people.

Whichever you choose, keep it behind authentication and, if you expose it, behind TLS. A cluster UI is a cluster credential in a browser tab.

Step 3: Check the replacement does the jobs your team actually does

Open a short list of real tasks in the replacement while the Dashboard is still up:

  1. Find a pod that is crash looping and read its logs and events.
  2. See which workloads are running with a single replica.
  3. Check where a hostname’s traffic goes and whether its certificate is valid.
  4. Do the one write operation your team uses most (for example a rollout restart), with the role you gave it.

If a task works in the Dashboard and not in the replacement, find out whether it is a missing permission or a missing feature before you decide. A missing permission is a one-line fix. A missing feature is a reason to pick a different tool.

Step 4: Remove the Dashboard

Once the replacement covers the tasks, take the Dashboard out. If it was exposed through a route or ingress, remove that first so no public path stays open while you work:

kubectl delete httproute <name> -n <namespace>     # or the ingress, as it applies to you
helm uninstall kubernetes-dashboard -n kubernetes-dashboard
kubectl delete namespace kubernetes-dashboard

That removes the Dashboard and the Kong gateway that its chart installed with it. It does not remove cluster-scoped objects that were created outside the chart, so check the bindings you found in step 1:

kubectl get clusterrolebinding admin-user -o yaml

Read the output before you delete anything. If it is the sample binding (service account admin-user in the kubernetes-dashboard namespace, role cluster-admin), delete it:

kubectl delete clusterrolebinding admin-user

Do not delete a binding with that name that you did not create for the Dashboard.

Step 5: Clean up the places that still point at the old tool

  • Remove the Helm repository from your machines, CI and runbooks: helm repo remove kubernetes-dashboard. The old URL, https://kubernetes.github.io/dashboard/, now returns a 404, and the archived project’s own README still tells readers to add it.
  • Search your documentation for kubernetes-dashboard, kong-proxy and the sample-user commands, and replace them.
  • Rotate or discard tokens that were issued for the Dashboard, and make sure nobody saved one in a password manager under a name nobody will recognise next year.
  • Update your onboarding notes so new engineers install the replacement, not the tool the old tutorial describes.

If something goes wrong

Because you saved the release values in step 1, you can put the Dashboard back while you sort things out. Until the replacement is trusted, treat that as temporary: the retired chart repository at https://kubernetes-retired.github.io/dashboard/ still serves the chart, but the project will not fix vulnerabilities in it.

Sources

Read on 21 October 2026: the archived Kubernetes Dashboard README and its “creating a sample user” and “accessing the dashboard” documentation; Headlamp’s in-cluster and installation documentation; Berth’s installation instructions. Each command comes from those documents or is a standard kubectl and helm command. Your cluster’s names and layout will differ, so read each command before you run it, and try the sequence on a non-production cluster first. If a step does not match what you see, tell us and we will correct it.

We checked every command in this guide against the current documentation of each project on 21 October 2026. We did not run them on a cluster for this update, so run them on a disposable cluster first, and tell us if one has drifted.

SEE IT ON YOUR OWN CLUSTER

Berth: a Kubernetes dashboard
you run yourself.

Endpoint health, capacity planning, and a read-only AI SRE. Free for small clusters, license checked offline. Discuss your Kubernetes security and architecture with CloudGuys.

Get a free Community key ↗ Talk to CloudGuys ↗
Prefer a text version?Read this page as Markdown · All pages