Accessing Flink’s Web UI

The Flink Kubernetes Operator, by default, does not change the way the native kubernetes integration exposes the Flink Web UI.

Ingress

Beyond the native options, the Operator also supports creating Ingress entries for external UI access. Ingress generation can be turned on by defining the ingress field in the FlinkDeployment:

  1. metadata:
  2. namespace: default
  3. name: advanced-ingress
  4. spec:
  5. image: flink:1.17
  6. flinkVersion: v1_17
  7. ingress:
  8. template: "flink.k8s.io/{{namespace}}/{{name}}(/|$)(.*)"
  9. className: "nginx"
  10. annotations:
  11. nginx.ingress.kubernetes.io/rewrite-target: "/$2"

The ingress specification defines a mandatory template field and two optional fields className and annotations. When the CR is submitted, the Operator substitutes the template variables from metadata and creates an Ingress entry on the Kubernetes cluster.
Given the example above the Flink UI could be accessed at https://flink.k8s.io/default/advanced-ingress/ and the generated Ingress entry would be:

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. annotations:
  5. nginx.ingress.kubernetes.io/rewrite-target: /$2
  6. name: advanced-ingress
  7. namespace: default
  8. spec:
  9. ingressClassName: nginx
  10. rules:
  11. - host: flink.k8s.io
  12. - http:
  13. paths:
  14. - backend:
  15. service:
  16. name: advanced-ingress-rest
  17. port:
  18. number: 8081
  19. path: /default/advanced-ingress(/|$)(.*)
  20. pathType: ImplementationSpecific

Note: Flink Web UI is built with the popular Angular framework and uses relative path to load static resources, hence the endpoint URL must end with trailing a / when accessing it from browsers through a proxy otherwise the main page appears as blank. In order to support accessing base URLs without a trailing / the URLs can be redirected. When using NGINX as ingress-controller this can be achieved by adding an extra annotation to the Ingress definition:

  1. nginx.ingress.kubernetes.io/configuration-snippet: |
  2. if ($uri = "/default/advanced-ingress") {rewrite .* $1/default/advanced-ingress/ permanent;}

Beyond the example above the Operator understands other template formats too:

Simple domain based routing:

  1. ingress:
  2. template: "{{name}}.{{namespace}}.flink.k8s.io"

This example requires that anything *.flink.k8s.io must be routed to the Ingress Controller with a wildcard DNS entry:

  1. kubectl get ingress -A
  2. NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
  3. default sample-job nginx sample-job.default.flink.k8s.io 192.168.49.2 80 30m

The Flink Web UI can be accessed at https://sample-job.default.flink.k8s.io

Simple path based routing:

  1. ingress:
  2. template: "/{{namespace}}/{{name}}(/|$)(.*)"
  3. annotations:
  4. nginx.ingress.kubernetes.io/rewrite-target: "/$2"

This example requires no DNS entries.

  1. kubectl get ingress -A
  2. NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
  3. default sample-job nginx * localhost 80 54m

The Flink Web UI can be accessed at https://localhost/default/sample-job/

Note: All the examples were created on a minikube cluster. Check the description for enabling the NGINX Ingress Controller on minikube.