Ingress tutorials

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 Jump to heading

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

To route traffic by hostname:

  1. On your DNS server, creat an A record that maps the hostname, for example example.com, 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 Deployment and Service resources. Here, we define an example application using the jmalloc/echo-server Docker container image:

    example-deployment.yaml
    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
    example-deployment.yaml
    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.

    nix
    kubectl apply -f example-deployment.yaml
    nix
    kubectl apply -f example-deployment.yaml
  4. Create an Ingress resource. 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
    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
    example-ingress.yaml
    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.

    nix
    kubectl apply -f example-ingress.yaml
    nix
    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:

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

    Port 80 has been mapped to NodePort 30000:

    output
    text
    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
    output
    text
    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 Jump to heading

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 applications.

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 resource, 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
    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
    example-ingress.yaml
    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:

    nix
    kubectl apply -f example-ingress.yaml
    nix
    kubectl apply -f example-ingress.yaml
  4. Optional: Add another rule that does not specify a host field. This rule would create a fallback that would handle all of the HTTP requests that have a hostname that does not match the other rules. For example:

    example-ingress.yaml
    yaml
    - host:
    http:
    paths:
    - path: "/"
    pathType: Prefix
    backend:
    service:
    name: fallback-service
    port:
    number: 8080
    example-ingress.yaml
    yaml
    - host:
    http:
    paths:
    - path: "/"
    pathType: Prefix
    backend:
    service:
    name: fallback-service
    port:
    number: 8080

Route HTTP traffic based on the requested URL path Jump to heading

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, you could route them to a service named music-service. You can combine this technique with routing by hostname.

To route traffic by URL path:

  1. Create an Ingress resource and include both a path field that sets the target URL path and a pathType field set to Prefix. In the example below, we route any request with a path beginning with /music to music-service. This applies to paths like /music/playlists/1, for instance.

    example-ingress.yaml
    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
    example-ingress.yaml
    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
  2. 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
    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
    example-ingress.yaml
    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
  3. Deploy this to your Kubernetes cluster using kubectl.

    nix
    kubectl apply -f example-ingress.yaml
    nix
    kubectl apply -f example-ingress.yaml
  4. 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:

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

    Port 80 has been mapped to NodePort 30000:

    output
    text
    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
    output
    text
    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

Do you have any suggestions on how we can improve the content of this page?