Ingress tutorials
Load balance HTTP
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:
-
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. -
Define the application you will deploy to Kubernetes by creating
DeploymentandServiceresources. Here, we define an example application using thejmalloc/echo-serverDocker container image:example-deployment.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:labels:run: appname: appspec:replicas: 1selector:matchLabels:run: apptemplate:metadata:labels:run: appspec:containers:- name: appimage: jmalloc/echo-serverports:- containerPort: 8080readinessProbe:httpGet:path: /port: 8080initialDelaySeconds: 5periodSeconds: 5successThreshold: 1---apiVersion: v1kind: Servicemetadata:name: example-servicespec:selector:run: appports:- name: httpprotocol: TCPport: 8080targetPort: 8080example-deployment.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:labels:run: appname: appspec:replicas: 1selector:matchLabels:run: apptemplate:metadata:labels:run: appspec:containers:- name: appimage: jmalloc/echo-serverports:- containerPort: 8080readinessProbe:httpGet:path: /port: 8080initialDelaySeconds: 5periodSeconds: 5successThreshold: 1---apiVersion: v1kind: Servicemetadata:name: example-servicespec:selector:run: appports:- name: httpprotocol: TCPport: 8080targetPort: 8080 -
Deploy this to your Kubernetes cluster using
kubectl.nixkubectl apply -f example-deployment.yamlnixkubectl apply -f example-deployment.yaml -
Create an Ingress resource. Include a
hostfield in your routing rule. Below, we set the host toexample.comand the service name toexample-service:example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080 -
Deploy this to your Kubernetes cluster using
kubectl.nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yaml -
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:nixkubectl get service haproxy-kubernetes-ingress --namespace haproxy-controllernixkubectl get service haproxy-kubernetes-ingress --namespace haproxy-controllerPort 80 has been mapped to NodePort 30000:
outputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhaproxy-kubernetes-ingress NodePort 10.101.116.157 <none> 80:30000/TCP,443:31962/TCP,1024:31675/TCP 97moutputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhaproxy-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:
-
On your DNS server, creat an A or CNAME record that maps the hostnames to your Kubernetes cluster.
-
In the Ingress resource, prepare the
rulessection by creating a separate rule for each hostname. In the example below, we specify that requests formusic.example.comwill go tomusic-service, while requests forbooks.example.comwill go tobooks-service:example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- host: "music.example.com"http:paths:- path: /pathType: Prefixbackend:service:name: music-serviceport:number: 8080- host: "books.example.com"http:paths:- path: /pathType: Prefixbackend:service:name: books-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- host: "music.example.com"http:paths:- path: /pathType: Prefixbackend:service:name: music-serviceport:number: 8080- host: "books.example.com"http:paths:- path: /pathType: Prefixbackend:service:name: books-serviceport:number: 8080 -
Deploy it with
kubectl:nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yaml -
Optional: Add another rule that does not specify a
hostfield. 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.yamlyaml- host:http:paths:- path: "/"pathType: Prefixbackend:service:name: fallback-serviceport:number: 8080example-ingress.yamlyaml- host:http:paths:- path: "/"pathType: Prefixbackend:service:name: fallback-serviceport: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:
-
Create an Ingress resource and include both a
pathfield that sets the target URL path and apathTypefield set to Prefix. In the example below, we route any request with a path beginning with/musictomusic-service. This applies to paths like/music/playlists/1, for instance.example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- http:paths:- path: /musicpathType: Prefixbackend:service:name: music-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxyrules:- http:paths:- path: /musicpathType: Prefixbackend:service:name: music-serviceport:number: 8080 -
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 thepath-rewriteannotation to a regular expression. Using the example below, a request for/music/playlists/1would be rewritten to/playlists/1:example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/path-rewrite: /music/(.*) /\1spec:ingressClassName: haproxyrules:- http:paths:- path: /musicpathType: Prefixbackend:service:name: music-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/path-rewrite: /music/(.*) /\1spec:ingressClassName: haproxyrules:- http:paths:- path: /musicpathType: Prefixbackend:service:name: music-serviceport:number: 8080 -
Deploy this to your Kubernetes cluster using
kubectl.nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yaml -
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:nixkubectl get service haproxy-kubernetes-ingress --namespace haproxy-controllernixkubectl get service haproxy-kubernetes-ingress --namespace haproxy-controllerPort 80 has been mapped to NodePort 30000:
outputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhaproxy-kubernetes-ingress NodePort 10.101.116.157 <none> 80:30000/TCP,443:31962/TCP,1024:31675/TCP 97moutputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhaproxy-kubernetes-ingress NodePort 10.101.116.157 <none> 80:30000/TCP,443:31962/TCP,1024:31675/TCP 97m
Change the load balancing algorithm for a specific service Jump to heading
By default, the ingress controller uses the round-robin algorithm to distribute requests across a service’s pods. To change the algorithm for a specific service:
-
Edit the Ingress resource and set the
load-balanceannotation to your chosen algorithm. Below, we set the service to use therandomalgorithm:example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:load-balance: randomspec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:load-balance: randomspec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080 -
Apply the change with
kubectl apply:nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yaml
Enable sticky sessions (session persistence) Jump to heading
In some cases, you may need to route all of a client’s requests to the same backend pod. For example, if that pod has stored the client’s server-side session, you would want to use that same pod, rather than load balance their requests across multiple pods. This is called sticky sessions. To enable it for a service:
-
In the Ingress resource, set the
cookie-persistenceannotation to a unique name, which the ingress controller uses when naming the HTTP cookie it stores in the client’s browser. The cookie will contain the selected pod’s IP address, port, and a secret key.example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:cookie-persistence: "example-session-persistence-cookie"spec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:cookie-persistence: "example-session-persistence-cookie"spec:ingressClassName: haproxyrules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080 -
Apply the change with
kubectl apply:nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yaml
Do you have any suggestions on how we can improve the content of this page?