Kubernetes Dashboard Installation

The Kubernetes Dashboard is the official web-based user interface for Kubernetes cluster management. This guide covers deploying the dashboard, creating admin users and service accounts, authenticating with tokens, implementing RBAC, and securing access via proxy or ingress on your VPS and baremetal Kubernetes infrastructure.

Table of Contents

Dashboard Overview

What is Kubernetes Dashboard?

The Kubernetes Dashboard is:

  • Official Kubernetes web UI
  • Built-in management interface
  • Container and pod management
  • Resource monitoring
  • Logs and event viewing

Features

  • Cluster overview
  • Pod and deployment management
  • Service and ingress configuration
  • Node and resource monitoring
  • Log viewing
  • Resource creation via UI

Kubernetes Versions

Dashboard version compatibility varies. Latest versions support:

  • Kubernetes 1.20+
  • Recommended versions track closely with Kubernetes releases

Installation Methods

Official Helm Chart Installation

# Add Helm repository
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm repo update

# Install Dashboard
helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
  -n kubernetes-dashboard \
  --create-namespace

Manual kubectl Deployment

Install from official manifest:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

Verify Installation

# Check dashboard pods
kubectl get pods -n kubernetes-dashboard

# Check services
kubectl get svc -n kubernetes-dashboard

Custom Installation with Values

# dashboard-values.yaml
replicaCount: 2

image:
  repository: kubernetesui/dashboard
  tag: v2.7.0
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 443
  targetPort: 8443

ingress:
  enabled: true
  ingressClassName: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
  - dashboard.example.com
  tls:
  - secretName: dashboard-tls
    hosts:
    - dashboard.example.com

resources:
  limits:
    cpu: 200m
    memory: 256Mi
  requests:
    cpu: 100m
    memory: 128Mi

Install with custom values:

helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard \
  -n kubernetes-dashboard \
  --create-namespace \
  -f dashboard-values.yaml

User Authentication

Creating Admin User

Create service account for dashboard admin:

# Create service account
kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard

# Create cluster role binding
kubectl create clusterrolebinding dashboard-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=kubernetes-dashboard:dashboard-admin

Getting Access Token

# Get token for admin user
kubectl -n kubernetes-dashboard create token dashboard-admin

# Or for long-lived token (v1.20 and earlier):
kubectl -n kubernetes-dashboard get secret \
  $(kubectl -n kubernetes-dashboard get secret | grep dashboard-admin-token | awk '{print $1}') \
  -o jsonpath='{.data.token}' | base64 --decode

Creating Limited User

For read-only access:

# Create service account
kubectl create serviceaccount dashboard-viewer -n kubernetes-dashboard

# Create cluster role for view-only access
kubectl create clusterrole dashboard-viewer \
  --verb=get,list,watch \
  --resource=pods,services,deployments

# Bind role to service account
kubectl create clusterrolebinding dashboard-viewer \
  --clusterrole=dashboard-viewer \
  --serviceaccount=kubernetes-dashboard:dashboard-viewer

# Get token
kubectl -n kubernetes-dashboard create token dashboard-viewer

Namespace-Scoped Access

For access to specific namespace only:

# Create service account in specific namespace
kubectl create serviceaccount dashboard-user -n production

# Create role for the namespace
kubectl create role dashboard-user \
  --verb=get,list,watch \
  --resource=pods,services,deployments \
  -n production

# Bind role to service account
kubectl create rolebinding dashboard-user \
  --role=dashboard-user \
  --serviceaccount=production:dashboard-user \
  -n production

# Get token
kubectl -n production create token dashboard-user

RBAC Configuration

