How to properly configure access to kubernees dashboard behind nginx ingress

6,928

TL;DR

You cannot pass the verification (pressing Sign In doing nothing) by the lack of HTTPS.

As I said in the comment:

Login not available

If your login view displays below error, this means that you are trying to log in over HTTP and it has been disabled for the security reasons.

Logging in is available only if URL used to access Dashboard starts with:

  • http://localhost/...
  • http://127.0.0.1/...
  • https://<domain_name>/...

Github.com: Kubernetes: Dashboard: Login not available

You can login to Kubernetes Dashboard without HTTPS only with:

  • http://localhost/...
  • http://127.0.0.1/...

You need HTTPS to login to your Kubernetes Dashboard with:

  • https://IP.ADDRESS
  • https://DOMAIN.NAME

endpoints "kubernetes-dashboard" not found

But this does not seem to work, no endpoint is configured

It means that the Ingress resource could not find the Endpoint to sent the traffic to. This happened in your case because:

  • Ingress is in default namespace
  • Service named kubernetes-dashboard is in monit namespace

To make it work you can (one of the ways) make another Ingress resource specifically in monit namespace.

You can invoke below commands to get more information about your resources:

  • $ kubectl get services -n monit
  • $ kubectl get endpoints -n monit

Resources in Kubernetes are strictly connected to namespaces. You can read about them more here: Kubernetes.io: Concepts: Working with objects: Namespaces


You have several ways to deploy Kubernetes Dashboard. It will depend on the solution you are using (minikube,bare metal kubeadm cluster,eks,gke, etc.).

General steps to take to deploy Kubernetes Dashboard with Nginx-ingress:

  • Deploy Nginx-ingress
  • Download and modify the Dashboard definition
  • Configure access to Dashboard with Ingress
  • Test it

Deploy Nginx-ingress

Please follow official documentation regarding deployment of Nginx-ingress: Kubernetes.github.io: Ingress-nginx: Deploy

Download and modify the Dashboard definition

Installation of Kubernetes Dashboard: Kubernetes.io: Web ui dashboard: Deployment

Above link can be used to deploy Dashboard but few adjustments will need to be made.

Assume the following:

  • Every resource in kubernetes-dashboard namespace
  • Arguments for Dashboard:
      - args:
        - --namespace=kubernetes-dashboard
        - --enable-insecure-login
        - --insecure-bind-address=0.0.0.0
    
  • Dashboard listening on port 9090
  • Services as well as healthchecks associated with Dashboard set to port 9090/TCP/HTTP.

A tip for arguments!

enable-skip-login false When enabled, the skip button on the login page will be shown.

Github.com: Kubernetes: Dashboard: Arguments

Your Dashboard definition will need a Service to be exposed outside the cluster. You can create your own definition of a Service like example below or edit definition included in installation YAML above.

Example below:

kind: Service
apiVersion: v1
metadata:
  name: dashboard-service
  namespace: kubernetes-dashboard
  labels:
    k8s-app: kubernetes-dashboard
spec:
  selector:
    k8s-app: kubernetes-dashboard
  ports:
    - port: 80
      targetPort: 9090
      nodePort: 30001
      name: dashboard-port
  type: NodePort

Please take a specific look on part:

  ports:
    - port: 80
      targetPort: 9090
      nodePort: 30001
      name: dashboard-port

Traffic will be sent to the Dashboard pod on port 9090 as required by the arguments of the Dashboard itself.

Configure access to Dashboard with Ingress

Assuming your Ingress is deployed correctly you can use below example to expose Dashboard:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard-ingress
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - secretName: tls-secret # NON-EXISTENT
  rules:
  - host:
    http:
      paths:
      - path: /
        backend:
          serviceName: dashboard-service
          servicePort: dashboard-port 

Please take specific look on parts:

  • - secretName: tls-secret # NON-EXISTENT - it will configure controller to use a fake certificate and allow HTTPS connections
  • namespace: kubernetes-dashboard - namespace is exactly the same as other Dashboard resources
  • serviceName: dashboard-service - name of the service associated with Dashboard
  • servicePort: dashboard-port - name of the port of the service associated with Dashboard

Test it

After this steps you should be able to enter either ip address or domain name to your web browser and open Dashboard panel.

Please make sure that you connect to Dashboard with: https://.

If you configured your Dashboard to require authentication you should provide the authentication token. You can find your token by invoking below command:

  • $ kubectl describe secret NAME_OF_THE_SECRET -n NAMESPACE
Share:
6,928
bachr
Author by

bachr

Updated on September 18, 2022

