How to Set Up a Kubernetes Dashboard on RHEL 7

The Kubernetes Dashboard is a web-based UI that provides a graphical interface for managing cluster resources, viewing workload status, inspecting pod logs, executing commands inside containers, and monitoring resource utilisation. While kubectl provides full cluster control from the command line, the Dashboard is invaluable for operators who prefer a visual overview, for team members less familiar with CLI tools, and for quickly diagnosing issues without constructing complex kubectl commands. This tutorial covers deploying the Kubernetes Dashboard on a RHEL 7 cluster, creating the necessary RBAC resources, retrieving a login token, accessing the Dashboard via kubectl proxy, and optionally exposing it through an Ingress controller for external access.

Prerequisites

  • RHEL 7 Kubernetes cluster (kubeadm-provisioned or equivalent) with at least one worker node
  • kubectl installed and configured with admin kubeconfig (~/.kube/config)
  • Cluster DNS and CoreDNS functioning correctly
  • Internet access to pull Dashboard images, or images available in a local registry
  • Optional: an Ingress controller (nginx-ingress) for external exposure
  • Optional: Metrics Server deployed for CPU/memory display in the Dashboard

Verify your cluster is healthy before proceeding:

kubectl cluster-info
kubectl get nodes
kubectl get pods --all-namespaces

Step 1: Deploying the Kubernetes Dashboard

The recommended installation method is to apply the official Dashboard manifest. Check the Kubernetes Dashboard releases page for the version compatible with your cluster version. For Kubernetes 1.20–1.24 clusters commonly found on RHEL 7:

# Download the manifest (version 2.7.0 — adjust for your cluster version)
curl -LO https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

# Review the manifest before applying
grep -E "image:|namespace:|kind:" recommended.yaml

# Apply to the cluster
kubectl apply -f recommended.yaml

This creates the kubernetes-dashboard namespace and deploys two main components: the Dashboard deployment itself and the metrics-scraper sidecar. Verify the pods start successfully:

kubectl get pods -n kubernetes-dashboard
kubectl get services -n kubernetes-dashboard

# Wait for pods to be Running
kubectl wait --for=condition=Ready pod 
  -l k8s-app=kubernetes-dashboard 
  -n kubernetes-dashboard 
  --timeout=120s

Step 2: Creating a ServiceAccount for Dashboard Access

The Dashboard requires a Kubernetes ServiceAccount to authenticate users. Create a dedicated admin ServiceAccount in the kubernetes-dashboard namespace:

cat > /tmp/dashboard-adminuser.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF

kubectl apply -f /tmp/dashboard-adminuser.yaml
kubectl get serviceaccount admin-user -n kubernetes-dashboard

Step 3: Creating a ClusterRoleBinding

Grant the ServiceAccount cluster-admin privileges by binding it to the built-in cluster-admin ClusterRole. This provides full read and write access to all resources — appropriate for a trusted admin account, but should be scoped more narrowly for regular users:

cat > /tmp/dashboard-clusterrolebinding.yaml <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF

kubectl apply -f /tmp/dashboard-clusterrolebinding.yaml
kubectl get clusterrolebinding admin-user

For a read-only Dashboard account, bind to the view ClusterRole instead of cluster-admin:

cat > /tmp/dashboard-readonly.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: readonly-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: readonly-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: ServiceAccount
  name: readonly-user
  namespace: kubernetes-dashboard
EOF

kubectl apply -f /tmp/dashboard-readonly.yaml

Step 4: Retrieving the Login Token

The Dashboard uses Bearer token authentication. Retrieve the token for the admin-user ServiceAccount:

# Kubernetes 1.23 and earlier: token is auto-generated in a Secret
kubectl -n kubernetes-dashboard get secret

# Find the secret name for admin-user
SECRET_NAME=$(kubectl -n kubernetes-dashboard get sa admin-user 
  -o jsonpath='{.secrets[0].name}')

# Retrieve and decode the token
kubectl -n kubernetes-dashboard get secret ${SECRET_NAME} 
  -o jsonpath='{.data.token}' | base64 --decode
echo ""

For Kubernetes 1.24 and later (where Secrets are no longer auto-created for ServiceAccounts), create a token explicitly:

# Kubernetes 1.24+: create a long-lived token Secret
cat > /tmp/admin-user-token.yaml <<'EOF'
apiVersion: v1
kind: Secret
metadata:
  name: admin-user-token
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token
EOF

kubectl apply -f /tmp/admin-user-token.yaml

# Wait for the token to be populated
sleep 5
kubectl -n kubernetes-dashboard get secret admin-user-token 
  -o jsonpath='{.data.token}' | base64 --decode
