Kubernetes Dashboard: A Complete Guide
Installing the Dashboard via Helm
We opted for Helm because it makes managing the lifecycle of the dashboard much easier than raw YAML manifests.
$ helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
$ helm repo update
$ helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
$ kubectl get all -n kubernetes-dashboardOnce the pods and services are in a Running state, the dashboard is live, but you still need a way to authenticate.
RBAC and Access Control
The Dashboard doesn't have its own user database; it relies on Kubernetes ServiceAccounts and bearer tokens. In our setup, we created two distinct levels of access to prevent accidental deletions in production.
1. Admin Access
For the lead engineers who need full control, we use a cluster-admin binding.
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboard-admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin-user
namespace: kubernetes-dashboardApply this and generate the token:
$ kubectl apply -f dashboard-admin-user.yml
$ kubectl -n kubernetes-dashboard create token dashboard-admin-user2. Read-Only Access
For the rest of the team or stakeholders who only need to monitor health, a scoped role is safer.
apiVersion: v1
kind: ServiceAccount
metadata:
name: read-only-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: read-only-clusterrole
rules:
- apiGroups: ["", "apps", "extensions"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-only-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: read-only-clusterrole
subjects:
- kind: ServiceAccount
name: read-only-user
namespace: kubernetes-dashboardApply and generate the token:
$ kubectl apply -f read-only-user.yml
$ kubectl -n kubernetes-dashboard create token read-only-userConnecting to the UI
For quick local checks, port-forwarding is the fastest route. If you are accessing this from a remote workstation, you'll need to bind to all interfaces and open your firewall.
# Open the port in the OS firewall
$ sudo ufw allow 8443/tcp
$ sudo ufw reload
# Forward the service to 0.0.0.0 to allow external access
$ kubectl port-forward service/kubernetes-dashboard-kong-proxy 8443:443 -n kubernetes-dashboard --address='0.0.0.0'You can then hit https://<your-node-ip>:8443. You'll get a certificate warning because it's self-signed—just bypass it and paste your token.
Moving to Production: Ingress and TLS
Port-forwarding is too fragile for a team environment. We moved the dashboard behind an Nginx Ingress controller with cert-manager to handle automated Let's Encrypt certificates.
Step 1: Deploy Nginx Ingress
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
$ helm repo update
$ helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespaceStep 2: Deploy cert-manager
This ensures our HTTPS traffic is actually valid and not just "accepted" by the browser.
$ helm repo add jetstack https://charts.jetstack.io
$ helm repo update
$ helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=trueBy moving to this AI workflow for cluster management, our team spent less time fighting with kubectl get pods -w and more time actually optimizing our deployments. It's a straightforward deployment, but the RBAC configuration is where most people trip up—keep those admin tokens secure.