Dashboard Admin Role

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dashboard-admin
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["batch"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["networking.k8s.io"]
  resources: ["*"]
  verbs: ["*"]

Bind role:

kubectl create clusterrolebinding dashboard-admin-binding \
  --clusterrole=dashboard-admin \
  --serviceaccount=kubernetes-dashboard:dashboard-admin

Read-Only Role

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dashboard-readonly
rules:
- apiGroups: [""]
  resources:
  - configmaps
  - endpoints
  - persistentvolumeclaims
  - persistentvolumes
  - pods
  - replicationcontrollers
  - replicationcontrollers/scale
  - services
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources:
  - daemonsets
  - deployments
  - deployments/scale
  - replicasets
  - replicasets/scale
  - statefulsets
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  resources:
  - cronjobs
  - jobs
  verbs: ["get", "list", "watch"]

Secure Access

Port Forwarding

# Forward local port to dashboard
kubectl port-forward -n kubernetes-dashboard svc/kubernetes-dashboard 8443:443

# Access: https://localhost:8443
# Accept self-signed certificate warning

Kubectl Proxy

# Start proxy
kubectl proxy

# Access dashboard:
# http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

Ingress with TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dashboard
  namespace: kubernetes-dashboard
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - dashboard.example.com
    secretName: dashboard-tls
  rules:
  - host: dashboard.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443

Apply ingress:

kubectl apply -f ingress.yaml

OIDC Authentication

Configure OIDC for external authentication (requires additional setup):

# Requires Kubernetes API server configuration
# Add to kube-apiserver:
# - --oidc-issuer-url=https://auth.example.com
# - --oidc-client-id=kubernetes
# - --oidc-username-claim=email
# - --oidc-groups-claim=groups

Dashboard Usage

Accessing Dashboard

# Get accessible URL
kubectl port-forward -n kubernetes-dashboard svc/kubernetes-dashboard 8443:443 &

# Or via proxy
kubectl proxy &

echo "Dashboard URL:"
echo "https://localhost:8443"
echo "or"
echo "http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/"

Logging In

  1. Open dashboard URL
  2. Select "Token" authentication
  3. Paste token from kubectl command
  4. Click "Sign in"

Common Dashboard Tasks

View Cluster Overview:

  • Cluster → Nodes: View node status and resources
  • Cluster → Namespaces: View all namespaces

Manage Workloads:

  • Workloads → Pods: Create, view, delete pods
  • Workloads → Deployments: Manage deployments
  • Workloads → StatefulSets: Manage stateful applications
  • Workloads → Jobs: View batch jobs

Configure Storage:

  • Storage → PersistentVolumes: View available volumes
  • Storage → PersistentVolumeClaims: Create and manage claims
  • Storage → StorageClasses: View storage options

View Logs:

  • Select pod → Logs tab
  • Filter containers and date range

Practical Examples

Example: Production Dashboard Setup

---
# Service account for admin
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard
---
# Admin role binding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: dashboard-admin
  namespace: kubernetes-dashboard
---
# Viewer service account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-viewer
  namespace: kubernetes-dashboard
---
# Viewer role
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dashboard-viewer
rules:
- apiGroups: [""]
  resources: ["pods", "nodes", "namespaces", "services"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets", "daemonsets"]
  verbs: ["get", "list", "watch"]
---
# Bind viewer role
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: dashboard-viewer
subjects:
- kind: ServiceAccount
  name: dashboard-viewer
  namespace: kubernetes-dashboard
---
# Ingress for HTTPS access
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dashboard
  namespace: kubernetes-dashboard
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - dashboard.example.com
    secretName: dashboard-tls
  rules:
  - host: dashboard.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443

Example: Token Rotation Script

#!/bin/bash

NAMESPACE="kubernetes-dashboard"
SERVICE_ACCOUNT="dashboard-admin"

echo "=== Dashboard Admin Token ==="
kubectl -n $NAMESPACE create token $SERVICE_ACCOUNT

echo ""
echo "=== Token Valid For ==="
kubectl -n $NAMESPACE describe token $SERVICE_ACCOUNT 2>/dev/null || echo "Use: kubectl -n $NAMESPACE create token $SERVICE_ACCOUNT"

echo ""
echo "=== Access Dashboard ==="
echo "1. Port forward: kubectl port-forward -n kubernetes-dashboard svc/kubernetes-dashboard 8443:443"
echo "2. Access: https://localhost:8443"
echo "3. Paste token above in authentication dialog"

Conclusion

The Kubernetes Dashboard provides an accessible web interface for managing Kubernetes clusters. By properly securing it with RBAC, using strong authentication, and deploying it behind TLS-encrypted ingress, you create a user-friendly management interface for your VPS and baremetal infrastructure. Start with admin access for setup and testing, then create role-based accounts for team members. Combine dashboard access with kubectl-based automation for a complete Kubernetes management strategy. Remember that dashboard access should be carefully controlled and monitored for production environments.