echo ""

Copy the token output — you will paste it into the Dashboard login screen.

Step 5: Accessing the Dashboard via kubectl proxy

The simplest and most secure way to access the Dashboard on RHEL 7 is via kubectl proxy, which creates an authenticated tunnel from your local machine to the API server. The Dashboard is never directly exposed to the network:

# Start the proxy (binds to localhost:8001 by default)
kubectl proxy &

# Access URL (open in a browser on the same machine)
echo "Dashboard URL:"
echo "http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/"

When the browser opens the Dashboard, select the Token authentication method and paste the token retrieved in Step 4. If running on a remote RHEL 7 server without a local browser, use SSH port forwarding:

# On your local workstation, forward the proxy port over SSH
ssh -L 8001:localhost:8001 [email protected] 
  "kubectl proxy"
# Then open http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ locally

Step 6: Exposing the Dashboard via Ingress (Optional)

For team access without relying on kubectl proxy, expose the Dashboard through an Ingress controller. Ensure nginx-ingress is deployed in your cluster first:

# First, change the Dashboard service to ClusterIP (it defaults to ClusterIP already)
kubectl get svc kubernetes-dashboard -n kubernetes-dashboard

# Create an Ingress resource for the Dashboard
cat > /tmp/dashboard-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: dashboard.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443
EOF

kubectl apply -f /tmp/dashboard-ingress.yaml
kubectl get ingress -n kubernetes-dashboard

Add the Ingress controller’s IP to your DNS or /etc/hosts on client machines:

INGRESS_IP=$(kubectl get svc ingress-nginx-controller 
  -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "${INGRESS_IP}  dashboard.example.com" | sudo tee -a /etc/hosts

Step 7: Installing Metrics Server for Dashboard Metrics

The Dashboard can display CPU and memory usage graphs, but only if the Metrics Server is deployed in the cluster. Install it on RHEL 7:

curl -LO https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# On RHEL 7 clusters with self-signed API server certs, add the insecure-tls arg
sed -i 's/- --metric-resolution=15s/- --metric-resolution=15sn        - --kubelet-insecure-tls/' components.yaml

kubectl apply -f components.yaml

# Verify it is working
kubectl top nodes
kubectl top pods --all-namespaces

Once Metrics Server is running, refresh the Dashboard and CPU/memory sparklines will appear on the Nodes, Pods, and Workloads overview pages.

Step 8: Exploring Dashboard Features

Once logged in, the Dashboard provides the following capabilities:

  • Workloads overview: View Deployments, ReplicaSets, StatefulSets, DaemonSets, and Jobs with real-time pod status
  • Pod logs: Stream or download logs from any container without kubectl logs
  • Exec into pods: Open an interactive shell in any running container directly from the browser
  • Resource editing: Edit Deployment replicas, ConfigMaps, and other resources inline via the UI
  • Namespace filtering: Switch between namespaces or view all namespaces at once
  • Events stream: View cluster events to diagnose scheduling failures and container crashes
# Useful kubectl commands to correlate with Dashboard views
kubectl get events --sort-by='.lastTimestamp' -A | tail -20
kubectl describe pod <podname> -n <namespace>
kubectl logs <podname> -n <namespace> --previous

Step 9: Securing the Dashboard with RBAC Namespaced Roles

For multi-tenant clusters, avoid giving developers cluster-admin access to the Dashboard. Create namespace-scoped RoleBindings instead:

cat > /tmp/dashboard-dev-role.yaml <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev-user
  namespace: development
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-user-binding
  namespace: development
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: edit
subjects:
- kind: ServiceAccount
  name: dev-user
  namespace: development
EOF

kubectl apply -f /tmp/dashboard-dev-role.yaml

# Get the dev-user token
kubectl -n development create token dev-user --duration=24h

The dev-user token will only allow Dashboard access to resources within the development namespace — cluster-level views will show “Forbidden” for resources outside the bound namespace.

Conclusion

The Kubernetes Dashboard provides a powerful visual management interface that complements the kubectl command line on RHEL 7 clusters. By following this tutorial you have deployed the Dashboard, created a properly RBAC-scoped ServiceAccount, retrieved a login token, and set up access via both the secure kubectl proxy method and an Ingress for team-wide access. The addition of Metrics Server unlocks real-time resource monitoring within the Dashboard, completing a robust observability setup. Always follow the principle of least privilege when creating Dashboard users — issue scoped tokens to developers and reserve the cluster-admin token for infrastructure administrators only. Tokens should be treated as credentials and rotated periodically to maintain cluster security on Red Hat Enterprise Linux 7.