
# 为Nginx Ingress配置一致性哈希负载均衡
原生的Nginx支持多种负载均衡规则，其中常用的有加权轮询、IP hash等。Nginx Ingress在原生的Nginx能力基础上，支持使用一致性哈希方法进行负载均衡。
Nginx默认支持的IP hash方法使用的是线性的hash空间，根据IP的hash运算值来选取后端的目标服务器。但是这种方法在添加删除节点时，所有IP值都需要重新进行hash运算，然后重新路由，这样的话就会导致大面积的会话丢失或缓存失效，因此Nginx Ingress引入了一致性哈希来解决这一问题。
一致性哈希是一种特殊的哈希算法，通过构建环状的hash空间来替代普通的线性hash空间，在增删节点时仅需要将路由的目标按顺时针原则向下迁移，而其他路由无需改变，可以尽可能地减少重新路由，有效解决动态增删节点带来的负载均衡问题。
通过配置一致性哈希规则，在增加一台服务器时，新的服务器会尽量分担其他所有服务器的压力；同样，在减少一台服务器时，其他所有服务器也可以尽量分担它的资源，可以有效减少集群局部节点的压力，防止由于某一节点宕机带来的集群雪崩效应。
#### 配置一致性哈希规则
Nginx Ingress可以通过"nginx.ingress.kubernetes.io/upstream-hash-by"注解实现一致性哈希规则的配置，如下所示：
1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)，使用kubectl连接集群。
2. 创建名为"**ingress-test.yaml** "的YAML文件，此处文件名可自定义。
   
   ```
   vi ingress-test.yaml
   ```
   **1.23及以上版本集群** ：
   ```
   apiVersion: networking.k8s.io/v1
   kind: Ingress 
   metadata: 
     name: ingress-test
     namespace: default
     annotations:
       nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"  #按照请求uri进行hash
   spec:
     rules:
       - host: ''
         http:
           paths:
             - path: '/'
               backend:
                 service:
                   name: <your_service_name>  #替换为您的目标服务名称
                   port:
                     number: <your_service_port>  #替换为您的目标服务端口
               property:
                 ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
               pathType: ImplementationSpecific
     ingressClassName: nginx
   ```
   **1.21及以下版本集群** ：
   ```
   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"  #按照请求uri进行hash
   spec:
     rules:
       - host: ''
         http:
           paths:
             - path: '/'
               backend:
                 serviceName: <your_service_name>  #替换为您的目标服务名称
                 servicePort: <your_service_port>  #替换为您的目标服务端口
   ```
   注解"nginx.ingress.kubernetes.io/upstream-hash-by"的参数值支持nginx参数、文本值或任意组合，例如：
   - nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"代表按照请求uri进行hash。
   
   - nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri$host"代表按照请求uri和域名进行hash。
   
   - nginx.ingress.kubernetes.io/upstream-hash-by: "${request_uri}-text-value"代表按照请求uri和文本值进行hash。
    
   
   
3. 创建Ingress。 
   ```
   kubectl create -f ingress-test.yaml
   ```
   回显类似如下，表示Ingress服务已创建。
   ```
   ingress.networking.k8s.io/ingress-test created
   ```
   
   
4. 查看已创建的Ingress。 
   ```
   kubectl get ingress
   ```
   回显如下，表示Ingress服务创建成功。
   ```
   NAME          CLASS   HOSTS     ADDRESS          PORTS   AGE
   ingress-test  nginx   *         121.**.**.**     80      10s
   ```
   
   
 
#### 相关文档
[Custom NGINX upstream hashing](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#custom-nginx-upstream-hashing)
