HAProxy Kubernetes Ingress Controller Documentation 1.7

Route HTTP traffic

In this section, you will learn how to define Ingress rules that state how traffic should be routed within your Kubernetes cluster. Ultimately, HAProxy Kubernetes Ingress Controller will implement those rules.

Route HTTP traffic based on the requested hostname

In this section, you’ll learn how to direct traffic based on the hostname the client requests. For example, if they request example.com, their traffic will be relayed to a service named example-service.

To route traffic by hostname:

  1. On your DNS server, creat an A or CNAME record that maps the hostname to your Kubernetes cluster. In a cloud environment, this IP address will be assigned to the cloud load balancer in front of your Kubernetes cluster. In an on-premises environment, this may be the address of an external load balancer like HAProxy, set to load balance traffic across your Kubernetes nodes.

  2. Define the application you will deploy to Kubernetes by creating YAML Deployment and Service resources. Here, we define an example app using the jmalloc/echo-server container image.

    example-app.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: app
      name: app
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: app
      template:
        metadata:
          labels:
            run: app
        spec:
          containers:
          - name: app
            image: jmalloc/echo-server
            ports:
            - containerPort: 8080
            readinessProbe:
              httpGet:
                path: /
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
              successThreshold: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
        name: example-service
    spec:
        selector:
          run: app
        ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
  3. Deploy this to your Kubernetes cluster using kubectl.

    $ kubectl apply -f example-app.yaml
  4. Create an Ingress resource and include a host field in your routing rule. Below, we set the host to example.com and the service name to example-service:

    example-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      ingressClassName: haproxy
      rules:
      - host: "example.com"
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 8080
  5. Deploy this to your Kubernetes cluster using kubectl.

    $ kubectl apply -f example-ingress.yaml
  6. If you deployed the ingress controller service using a NodePort, then you can access the example service at the NodePort HTTP port. For example, http://example.com:30000/. To find which NodePort port has been assigned, view the service’s status:

    $ kubectl get service haproxy-kubernetes-ingress --namespace haproxy-controller

    output

    NAME                         TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                     AGE
    haproxy-kubernetes-ingress   NodePort   10.101.116.157   <none>        80:30000/TCP,443:31962/TCP,1024:31675/TCP   97m
    

Route HTTP traffic to multiple hostnames at the same IP address

This section describes how to implement routing for multiple hostnames using the ingress controller.

Because the ingress controller receives all ingress traffic at its IP address before relaying it to the appropriate service in the cluster, you can define multiple hostnames in your Ingress resources to route traffic for various teams.

To define more than one hostname in an Ingress resource:

  1. On your DNS server, creat an A or CNAME record that maps the hostnames to your Kubernetes cluster.

  2. In the Ingress YAML, prepare the rules section by creating a separate rule for each hostname. In the example below, we specify that requests for music.example.com will go to music-service, while requests for books.example.com will go to books-service.

    example-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      ingressClassName: haproxy
      rules:
      - host: "music.example.com"
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: music-service
                port:
                  number: 8080
      - host: "books.example.com"
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: books-service
                port:
                  number: 8080
  3. Deploy it with kubectl:

    $ kubectl apply -f example-ingress.yaml
  4. Optional: Add another rule that does not specify a host field. This rule would handle all the HTTP requests whose hostname does not match the other rules, for example:

    - host: 
      http:
        paths:
        - path: "/"
          pathType: Prefix
          backend:
            service:
              name: miscellaneous-service
              port:
                number: 8080

Route HTTP traffic based on the requested URL path

In this section, you’ll learn how to direct traffic based on the URL path the client requests. For example, if they request example.com/music, their traffic will be relayed to a service named music-service. You can combine this technique with routing by hostname.

To route traffic by path:

  1. Define the application you will deploy to Kubernetes by creating YAML Deployment and Service resources. Here, we define an example app using the jmalloc/echo-server container image.

    example-app.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: app
      name: app
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: app
      template:
        metadata:
          labels:
            run: app
        spec:
          containers:
          - name: app
            image: jmalloc/echo-server
            ports:
            - containerPort: 8080
            readinessProbe:
              httpGet:
                path: /
                port: 8080
              initialDelaySeconds: 5
              periodSeconds: 5
              successThreshold: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
        name: music-service
    spec:
        selector:
          run: app
        ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
  2. Deploy this to your Kubernetes cluster using kubectl.

    $ kubectl apply -f example-app.yaml
  3. Create an Ingress resource and include both a path field that sets the target path and a pathType field set to Prefix. Below, we route any request with a path beginning with music to music-service. This applies to paths like /music/playlists/1, for example.

    example-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
    spec:
      ingressClassName: haproxy
      rules:
      - http:
          paths:
          - path: /music
            pathType: Prefix
            backend:
              service:
                name: music-service
                port:
                  number: 8080
  4. Optional: Rewrite the request’s path to remove the prefix. In many cases, you will receive HTTP requests at a prefix path, such as /music, but you will want to strip that off of the URL before the backend application processes it. To do so, set the path-rewrite annotation to a regular expression. Using the example below, a request for /music/playlists/1 would be rewritten to /playlists/1:

    example-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
      annotations:
         haproxy.org/path-rewrite: /music/(.*) /\1
    spec:
      ingressClassName: haproxy
      rules:
      - http:
          paths:
          - path: /music
            pathType: Prefix
            backend:
              service:
                name: music-service
                port:
                  number: 8080
  5. Deploy this to your Kubernetes cluster using kubectl.

    $ kubectl apply -f example-ingress.yaml
  6. If you deployed the ingress controller service using a NodePort, then you can access the example service at the NodePort HTTP port. For example, http://example.com:30000/music. To find which NodePort port has been assigned, view the service’s status:

    $ kubectl get service haproxy-kubernetes-ingress --namespace haproxy-controller

    output

    NAME                         TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                                     AGE
    haproxy-kubernetes-ingress   NodePort   10.101.116.157   <none>        80:30000/TCP,443:31962/TCP,1024:31675/TCP   97m
    

Next up

Terminate SSL / TLS