<p>I have microk8s v1.22.2 running on Ubuntu 20.04.3 LTS.</p>
<p>Output from <code>/etc/hosts</code>:</p>
<pre><code>127.0.0.1 localhost
127.0.1.1 main
</code></pre>
<p>Excerpt from <code>microk8s status</code>:</p>
<pre><code>addons:
  enabled:
    dashboard            # The Kubernetes dashboard
    ha-cluster           # Configure high availability on the current node
    ingress              # Ingress controller for external access
    metrics-server       # K8s Metrics Server for API access to service metrics
</code></pre>
<p>I checked for the running dashboard (<code>kubectl get all --all-namespaces</code>):</p>
<pre><code>NAMESPACE     NAME                                             READY   STATUS    RESTARTS   AGE
kube-system   pod/calico-node-2jltr                            1/1     Running   0          23m
kube-system   pod/calico-kube-controllers-f744bf684-d77hv      1/1     Running   0          23m
kube-system   pod/metrics-server-85df567dd8-jd6gj              1/1     Running   0          22m
kube-system   pod/kubernetes-dashboard-59699458b-pb5jb         1/1     Running   0          21m
kube-system   pod/dashboard-metrics-scraper-58d4977855-94nsp   1/1     Running   0          21m
ingress       pod/nginx-ingress-microk8s-controller-qf5pm      1/1     Running   0          21m

NAMESPACE     NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
default       service/kubernetes                  ClusterIP   10.152.183.1     &lt;none&gt;        443/TCP    23m
kube-system   service/metrics-server              ClusterIP   10.152.183.81    &lt;none&gt;        443/TCP    22m
kube-system   service/kubernetes-dashboard        ClusterIP   10.152.183.103   &lt;none&gt;        443/TCP    22m
kube-system   service/dashboard-metrics-scraper   ClusterIP   10.152.183.197   &lt;none&gt;        8000/TCP   22m

NAMESPACE     NAME                                               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/calico-node                         1         1         1       1            1           kubernetes.io/os=linux   23m
ingress       daemonset.apps/nginx-ingress-microk8s-controller   1         1         1       1            1           &lt;none&gt;                   22m

NAMESPACE     NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/calico-kube-controllers     1/1     1            1           23m
kube-system   deployment.apps/metrics-server              1/1     1            1           22m
kube-system   deployment.apps/kubernetes-dashboard        1/1     1            1           22m
kube-system   deployment.apps/dashboard-metrics-scraper   1/1     1            1           22m

NAMESPACE     NAME                                                   DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/calico-kube-controllers-69d7f794d9     0         0         0       23m
kube-system   replicaset.apps/calico-kube-controllers-f744bf684      1         1         1       23m
kube-system   replicaset.apps/metrics-server-85df567dd8              1         1         1       22m
kube-system   replicaset.apps/kubernetes-dashboard-59699458b         1         1         1       21m
kube-system   replicaset.apps/dashboard-metrics-scraper-58d4977855   1         1         1       21m
</code></pre>
<p>I want to expose the microk8s dashboard within my local network to access it through <code>http://main/dashboard/</code></p>
<p>To do so, I did the following <code>nano ingress.yaml</code>:</p>
<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: public
    nginx.ingress.kubernetes.io/backend-protocol: &quot;HTTPS&quot;
  name: dashboard
  namespace: kube-system
spec:
  rules:
  - host: main
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /
</code></pre>
<p>Enabling the ingress-config through <code>kubectl apply -f ingress.yaml</code> gave the following error:</p>
<pre><code>error: unable to recognize &quot;ingress.yaml&quot;: no matches for kind &quot;Ingress&quot; in version &quot;extensions/v1beta1&quot;
</code></pre>
<p>Help would be much appreciated, thanks!</p>
<p><strong>Update:</strong>
@harsh-manvar pointed out a mismatch in the config version. I have rewritten ingress.yaml to a very stripped down version:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dashboard
  namespace: kube-system