Comments

  • bachr
    bachr over 1 year

    I'm trying to configure nginx ingress to access several services, like this:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-monit
    spec:
      rules:
      - host: grafana.localhost
        http:
          paths:
          - path: /
            backend:
              serviceName: prometheus-grafana
              servicePort: 80
      - host: kubernetes-dashboard.localhost
        http:
          paths:
          - path: /
            backend:
              serviceName: kubernetes-dashboard
              servicePort: 80
    

    I've access to the grafana service without any problems, my issue is with kubernetes-dashboard. I've already configured kubernetes-dashboard to allow HTTP traffic with this configuration

    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: monit
    spec:
      ports:
        - port: 80
          targetPort: 9090
      selector:
        k8s-app: kubernetes-dashboard
    
    ---
    
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: monit
    spec:
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          k8s-app: kubernetes-dashboard
      template:
        metadata:
          labels:
            k8s-app: kubernetes-dashboard
        spec:
          containers:
            - name: kubernetes-dashboard
              image: kubernetesui/dashboard:v2.0.0-beta8
              imagePullPolicy: Always
              ports:
                - containerPort: 9090
                  protocol: TCP
              args:
                - --namespace=monit
                - --insecure-bind-address=0.0.0.0
                - --insecure-port=9090
                - --enable-insecure-login
                # Uncomment the following line to manually specify Kubernetes API server Host
                # If not specified, Dashboard will attempt to auto discover the API server and connect
                # to it. Uncomment only if the default does not work.
                # - --apiserver-host=http://my-address:port
              volumeMounts:
                - name: kubernetes-dashboard-certs
                  mountPath: /certs
                  # Create on-disk volume to store exec logs
                - mountPath: /tmp
                  name: tmp-volume
              livenessProbe:
                httpGet:
                  scheme: HTTP
                  path: /
                  port: 9090
                initialDelaySeconds: 30
                timeoutSeconds: 30
              securityContext:
                allowPrivilegeEscalation: false
                readOnlyRootFilesystem: true
                runAsUser: 1001
                runAsGroup: 2001
          volumes:
            - name: kubernetes-dashboard-certs
              secret:
                secretName: kubernetes-dashboard-certs
            - name: tmp-volume
              emptyDir: {}
          serviceAccountName: kubernetes-dashboard
          nodeSelector:
            "beta.kubernetes.io/os": linux
          # Comment the following tolerations if Dashboard must not be deployed on master
          tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
    

    I;ve also a valid token which I can use to access kubernetes dashboard when I use ClusterIP. However when I access it through ngress I cannot go over the login page even with valid token (see screenshot).

    enter image description here

    I looked into Nginx logs for problems/errors but everything seemed fine

    $ kubectl logs -n monit ingress-nginx-controller-bbdc786b4-6nl9h  -f
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "GET /api/v1/csrftoken/login HTTP/1.1" 200 85 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 479 0.001 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 85 0.001 200 59fc952888dfadf0223740c31e562ef8
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "POST /api/v1/login HTTP/1.1" 200 1508 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 1545 0.005 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 1508 0.005 200 241388246b11031765557475bea603ff
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "GET /api/v1/plugin/config HTTP/1.1" 200 185 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 477 0.003 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 185 0.003 200 45371469793ce4f35c45dec70530bea0
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "GET /api/v1/login/status HTTP/1.1" 200 108 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 476 0.001 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 108 0.001 200 49171f5e9316a2d6da883d1c4f0b50df
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "GET /api/v1/login/status HTTP/1.1" 200 108 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 476 0.001 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 108 0.001 200 c69b9d166f1527f00e7cd175696ec8c7
    192.168.65.3 - - [03/Jun/2020:02:03:13 +0000] "GET /api/v1/login/status HTTP/1.1" 200 108 "http://kubernetes-dashboard.localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" 476 0.001 [monit-kubernetes-dashboard-80] [] 10.1.0.123:9090 108 0.001 200 1f9c27ca407bca57dcc0c26bca65be58
    

    What am I missing in my ingress configuration?

    UPDATE: I tried to setup an https ingress for the dashboard with this config

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: https-ingress-monit
      annotations:
        nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    spec:
      rules:
      - host: kubernetes-dashboard.localhost
        http:
          paths:
          - path: /
            backend:
              serviceName: kubernetes-dashboard
              servicePort: 443
    

    But this does not seem to work, no endpoint is configured

    $ kubectl describe ingress https-ingress-monit -n monit
    Name:             https-ingress-monit
    Namespace:        monit
    Address:          localhost
    Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
    Rules:
      Host                            Path  Backends
      ----                            ----  --------
      kubernetes-dashboard.localhost  
                                      /   kubernetes-dashboard:443 (<error: endpoints "kubernetes-dashboard" not found>)
    Annotations:                      nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    Events:
      Type    Reason  Age   From                      Message
      ----    ------  ----  ----                      -------
      Normal  CREATE  87s   nginx-ingress-controller  Ingress monit/https-ingress-monit
      Normal  UPDATE  74s   nginx-ingress-controller  Ingress monit/https-ingress-monit
    

    Now when I try to access http://kubernetes-dashboard.localhost/ I see 503 Service Temporarily Unavailable

    • Dawid Kruk
      Dawid Kruk almost 4 years
      It looks like you cannot login by the lack of HTTPS. Please take a look here: Github.com: Kubernetes: Dashboard: Login not available and here Stackoverflow: Accessing Kubernetes Dashboard. You will need to reconfigure your Ingress resource. Please let me know the results.
    • bachr
      bachr almost 4 years
      thanks for the links, I don't have an error message like the one described in github.com/kubernetes/dashboard/tree/master/docs/user/…. In fact, nothing happens when I click sign in
    • bachr
      bachr almost 4 years
      Does this means that when exposing the dashboard on a URL like kubernetes-dashboard.localhost it just won;t work and I have to configure another ingress rule for https?
    • Dawid Kruk
      Dawid Kruk almost 4 years
      Yes, please try to configure your Ingress resource to support HTTPS and let me know if it helped.
    • bachr
      bachr almost 4 years
      @DawidKruk I tried with https for communication between Nginx and dashboard service. see updated post
  • bachr
    bachr almost 4 years
    this is outstanding, thanks for the details pointer, that answers lot of my questions all at once!!