Configuring Consistent Hashing for Load Balancing of an Nginx Ingress
The native Nginx supports multiple load balancing rules, including weighted round robin and IP hash. Nginx Ingress supports load balancing by using consistent hashing based on the native Nginx capabilities.
By default, the IP hash method supported by Nginx uses the linear hash space. The backend server is selected based on the hash value of the IP address. However, when this method is used to add or delete a node, all IP addresses need to be hashed again and then routed again. As a result, a large number of sessions are lost or the cache becomes invalid. Therefore, consistent hashing is introduced to Nginx Ingress to solve this problem.
Consistent hashing is a special hash algorithm, which constructs a ring hash space to replace the common linear hash space. When a node is added or deleted, only the target route is migrated clockwise, and other routes do not need to be changed. In this way, rerouting can be reduced as much as possible, resolving the load balancing issue caused by dynamic node addition and deletion.
If a consistent hashing rule is configured, the newly added server will share the load of all other servers. Similarly, when a server is removed, all other servers can share the load of the removed server. This balances the load among nodes in the cluster and prevents the avalanche effect caused by the breakdown of a node.
Configuring a Consistent Hashing Rule
Nginx Ingress can use the nginx.ingress.kubernetes.io/upstream-hash-by annotation to configure consistent hashing rules. The following is an example:
- Use kubectl to access the cluster. For details, see Connecting to a Cluster Using kubectl.
- Create a YAML file named ingress-test.yaml. The file name can be customized.
vi ingress-test.yaml
For clusters of v1.23 or later:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test namespace: default annotations: nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" # Perform hashing based on the request URI. spec: rules: - host: '' http: paths: - path: '/' backend: service: name: <your_service_name> # Replace it with the name of your target Service. port: number: <your_service_port> # Replace it with the port number of your target Service. property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: nginx
For clusters of v1.21 or earlier:apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-test namespace: default annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" # Perform hashing based on the request URI. spec: rules: - host: '' http: paths: - path: '/' backend: serviceName: <your_service_name> # Replace it with the name of your target Service. servicePort: <your_service_port> # Replace it with the port number of your target Service.
The value of nginx.ingress.kubernetes.io/upstream-hash-by can be an nginx variable, a text value, or any combination:- nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" indicates that requests are hashed based on the request URI.
- nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri$host" indicates that requests are hashed based on the request URI and domain name.
- nginx.ingress.kubernetes.io/upstream-hash-by: "${request_uri}-text-value" indicates that requests are hashed based on the request URI and text value.
- Create an ingress.
kubectl create -f ingress-test.yaml
If information similar to the following is displayed, the ingress has been created:
ingress/ingress-test created
- Check the created ingress.
kubectl get ingress
If information similar to the following is displayed, the ingress has been created:
NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test nginx * 121.**.**.** 80 10s
Documentation
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.