{"id":2131,"date":"2020-08-24T19:32:35","date_gmt":"2020-08-24T16:32:35","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/deploy-kubernetes-dashboard\/"},"modified":"2020-08-24T19:32:35","modified_gmt":"2020-08-24T16:32:35","slug":"deploy-kubernetes-dashboard","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/deploy-kubernetes-dashboard\/","title":{"rendered":"How to deploy Kubernetes\u00ae Dashboard quickly and easily"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Kubernetes offers a convenient graphical user interface with <span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">its&nbsp;<a href=\"https:\/\/kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/\" target=\"_blank\" rel=\"noopener\">web dashboard,<\/a>&nbsp;which can be used to create, monitor,<\/span> and manage a cluster. The installation is quite straightforward, but it takes a few steps to set up everything in a convenient manner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In addition to deploying the dashboard, we\u2019ll go over how to set up both admin and read-only access to the dashboard. However, before we begin, we need to have a working Kubernetes cluster. You can <a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-kubernetes-cluster-centos-8\" target=\"_blank\" rel=\"noreferrer noopener\">get started with Kubernetes by following our earlier tutorial.<\/a><\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">1. Deploy the latest Kubernetes dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019ve set up your Kubernetes cluster, or if you already had one running, we can get started.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing to know about the web UI is that it can only be accessed using the localhost address on the machine it runs on.&nbsp;This means we need to have an SSH tunnel to the server. For most OS, you can create an SSH tunnel using this command. Replace the <tt style=\"color: #ff0000;\">&lt;user&gt;<\/tt> and <tt style=\"color: #ff0000;\">&lt;master_public_IP&gt;<\/tt> with the relevant details to your Kubernetes cluster.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssh -L localhost:8001:127.0.0.1:8001 <span style=\"color: #ff0000;\">&lt;user&gt;<\/span>@<span style=\"color: #ff0000;\">&lt;master_public_IP&gt;<\/span><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After you\u2019ve logged in, you can deploy the dashboard itself with the following single command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl apply -f https:\/\/raw.githubusercontent.com\/kubernetes\/dashboard\/v2.0.0\/aio\/deploy\/recommended.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If your cluster is working correctly, you should see an output confirming the creation of a bunch of Kubernetes components, as in the example below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">namespace\/kubernetes-dashboard created\nserviceaccount\/kubernetes-dashboard created\nservice\/kubernetes-dashboard created\nsecret\/kubernetes-dashboard-certs created\nsecret\/kubernetes-dashboard-csrf created\nsecret\/kubernetes-dashboard-key-holder created\nconfigmap\/kubernetes-dashboard-settings created\nrole.rbac.authorization.k8s.io\/kubernetes-dashboard created\nclusterrole.rbac.authorization.k8s.io\/kubernetes-dashboard created\nrolebinding.rbac.authorization.k8s.io\/kubernetes-dashboard created\nclusterrolebinding.rbac.authorization.k8s.io\/kubernetes-dashboard created\ndeployment.apps\/kubernetes-dashboard created\nservice\/dashboard-metrics-scraper created\ndeployment.apps\/dashboard-metrics-scraper created\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, you should have two new pods running on your cluster.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl get pods -A<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">...\nkubernetes-dashboard   dashboard-metrics-scraper-6b4884c9d5-v4z89   1\/1     Running   0          30m\nkubernetes-dashboard   kubernetes-dashboard-7b544877d5-m8jzk        1\/1     Running   0          30m\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can then continue ahead with creating the required user accounts.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud for free!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2. Creating Admin user<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Kubernetes dashboard supports several ways to manage access control. In this example, we\u2019ll create an admin user account with full privileges to modify the cluster and use tokens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start by making a new directory for the dashboard configuration files.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir ~\/dashboard &amp;&amp; cd ~\/dashboard<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create the following configuration and save it as <tt>dashboard-admin.yaml<\/tt> file. Note that indentation matters in the YAML files, which should use two spaces in a regular text editor.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nano dashboard-admin.yaml<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: admin-user\n  namespace: kubernetes-dashboard\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: admin-user\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: cluster-admin\nsubjects:\n- kind: ServiceAccount\n  name: admin-user\n  namespace: kubernetes-dashboard\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once set, save the file and exit the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, deploy the admin user role using the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl apply -f dashboard-admin.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see a service account and a cluster role binding created.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">serviceaccount\/admin-user created\nclusterrolebinding.rbac.authorization.k8s.io\/admin-user created<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using this method doesn\u2019t require setting up or memorising passwords, instead, accessing the dashboard will require a token.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Get the admin token using the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl get secret -n kubernetes-dashboard $(kubectl get serviceaccount admin-user -n kubernetes-dashboard -o jsonpath=\"{.secrets[0].name}\") -o jsonpath=\"{.data.token}\" | base64 --decode<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You\u2019ll then see an output of a long string of seemingly random characters, like in the example below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">eyJhbGciOiJSUzI1NiIsImtpZCI6Ilk2eEd2QjJMVkhIRWNfN2xTMlA5N2RNVlR5N0o1REFET0dp\ndkRmel90aWMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlc\ny5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1Y\nmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuL\nXEyZGJzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZ\nSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb\n3VudC51aWQiOiI1ODI5OTUxMS1hN2ZlLTQzZTQtODk3MC0yMjllOTM1YmExNDkiLCJzdWIiOiJze\nXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.GcUs\nMMx4GnSV1hxQv01zX1nxXMZdKO7tU2OCu0TbJpPhJ9NhEidttOw5ENRosx7EqiffD3zdLDptS22F\ngnDqRDW8OIpVZH2oQbR153EyP_l7ct9_kQVv1vFCL3fAmdrUwY5p1-YMC41OUYORy1JPo5wkpXrW\nOytnsfWUbZBF475Wd3Gq3WdBHMTY4w3FarlJsvk76WgalnCtec4AVsEGxM0hS0LgQ-cGug7iGbmf\ncY7odZDaz5lmxAflpE5S4m-AwsTvT42ENh_bq8PS7FsMd8mK9nELyQu_a-yocYUggju_m-BxLjgc\n2cLh5WzVbTH_ztW7COlKWvSVbhudjwcl6w<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The token is created each time the dashboard is deployed and is required to log into the dashboard. Note that the token will change if the dashboard is stopped and redeployed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Creating Read-Only user<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can create a read-only view for the cluster if you wish to provide access to your Kubernetes dashboard, for example, for demonstrative purposes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Similarly to the admin account, save the following configuration in <tt>dashboard-read-only.yaml<\/tt><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nano dashboard-read-only.yaml<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: read-only-user\n  namespace: kubernetes-dashboard\n---\napiVersion:&nbsp;rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n  annotations:\n    rbac.authorization.kubernetes.io\/autoupdate: \"true\"\n  labels:\n  name: read-only-clusterrole\n  namespace: default\nrules:\n- apiGroups:\n  - \"\"\n  resources: [\"*\"]\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - extensions\n  resources: [\"*\"]\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - apps\n  resources: [\"*\"]\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion:&nbsp;rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: read-only-binding\nroleRef:\n  kind: ClusterRole\n  name: read-only-clusterrole\n  apiGroup:&nbsp;rbac.authorization.k8s.io\nsubjects:\n- kind: ServiceAccount\n  name: read-only-user\n  namespace: kubernetes-dashboard<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once set, save the file and exit the editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, deploy the read-only user account using the command below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl apply -f dashboard-read-only.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To allow users to log in via the read-only account, you\u2019ll need to provide a token which can be fetched using the next command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl get secret -n kubernetes-dashboard $(kubectl get serviceaccount read-only-user -n kubernetes-dashboard -o jsonpath=\"{.secrets[0].name}\") -o jsonpath=\"{.data.token}\" | base64 --decode<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The toke will be a long series of characters unique to the dashboard currently running.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Accessing the dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019ve deployed the dashboard and created user accounts for it. Next, we can start managing the Kubernetes cluster itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, before we can log in to the dashboard, it needs to be made available by creating a proxy service on the localhost. Run the next command on your Kubernetes cluster.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl proxy<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will start the server at 127.0.0.1:8001, as shown by the output.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Starting to serve on 127.0.0.1:8001<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, assuming that we have already established an SSH tunnel binding to the localhost port 8001 at both ends, open a browser to the link below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">http:\/\/localhost:8001\/api\/v1\/namespaces\/kubernetes-dashboard\/services\/https:kubernetes-dashboard:\/proxy\/<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If everything is running correctly, you should see the dashboard login window.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/kubernetes-dashboard-sign-in.png\" alt=\"Signing in to Kubernetes dashboard\" class=\"wp-image-16376\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Select the token authentication method and copy your admin token into the field below. Then click the Sign in button.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You will then be greeted by the overview of your Kubernetes cluster.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/kubernetes-dashboard.png\" alt=\"Kubernetes dashboard overview\" class=\"wp-image-16374\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">While signed in as an admin, you can deploy new pods and services quickly and easily by clicking the plus icon at the top right corner of the dashboard.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/kubernetes-dashboard-create.png\" alt=\"Creating new from input on Kubernetes dashboard\" class=\"wp-image-16375\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then either copy in any configuration file you wish, select the file directly from your machine or create a new configuration from a form.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Stopping the dashboard<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">User roles that are no longer needed can be removed using the delete method.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl delete -f dashboard-admin.yaml\nkubectl delete -f dashboard-read-only.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Likewise, if you want to disable the dashboard, it can be deleted just like any other deployment.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl delete -f https:\/\/raw.githubusercontent.com\/kubernetes\/dashboard\/v2.0.0\/aio\/deploy\/recommended.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The dashboard can then be redeployed at any time following the same procedure as before.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Setting up management script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The steps to deploy or delete the dashboard are not complicated but they can be further simplified.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The following script can be used to start, stop or check the dashboard status.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">nano ~\/dashboard\/dashboard.sh<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\nshowtoken=1\ncmd=\"kubectl proxy\"\ncount=`pgrep -cf \"$cmd\"`\ndashboard_yaml=\"https:\/\/raw.githubusercontent.com\/kubernetes\/dashboard\/v2.0.0\/aio\/deploy\/recommended.yaml\"\nmsgstarted=\"-e Kubernetes Dashboard e[92mstartede[0m\"\nmsgstopped=\"Kubernetes Dashboard stopped\"\n\ncase $1 in\nstart)\n   kubectl apply -f $dashboard_yaml &gt;\/dev\/null 2&gt;&amp;1\n   kubectl apply -f ~\/dashboard\/dashboard-admin.yaml &gt;\/dev\/null 2&gt;&amp;1\n   kubectl apply -f ~\/dashboard\/dashboard-read-only.yaml &gt;\/dev\/null 2&gt;&amp;1\n\n   if [ $count = 0 ]; then\n      nohup $cmd &gt;\/dev\/null 2&gt;&amp;1 &amp;\n      echo $msgstarted\n   else\n      echo \"Kubernetes Dashboard already running\"\n   fi\n   ;;\n\nstop)\n   showtoken=0\n   if [ $count -gt 0 ]; then\n      kill -9 $(pgrep -f \"$cmd\")\n   fi\n   kubectl delete -f $dashboard_yaml &gt;\/dev\/null 2&gt;&amp;1\n   kubectl delete -f ~\/dashboard\/dashboard-admin.yaml &gt;\/dev\/null 2&gt;&amp;1\n   kubectl delete -f ~\/dashboard\/dashboard-read-only.yaml &gt;\/dev\/null 2&gt;&amp;1\n   echo $msgstopped\n   ;;\n\nstatus)\n   found=`kubectl get serviceaccount admin-user -n kubernetes-dashboard 2&gt;\/dev\/null`\n   if [[ $count = 0 ]] || [[ $found = \"\" ]]; then\n      showtoken=0\n      echo $msgstopped\n   else\n      found=`kubectl get clusterrolebinding admin-user -n kubernetes-dashboard 2&gt;\/dev\/null`\n      if [[ $found = \"\" ]]; then\n         nopermission=\" but user has no permissions.\"\n         echo $msgstarted$nopermission\n         echo 'Run \"dashboard start\" to fix it.'\n      else\n         echo $msgstarted\n      fi\n   fi\n   ;;\nesac\n\n# Show full command line # ps -wfC \"$cmd\"\nif [ $showtoken -gt 0 ]; then\n   # Show token\n   echo \"Admin token:\"\n   kubectl get secret -n kubernetes-dashboard $(kubectl get serviceaccount admin-user -n kubernetes-dashboard -o jsonpath=\"{.secrets[0].name}\") -o jsonpath=\"{.data.token}\" | base64 --decode\n   echo\n\n   echo \"User read-only token:\"\n   kubectl get secret -n kubernetes-dashboard $(kubectl get serviceaccount read-only-user -n kubernetes-dashboard -o jsonpath=\"{.secrets[0].name}\") -o jsonpath=\"{.data.token}\" | base64 --decode\n   echo\nfi<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once everything is set, save the file and exit the text editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, make the script executable.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">chmod +x ~\/dashboard\/dashboard.sh<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, create a symbolic link to the dashboard script to be able to run it from anywhere on the system.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo ln -s ~\/dashboard\/dashboard.sh \/usr\/local\/bin\/dashboard<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can then use the following commands to run the dashboard like an application.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start the dashboard and show the tokens<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dashboard start<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check whether the dashboard is running or not and output the tokens if they are currently set.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dashboard status<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Stop the dashboard<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dashboard stop<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations, you have successfully installed the Kubernetes dashboard! You can now start getting familiar with the dashboard by exploring the different menus and views it offers.<\/p>\n\n\n","protected":false},"author":34,"featured_media":16374,"comment_status":"open","ping_status":"closed","template":"","community-category":[223,229],"class_list":["post-2131","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2131"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2131\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2131"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}