spec:
  rules:
  - http:
      paths:
      - path: /dashboard
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443
</code></pre>
<p>Applying this works. Also, the ingress rule gets created.</p>
<pre><code>NAMESPACE     NAME        CLASS    HOSTS   ADDRESS     PORTS   AGE
kube-system   dashboard   public   *       127.0.0.1   80      11m
</code></pre>
<p>However, when I access the dashboard through <code>http://&lt;ip-of-kubernetes-master&gt;/dashboard</code>, I get a <code>400</code> error.</p>
<p>Log from the ingress controller:</p>
<pre><code>192.168.0.123 - - [10/Oct/2021:21:38:47 +0000] &quot;GET /dashboard HTTP/1.1&quot; 400 54 &quot;-&quot; &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36&quot; 466 0.002 [kube-system-kubernetes-dashboard-443] [] 10.1.76.3:8443 48 0.000 400 ca0946230759edfbaaf9d94f3d5c959a
</code></pre>
<p>Does the dashboard also need to be exposed using the <code>microk8s proxy</code>? I thought the ingress controller would take care of this, or did I misunderstand this?</p>

<p>To fix the error <code>error: unable to recognize &quot;ingress.yaml&quot;: no matches for kind &quot;Ingress&quot; in version &quot;extensions/v1beta1</code> you need to set <code>apiVersion</code> to the <code> networking.k8s.io/v1</code>. From the <a href="https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/" rel="noreferrer">Kubernetes v1.16 article about deprecated APIs</a>:</p>
<blockquote>
<ul>
<li>NetworkPolicy in the  <strong>extensions/v1beta1</strong>  API version is no longer served
-   Migrate to use the  <strong>networking.k8s.io/v1</strong>  API version, available since v1.8. Existing persisted data can be retrieved/updated via the new version.</li>
</ul>
</blockquote>
<p>Now moving to the second issue. You need to add a few annotations and make few changes in your Ingress definition to make dashboard properly exposed on the microk8s cluster:</p>
<ul>
<li>add <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/" rel="noreferrer"><code>nginx.ingress.kubernetes.io/rewrite-target: /$2</code> annotation</a></li>
<li>add <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#configuration-snippet" rel="noreferrer"><code>nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^(/dashboard)$ $1/ redirect;</code> annotation</a></li>
<li>change <code>path: /dashboard</code> to <code>path: /dashboard(/|$)(.*)</code></li>
</ul>
<p>We need them to properly forward the request to the backend pods - <a href="https://aws.amazon.com/premiumsupport/knowledge-center/eks-kubernetes-dashboard-custom-path/" rel="noreferrer">good explanation in this article</a>:</p>
<blockquote>
<p><strong>Note:</strong> The &quot;nginx.ingress.kubernetes.io/rewrite-target&quot; annotation rewrites the URL before forwarding the request to the backend pods. In <strong>/dashboard(/|$)(.*)</strong> for <strong>path</strong>, <strong>(.*)</strong> stores the dynamic URL that's generated while accessing the Kubernetes Dashboard. The &quot;nginx.ingress.kubernetes.io/rewrite-target&quot; annotation replaces the captured data in the URL before forwarding the request to the <strong>kubernetes-dashboard</strong> service. The &quot;nginx.ingress.kubernetes.io/configuration-snippet&quot; annotation rewrites the URL to add a trailing slash (&quot;/&quot;) only if <strong>ALB-URL/dashboard</strong> is accessed.</p>
</blockquote>
<p>Also we need another two changes:</p>
<ul>
<li>add <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol" rel="noreferrer"><code>nginx.ingress.kubernetes.io/backend-protocol: &quot;HTTPS&quot;</code> annotation</a> to tell NGINX Ingress to communicate with Dashboard service using HTTPs</li>
<li>add <code>kubernetes.io/ingress.class: public</code> annotation <a href="https://stackoverflow.com/a/67041204/16391991">to use NGINX Ingress created by microk8s <code>ingress</code> plugin</a></li>
</ul>
<p>After implementing everything above, the final YAML file looks like this:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite ^(/dashboard)$ $1/ redirect;
    nginx.ingress.kubernetes.io/backend-protocol: &quot;HTTPS&quot;
    kubernetes.io/ingress.class: public
  name: dashboard
  namespace: kube-system
spec:
  rules:
  - http:
      paths:
      - path: /dashboard(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443
</code></pre>
<p>It should work fine. No need to run <code>microk8s proxy</code> command.</p>
