Install Kubernetes Dashboard

Lars Jönsson 2022-12-05

Instructions of how to install the Dashboard on a running Kubernetes cluster. It is based on the recommended setup in the Kubernetes Dashboard README file.

Preparations

Certificates

Create private key and certificate that can be used when accessing the Dashboard. It is assumed that they are available at $HOME/certs and named dashboard.key resp. dashboard.crt.

More information about how to create the certificate is described here.

YAML definition

For Dashboard to pickup the certificates, you must pass arguments --tls-cert-file=/dashboard.crt and --tls-key-file=/dashboard.key to the container. First download the file.

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

Under Deployment section, add arguments to pod definition, it should look as follows:

containers:
  ...
  args:
    - --tls-cert-file=/dashboard.crt
    - --tls-key-file=/dashboard.key
    - --auto-generate-certificates

--auto-generate-certificates can be left in place, and will be used as a fallback.

Installation

Create the namespace for the Dashboard and install the secret (key and certificate):

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

Install the Dashboard:

kubectl apply -f recommended.yaml 

The Dashboard is available as a NodePort. This way of accessing Dashboard is only recommended for development environments in a single node setup.

Edit kubernetes-dashboard service:

kubectl -n kubernetes-dashboard edit service kubernetes-dashboard

You should see yaml representation of the service. Change type: ClusterIP to type: NodePort and save file.

  sessionAffinity: None
  type: NodePort

Next we need to check port on which Dashboard was exposed.

kubectl -n kubernetes-dashboard get service kubernetes-dashboard
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   NodePort   10.103.10.241   <none>        443:31262/TCP   4m3s

Dashboard has been exposed on port 31262 (HTTPS). Now you can access it from your browser at: https://<master-ip>:31262. master-ip can be found by executing kubectl cluster-info.

Dashboard user

An admin user is needed when accessing the Dashboard. It is created using the Service Account mechanism of Kubernetes and granting this user admin permissions. A bearer token tied to the user is used for login to the Dashboard.

IMPORTANT Make sure that you know what you are doing before proceeding. Granting admin privileges to Dashboard's Service Account might be a security risk.

Creating the user

Create a dashboard-adminuser.yaml file with the following content:

# Admin user for the Dashboard

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

---

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

Create the admin user:

kubectl apply -f dashboard-adminuser.yaml

Getting the bearer token

Now we need to find the token we can use to log in. Execute the following command:

kubectl -n kubernetes-dashboard create token admin-user

It should print something like:

eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXY1N253Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIwMzAzMjQzYy00MDQwLTRhNTgtOGE0Ny04NDllZTliYTc5YzEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.Z2JrQlitASVwWbc-s6deLRFVk5DWD3P_vjUFXsqVSY10pbjFLG4njoZwh8p3tLxnX_VBsr7_6bwxhWSYChp9hwxznemD5x5HLtjb16kI9Z7yFWLtohzkTwuFbqmQaMoget_nYcQBUC5fDmBHRfFvNKePh_vSSb2h_aYXa8GV5AcfPQpY7r461itme1EXHQJqv-SN-zUnguDguCTjD80pFZ_CmnSE1z9QdMHPB8hoB4V68gtswR1VLa6mSYdgPwCHauuOobojALSaMc3RH7MmFUumAgguhqAkX3Omqd3rJbYOMRuMjhANqd08piDC3aIabINX6gP5-Tuuw2svnV6NYQ

The token can be copied and pasted into Enter token field on the login screen. The default lifetime of the token is 1 hour. It can be changed by using the --duration option. The maximum value is 48 hours.

Create a long-lived API token

NOTE This should only be used in a controlled lab environment

Somtimes it is preferred to use long-lived tokens for Dashboard access. To obtain an API token for the admin-user service account, you create a new secret with a special annotation, kubernetes.io/service-account.name.

Create a dashboard-token.yaml file with the following content:

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

Create the token:

kubectl apply -f dashboard-token.yaml

View the token by using:

kubectl describe -n kubernetes-dashboard secrets admin-user-secret

The output is similar to this:

Name:         admin-user-secret
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: b0b289c5-31d8-4a22-8abb-5655436c4ade

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  20 bytes
token:      ...

The token can be copied and pasted into Enter token field on the login screen.

NOTE The content of token is elided here.

When you delete a service account that has an associated secret, the Kubernetes control plane automatically cleans up the long-lived token from that secret.