How do I access the Kubernetes Dashboard on a custom path in Amazon EKS?

Last updated: 2020-04-06

I want to access the Kubernetes Dashboard on a custom path in Amazon Elastic Kubernetes Service (Amazon EKS).

Short Description

To access the Kubernetes Dashboard, you must complete the following:

  1. Create or use an existing self-signed certificate, and then upload the certificate to the AWS Certificate Manager (ACM).
  2. Deploy the NGINX Ingress Controller and expose it as a NodePort service.
  3. Create an Ingress object for the Application Load Balancer (ALB) Ingress Controller that forwards all the requests from the ALB to the NGINX Ingress Controller that you deployed earlier using a manifest file.
  4. Deploy the Kubernetes Dashboard.
  5. Create an Ingress for the NGINX Ingress Controller.

Here's how the resolution works:

  1. The ALB forwards all the incoming traffic to the NGINX Ingress Controller.
  2. The NGINX Ingress Controller evaluates the path-pattern of the incoming request (for example, /custom-path/additonalcustompath).
  3. The NGINX Ingress Controller rewrites the URL to /additonalcustompath before forwarding the request to the kubernetes-dashboard service.

Resolution

Create or use an existing self-signed certificate, and then upload the certificate to ACM

If you want to use an existing ACM certificate with the ALB, then you can skip the steps in this section.

Note: The following steps apply to the Amazon Linux Amazon Machine Image (AMI) release 2018.03.

1.    Generate a private key using OpenSSL:

openssl genrsa 2048 > kube-dash-private.key

2.    Create a certificate using the key generated in step 1:

openssl req -new -x509 -nodes -sha1 -days 3650 -extensions v3_ca -key kube-dash-private.key > kube-dash-public.crt

Important: Be sure to provide a fully qualified domain for Common Name, as the ALB allows only ACM certificates with fully qualified domain names to be attached to the listener 443.

The output should look similar to the following:

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:   
Common Name (eg, your name or your server's hostname) []:kube-dashboard.com         ==>This is important
Email Address []:

3.    Install the AWS Command Line Interface (AWS CLI) and set up the credentials.

4.    Upload the private key and the certificate to ACM in your AWS Region:

aws acm import-certificate --certificate file://kube-dash-public.crt --private-key file://kube-dash-private.key --region us-east-1

Note: Replace us-east-1 with your AWS Region.

The output looks similar to the following:

{
    "CertificateArn": "arn:aws:acm:us-east-1:your-account:certificate/your-certificate-id"
}

5.    Open the ACM console, and then verify that the domain name appears in your imported ACM certificate.

Tip: If the domain name doesn't appear in the ACM console, then recreate the certificate with a valid fully qualified domain name.

Deploy the NGINX Ingress Controller and expose it as a NodePort service

1.    Deploy the NGINX Ingress Controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

2.    To expose the NGINX Ingress Controller as a NodePort service, create a ingress-controller-service.yaml file based on the following:

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  # this setting is to make sure the source IP address is preserved.
  type: NodePort
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

3.    Apply the manifest file:

kubectl apply -f ingress-controller-service.yaml

Create an Ingress object for the ALB Ingress Controller that forwards all the requests from the ALB Ingress Controller to the NGINX Ingress Controller that you deployed earlier using a manifest file

1.    Deploy the ALB Ingress Controller.

2.    Create an Ingress object for the ALB Ingress Controller based on the following alb-ingress.yaml file:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "alb-ingress"
  namespace: "ingress-nginx"
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:your-region:your-account-id:certificate/XXXX-XXXX-XXXX-XXXX-XXXXX
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
  labels:
    app: dashboard
spec:
  rules:
    - http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: "ingress-nginx"
              servicePort: 80

Note: Replace the "alb.ingress.kubernetes.io/certificate-arn" value with your ACM certificate ARN.

The preceding manifest file uses the following annotations:

A) The "alb.ingress.kubernetes.io/scheme" annotation creates an internet-facing ALB.
B) The "alb.ingress.kubernetes.io/certificate-arn" annotation associates the ACM certificate Amazon Resource Name (ARN) with the 443 listener of the ALB.
C) The "alb.ingress.kubernetes.io/listen-ports" annotation creates the listeners for ports 80 and 443.
D) The "alb.ingress.kubernetes.io/actions.ssl-redirect" annotation redirects all the requests coming to ports 80 to 443.

3.    Apply the manifest file from the preceding step 2:

kubectl apply -f alb-ingress.yaml

Deploy the Kubernetes Dashboard

To deploy the Kubernetes Dashboard, follow the instructions at Tutorial: Deploy the Kubernetes Web UI (Dashboard).

Create an Ingress for the NGINX Ingress Controller

1.    Create an Ingress for the NGINX Ingress Controller based on the following ingress-dashboard.yaml file:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: dashboard
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  namespace: kubernetes-dashboard
spec:
  rules:
  - http:
      paths:
      - path: /dashboard(/|$)(.*)
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 443

Note: The "nginx.ingress.kubernetes.io/rewrite-target" annotation rewrites the URL before forwarding the request to the backend pods. In /dashboard(/|$)(.*) for path, (.*) stores the dynamic URL that is generated while accessing the Kubernetes Dashboard. The "nginx.ingress.kubernetes.io/rewrite-target" annotation replaces the captured data in the URL before forwarding the request to the kubernetes-dashboard service.

2.    Apply the manifest file ingress-dashboard.yaml:

kubectl apply -f ingress-dashboard.yaml

3.    Check the ALB URL in the ADDRESS of the alb-ingress that you created earlier:

kubectl get ingress alb-ingress -n ingress-nginx

You can now access the Kubernetes Dashboard using ALB-URL/dashboard/.

Important: To make the dashboard accessible to users, you must add a trailing slash to the URL.

Note: The ALB targets report unhealthy status because by default the ALB health checks are done on path "/", and a 200 success code is expected. However, the NGINX Ingress Controller returns a 404 at path "/", because you configured only the /dashboard(/|$)(.*) path. The requests are still routed to the targets because all the targets are in unhealthy status.

Clean up the resources that you created earlier

1.    Delete the ingress for the NGINX Ingress Controller:

kubectl delete -f ingress-dashboard.yaml

2.    Delete the Kubernetes Dashboard components and the Metrics Server:

kubectl delete -f eks-admin-service-account.yaml

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

kubectl delete -f metrics-server-$DOWNLOAD_VERSION/deploy/1.8+/

3.    Delete the alb-ingress and the alb-ingress-controller components:

kubectl delete -f alb-ingress.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml

Note: If you created AWS Identity and Access Management (IAM) resources, then you can delete the IAM role and IAM policy.

4.    Delete the NodePort service and the NGINX Ingress Controller:

kubectl delete -f ingress-controller-service.yaml

kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

5.    If you created an ACM certificate and want to delete the certificate, then run the following command:

aws acm delete-certificate --certificate-arn arn:aws:acm:us-east-1:your-account-id:certificate/XXXX-XXXX-XXXX-XXXX-XXXXX --region us-east-1

Note: Replace certificate-arn with your certificate ARN. Replace us-east-1 with your AWS Region. Replace your-account-id with your account ID.


Did this article help you?

Anything we could improve?


Need more help?