<p>Document followed 
<a href="https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html" rel="nofollow noreferrer">https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html</a></p>

<p>I am able to set up the dashboard and access it using the link  <a href="http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#!/login" rel="nofollow noreferrer">http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#!/login</a></p>

<p>The issue with this is that "EVERY USER HAS TO FOLLOW THE SAME TO ACCESS THE DASHBOARD"</p>

<p>I was wondering if there was some way wherein we can access the dashboard via DomainName and everyone should be able to access it without much pre-set up required.</p>

<p>We have two approaches to expose the Dashboard, <code>NodePort</code> and in <code>LoadBalancer</code>.</p>

<p>I'll demonstrate both cases and some of it's pros and cons.</p>

<hr>

<h2><code>type: NodePort</code></h2>

<p>This way your dashboard will be available in <code>https://&lt;MasterIP&gt;:&lt;Port&gt;</code>.</p>

<ul>
<li>I'll start with Dashboard is already deployed and running as ClusterIP (just like yours).</li>
</ul>

<pre><code>$ kubectl get service kubernetes-dashboard -n kubernetes-dashboard
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes-dashboard   ClusterIP   10.0.11.223   &lt;none&gt;        80/TCP     11m
</code></pre>

<ul>
<li>We patch the service to change the <a href="https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types" rel="nofollow noreferrer">ServiceType</a>:</li>
</ul>

<pre><code>$ kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec": {"type": "NodePort"}}'
service/kubernetes-dashboard patched
</code></pre>

<p><strong>Note:</strong> You can also apply in YAML format changing the field <code>type: ClusterIP</code> to <code>type: Nodeport</code>, instead I wanted to show a direct approach with <a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#patch" rel="nofollow noreferrer"><code>kubectl patch</code></a> using JSON format to patch the same field.</p>

<ul>
<li>Now let's list to see the new port:</li>
</ul>

<pre><code>$ kubectl get service kubernetes-dashboard -n kubernetes-dashboard
NAME                   TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   NodePort   10.0.11.223   &lt;none&gt;        443:31681/TCP   13m
</code></pre>

<p><strong>Note:</strong> Before accessing from an outside cluster, you must enable the security group of the nodes to allow incoming traffic through the port exposed,  or here for <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/exposing-apps#creating_a_service_of_type_nodeport" rel="nofollow noreferrer">GKE</a>.
  Below my example creating the rule on Google Cloud, but the same concept applies to <a href="https://aws.amazon.com/premiumsupport/knowledge-center/eks-kubernetes-services-cluster/" rel="nofollow noreferrer">EKS</a>.</p>

<pre><code>$ gcloud compute firewall-rules create test-node-port --allow tcp:31681
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/owilliam/global/firewalls/test-node-port].                                                                 
Creating firewall...done.                                                                                                                                                               
NAME            NETWORK  DIRECTION  PRIORITY  ALLOW      DENY  DISABLED
test-node-port  default  INGRESS    1000      tcp:31681        False                                                                                                                                                               

$ kubectl get nodes --output wide
NAME                                 STATUS   ROLES    AGE   VERSION         INTERNAL-IP   EXTERNAL-IP
gke-cluster-1-pool-1-4776b3eb-16t7   Ready    &lt;none&gt;   18d   v1.15.8-gke.3   10.128.0.13   35.238.162.157

</code></pre>

<ul>
<li>And I'll access it using <code>https://35.238.162.157:31681</code>:</li>
</ul>

<p><a href="https://i.stack.imgur.com/UDz0d.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UDz0d.png" alt="enter image description here"></a></p>

<hr>

<h2><code>type: LoadBalancer</code></h2>

<p>This way your dashboard will be available in <code>https://IP</code>.</p>

<ul>
<li><p>Using <code>LoadBalancer</code> your cloud provider automates the firewall rule and port forwarding assigning an IP for it. (you may be charged extra depending on your plan).</p></li>
<li><p>Same as before, I deleted the service and created again as clusterIP:</p></li>
</ul>

<pre><code>$ kubectl get service kubernetes-dashboard -n kubernetes-dashboard
NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes-dashboard   ClusterIP   10.0.2.196   &lt;none&gt;        443/TCP   15s

$ kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec": {"type": "LoadBalancer"}}'
service/kubernetes-dashboard patched

$ kubectl get service kubernetes-dashboard -n kubernetes-dashboard
NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   LoadBalancer   10.0.2.196   &lt;pending&gt;     443:30870/TCP   58s

$ kubectl get service kubernetes-dashboard -n kubernetes-dashboard
NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP      PORT(S)         AGE
kubernetes-dashboard   LoadBalancer   10.0.2.196   35.232.133.138   443:30870/TCP   11m
</code></pre>

<p><strong>Note:</strong> When you apply it, the EXTERNAL-IP will be in <code>&lt;pending&gt;</code> state, after a few minutes a Public IP should be assigned as you can see above.</p>

<ul>
<li>You can access it using <code>https://35.232.133.138</code>:</li>
</ul>

<p><a href="https://i.stack.imgur.com/yWBfv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yWBfv.png" alt="enter image description here"></a></p>

<hr>

<p><strong>Security Considerations:</strong></p>

<ul>
<li><p>Your connection to the Dashboard when exposed is always thru HTTPS, you may get a notification about the autogenerated certificate everytime you enter, unless you change it for a trusted one. You can find more <a href="https://github.com/kubernetes/dashboard/blob/master/docs/user/certificate-management.md" rel="nofollow noreferrer">here</a></p></li>
<li><p>Since the Dashboard is not meant to be much exposed, I'd suggest to keep the access using the Public IP (or custom dns name in case of aws, i.e: *****.us-west-2.elb.amazonaws.com).</p></li>
<li><p>If you really like to integrate to your main domain name, I'd suggest to put it behind another layer of authentication on your website.</p></li>
<li><p>New access will still need the Access Token, but no one will have to go thru that process to expose the Dashboard, you only have to pass the IP/DNS Address and the Token to access it.</p></li>
<li><p>This token has Cluster-Admin Access, so keep it safe as you'd keep a root password.</p></li>
</ul>

<p>If you have any doubts, let me know!</p>
