Skip to content

Instantly share code, notes, and snippets.

@s-lyn
Last active November 7, 2025 10:47
Show Gist options
  • Select an option

  • Save s-lyn/3aba97628c922ddc4a9796ac31a6df2d to your computer and use it in GitHub Desktop.

Select an option

Save s-lyn/3aba97628c922ddc4a9796ac31a6df2d to your computer and use it in GitHub Desktop.
Configure Kubernetes Dashboard Web UI hosted with Nginx Ingress Controller

This gist is based on [Kubernetes Dashboard](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/} deploy docs. I think you have installed the Nginx Iingress Controller.

1) Deploy the Dashboard UI

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml

2) Creating the Service Account and ClusterRoleBinding

cat <<EOF | kubectl apply -f -
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
EOF

3) Get a Bearer Token

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

For Bash:

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

For Powershell:

kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | sls admin-user | ForEach-Object { $_ -Split '\s+' } | Select -First 1)

It should print the data with line like:

token: <YOUR TOKEN HERE>

Now save it. You need to use it whe login the dashboard.

4) Create the ingress controller

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  namespace: kubernetes-dashboard
  name: kubernetes-dashboard-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    # Uncomment next if you use https://cert-manager.io/
    #cert-manager.io/cluster-issuer: "<YOUR CLUSTER ISSUER>"
spec:
  tls:
  - hosts:
    - <YOUR DOMAIN HERE>
    secretName: kubernetes-dashboard-cert
  rules:
  - host: <YOUR DOMAIN HERE>
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
EOF

5) Login to dashboard

Go to https://<YOUR DOMAIN> and insert the previous created token into Enter token field.

@chadleywilson
Copy link

Not sure I understand this document

I have tried hostname.mydomian.net
mydomain.net
and just hostname

either way I get this error

error: unable to recognize "STDIN": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

@s-lyn
Copy link
Author

s-lyn commented Feb 20, 2023

Not sure I understand this document I have tried hostname.mydomian.net mydomain.net and just hostname

either way I get this error

error: unable to recognize "STDIN": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

Hi @chadleywilson!
This gist was created more then 2 years ago, as I see from docs apiVersion was changed from networking.k8s.io/v1beta1 to networking.k8s.io/v1.
I don't have a cluster to check now, but you cought try follow relevant docs for your Ingress controller's version.

@s-lyn
Copy link
Author

s-lyn commented Feb 20, 2023

@chadleywilson Possible version changing is good enought to work in your case.

@chadleywilson
Copy link

chadleywilson commented Feb 20, 2023

turns out it not just a version change there are syntax changes as well:

 apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: kubernetes-dashboard
  name: kubernetes-dashboard-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    # Uncomment next if you use https://cert-manager.io/
    # cert-manager.io/cluster-issuer: "<YOUR CLUSTER ISSUER>"
spec:
  tls:
  - hosts:
    - bw-npe.net
    secretName: kubernetes-dashboard-cert
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
               number: 443

@lolpro11
Copy link

lolpro11 commented Jan 9, 2024

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: kubernetes-dashboard
  name: kubernetes-dashboard-ingress
  annotations:
    kubernetes.io/spec.ingressClassName.class: "nginx"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - lolpro11'
spec:
  rules:
  - host: lolpro11.me
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 80
EOF

@evan-sm
Copy link

evan-sm commented Jul 7, 2024

In my situation backend service name was "kubernetes-dashboard-kong-proxy"

@C-L-STARK
Copy link

.... not work for me!

@FabienPapet
Copy link

FabienPapet commented Oct 30, 2024

This worked for me

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: kubernetes-dashboard
  name: kubernetes-dashboard-ingress
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    cert-manager.io/cluster-issuer: <name of issuer>
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - <filtered>
      secretName: kubernetes-dashboard-cert
  rules:
    - host: <filtered>
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kubernetes-dashboard-kong-proxy
                port:
                  number: 443

@Garden-Leave
Copy link

one question, if you match / for this svc, what about other services ?

@mohag
Copy link

mohag commented Feb 7, 2025

You probably should not be using the ssl-passthrough annotations (the feature is disabled by default) - if it works, the cert needs to be managed on the backend service...

@garry-t
Copy link

garry-t commented May 19, 2025

Still pain in ass, how to make it work with existing Traefik, which terminates ssl, I need to have dashboard in plain http

@Marzena-Olga
Copy link

Marzena-Olga commented Nov 7, 2025

I used helm deployment:

helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace -n kubernetes-dashboard --values values.yaml

  • dashboard-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dashboard
spec:
  acme:
    email:  [email protected]
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-dashboard
    solvers:
      - http01:
          ingress:
            class: nginx
app:
  ingress:
    enabled: true
    hosts:
      # Keep 'localhost' host only if you want to access Dashboard using 'kubectl port-forward ...' on:
      # https://localhost:8443
      - your-host.domain.com
    ingressClassName: nginx
    # Use only if your ingress controllers support default ingress classes.
    # If set to true ingressClassName will be ignored and not added to the Ingress resources.
    # It should fall back to using IngressClass marked as the default.
    useDefaultIngressClass: false
    # This will append our Ingress with annotations required by our default configuration.
    #    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    #    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    #    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    useDefaultAnnotations: true
    pathType: ImplementationSpecific
    # If path is not the default (/), rewrite-target annotation will be added to the Ingress.
    # It allows serving Kubernetes Dashboard on a sub-path. Make sure that the configured path
    # does not conflict with gateway route configuration.
    path: /
    issuer:
      name: letsencrypt-dashboard
      # Scope determines what kind of issuer annotation will be used on ingress resource
      # - default - adds 'cert-manager.io/issuer'
      # - cluster - adds 'cert-manager.io/cluster-issuer'
      # - disabled - disables cert-manager annotations
      scope: cluster
    tls:
      enabled: true
      # If provided it will override autogenerated secret name
      secretName: "letsencrypt-dashboard"
    labels: {}
    annotations: {}
  # Use the following toleration if Dashboard can be deployed on a tainted control-plane nodes
  # - key: node-role.kubernetes.io/control-plane
  #   effect: NoSchedule
  tolerations: []
  affinity: {}

Ingerss generated by helm:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-dashboard
    meta.helm.sh/release-name: kubernetes-dashboard
    meta.helm.sh/release-namespace: kubernetes-dashboard
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app.kubernetes.io/instance: kubernetes-dashboard
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/part-of: kubernetes-dashboard
    helm.sh/chart: kubernetes-dashboard-7.13.0
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ingressClassName: nginx
  rules:
  - host: your-host.domain.com
    http:
      paths:
      - backend:
          service:
            name: kubernetes-dashboard-kong-proxy
            port:
              number: 443
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - your-host.domain.com
    secretName: letsencrypt-dashboard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment