Routing with ingress

Learn more about routing with ingress.

The Flink Operator supports creating Ingress entries for external User Interface (UI) access. The Ingress solution is ideal for production environments, and the manual port-forwarding of the service port can be used for smaller local jobs.

Ingress controllers allow you to route traffic from outside the Kubernetes cluster to your Service resources by providing a single point of entry and routing the traffic based on the data in the request (for example, URL path) to the correct services. Ingress can also be used to easily set up HTTPS for your services without the need to install any certificates to Flink itself.

To use the Ingress controller, you must create the Ingress resources in the Kubernetes cluster with the required filters and configurations that describe when and how to route requests to the Flink service. This can be done by adding the spec.ingress the FlinkDeployment resource as shown in the following example:
apiVersion: flink.apache.org/v1beta1
kind: FlinkDeployment
metadata:
  name: flink-kubernetes-tutorial
spec:
  image: [***REGISTRY HOST***]:[***PORT***]/[***PROJECT***]/flink-kubernetes-tutorial:latest
  flinkVersion: v1_18
  flinkConfiguration:
    taskmanager.numberOfTaskSlots: "4"
  serviceAccount: flink
  mode: native
  jobManager:
    resource:
      memory: "2048m"
      cpu: 1
  taskManager:
    resource:
      memory: "2048m"
      cpu: 1
  job:
    jarURI: local:///opt/flink/usrlib/flink-kubernetes-tutorial.jar
    parallelism: 4
    state: running
    upgradeMode: stateless
  ingress:
    className: nginx
    template: "[***HOSTNAME***]/{{namespace}}/{{name}}(/|$)(.*)"
    annotations:
      nginx.ingress.kubernetes.io/rewrite-target: "/$2"
You can use the following command to create the new deployment:
kubectl -n flink apply -f flink-deployment.yaml
The Flink Operator will automatically create the Ingress resources specified when creating the deployment. If you inspect the newly created Ingress resource, it should look something like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
	nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: flink-kubernetes-tutorial
  namespace: flink
spec:
  rules:
  - http:
  	paths:
  	- backend:
      	service:
        	name: flink-kubernetes-tutorial-rest
        	port:
          	number: 8081
    	path: /flink/flink-kubernetes-tutorial(/|$)(.*)
    	pathType: ImplementationSpecific

You can see that the Operator has replaced the template /{{namespace}}/{{name}}(/|$)(.*) with /flink/flink-kubernetes-tutorial(/|$)(.*) which corresponds to the namespace and name of the job. This makes it easier to run multiple jobs with the same ingress configuration, even in multiple namespaces.

You can also notice that two Regex capturing groups are specified in the path filter. The nginx.ingress.kubernetes.io/rewrite-target annotation instructs the Ingress controller to rewrite the URI path to only contain characters matched by the second capture group (in this example, (.*)).

This will re-write the path of http://localhost/flink/flink-kubernetes-tutorial/#/job/running to simply be /#/job/running when routing it to the Flink service.

You can further customize it using the template template: "flink.mydomain.com/{{namespace}}/{{name}}(/|$)(.*)". This will add the host flink.mydomain.com to the rules list and allows for even greater freedom of configuration.