更新时间:2024-09-29 GMT+08:00

为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连接集群,使用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/ingress-test created

  4. 查看已创建的Ingress。

    kubectl get ingress

    回显如下,表示Ingress服务创建成功。

    NAME          CLASS   HOSTS     ADDRESS          PORTS   AGE
    ingress-test  nginx   *         121.**.**.**     80      10s