How to deploy Kubernetes Dashboard for Public Access

Damian Igbe,Phd
July 29, 2022, 1:21 a.m.

Subscribe to Newsletter

Be first to know about new blogs, training offers, and company news.

Kubernetes dashboard is useful for managing Kubernetes from a Graphical interface. However you require proper certificates to able to install and use it from the internet. In this blog, you learn how to deploy a Kubernetes dashboard for public access through the internet using NodePort service. You will deploy the Kubernetes Dashboard so that it is accessible from a NodePort (i.e. a port exposed from your Kubernetes hosts). 

Note that you must have a working kubernetes cluster like the one deployed here with kubeadm. You can use it to deploy a working kubernetes cluster

Here are the steps:

Step 1: Create self signed Certificates

You need a dashboard.key and dashboard.crt files for HTTPS. Here we create self-signed certificates. Replace ’ localhost’ with the name of the master node.

mkdir $HOME/certs
cd $HOME/certs
openssl genrsa -out dashboard.key 2048
openssl rsa -in dashboard.key -out dashboard.key
openssl req -sha256 -new -key dashboard.key -out dashboard.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in dashboard.csr -signkey dashboard.key -out dashboard.crt

Next, load the certificates into a secret:

kubectl -n kube-system create secret generic kubernetes-dashboard-certs --from- file=$HOME/certs

Step 2: Deploy dashboard

The following will deploy the kubernetes-dashboard service account, role, rolebinding, deployment and service. 

kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml

3: Check if the replica set is properly created Find the dashboard replica set:

kubectl -n kubernetes-dashboard get rs

If the desired, current and ready counts are all 1, then congratulations!

Step 4.1: Create a Pod Security Policy

A permissive example but blocking privileged mode:
Put the following in a file (psp.yaml) and create with kubectl create -f psp.yaml

apiVersion: policy/v1beta1 
kind: PodSecurityPolicy
  name: dashboard
  privileged: false
    rule: RunAsAny
    rule: RunAsAny
    rule: RunAsAny
    rule: RunAsAny
  - '*'

Step 4.2 Create a role to allow use of the PSP

kubectl -n kubernetes-dashboard create role psp:dashboard --verb=use --resource=podsecuritypolicy --resource-name=dashboard

Step 4.3: Bind the role to kubernetes-dashboard service account

kubectl -n kubernetes-dashboard create rolebinding kubernetes-dashboard-policy --role=psp:dashboard --serviceaccount=kube-system:kubernetes-dashboard

Check that the output of the following command is yes:

kubectl --as=system:serviceaccount:kube-system:kubernetes-dashboard -n kubernetes-dashboard auth can-i use podsecuritypolicy/dashboard

After a while, check the status of your replica set and it should now have been able to create the pods!

Step 5: Expose dashboard service on a NodePort

Finally, we can expose the dashboard service on a NodePort. This will allow it to be publicly accessible via a port forwarded on the Kubernetes hosts.

Edit the kubernetes-dashboard service and change the following options:

  • spec.type from ClusterIP to NodePort
  • spec.ports[0].nodePort from 32641 to whatever port you want it to be exposed on kubectl -n kubernetes-dashboard edit service kubernetes-dashboard

When you save the close the text file, find out which port was allocated:

root@master-22-04:~/certs# kubectl -n kubernetes-dashboard get services

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   <none>        8000/TCP        51m
kubernetes-dashboard        NodePort    <none>        443:32641/TCP   51m

Here you can see that the dashboard was assigned port 32641.

Step 6: Create Service Account

Create ClusterRoleBinding

We are creating Service Account with name admin-user in namespace kube-dashboard first.


apiVersion: v1 
kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

In most cases after provisioning our cluster using kubeadm the ClusterRole admin-Role already exists in the cluster. We can use it and create only ClusterRoleBinding for our ServiceAccount.

NOTE: apiVersion of ClusterRoleBinding resource may differ between Kubernetes versions. Prior to Kubernetes v1.8 the apiVersion was rbac.authorization.k8s.io/v1

apiVersion: rbac.authorization.k8s.io/v1 
kind: ClusterRoleBinding
  name: admin-user
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

From Kubernetes 1.23, you need to create a secret when you create a service account unlike the earlier versions that has the secret and token created whenever you create a service  account. You  can verify that by running this command:

kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

So lets create it with this yaml file:

apiVersion: v1
kind: Secret
  name: admin-token
  namespace: kubernetes-dashboard
    kubernetes.io/service-account.name: admin-user
type: kubernetes.io/service-account-token


kubectl create -f secret.yaml
kubectl get secret -n kubernetes-dashboard
kubectl describe secret admin-token -n kubernetes-dashboard
Name:         admin-token
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: 565548de-0d15-485a-ad27-f87043b6823b
Type:  kubernetes.io/service-account-token
namespace:  20 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Im1XUU5zclFwQWxqZE4wRXRxVTBGNE9TU0ZNc3JaQ09vM1hIRl9aWjV3LVEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbi11c2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNTY1NTQ4ZGUtMGQxNS00ODVhLWFkMjctZjg3MDQzYjY4MjNiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmFkbWluLXVzZXIifQ.asG7VEWTpig47Kbzq7DNwEfnGVwpNr7aWfjtjS5Rp8NP8trI-6iD606sYMZy2D0Yu-VQxD86De81JvgLV7CE5i0ZSMs4O2QDtD0gtGPQDI-rZq0M_lvZmO_mB2CKgJhBd42vXjH8xWsZMo2D3RO_CO3TvWd5WqFc_JxxMXnzRKCO1u9TS_h4eU0h-Mf0u_pYjS0M7nOI5QtaTNTVRazefFZUcp0e-bbh0P47gvRXD2AatDqAy39uEK0OZUo7XdaZowFeil3aUcbip8vkAjTMS3XbusmUo-LlLGGpENOgK-Lt4pSk0WaFUZv8U5GIZhJrOZbsVdXk_qEqFg1e_Lzdlg
ca.crt:     1099 bytes

Now you can use this bearer token to login to the dashboard.

You can try to access the dashboard from mozilla firefox. Don't use chrome as it wont let you access a self-signed certificate. Replace the following with your Ip address.

You can now login with the bearer token obtained above.

Click Sign in button and that's it. You are now logged in as an admin.


If you have a Kubernetes cluster deployed, you can use the above instructions to deploy the dashboard.

Zero-to-Hero Program: We Train and Mentor you to land your first Tech role