Nginx Ingress Controller使用建议

Nginx Ingress Controller使用建议

更新时间:

Nginx Ingress Controller是部署于集群内部的Ingress控制器,可以为您提供性能更好且定制性更高的使用方式。在社区版本的基础上,ACK集群提供的Nginx Ingress Controller整合了阿里云产品的一系列功能,提供更加便捷的使用体验。由于Nginx Ingress Controller部署在集群内部,因此它的稳定性与使用时的配置、当前集群状态密切相关。本文介绍Nginx Ingress Controller的使用建议,您可以参考以下使用建议,对集群内的Ingress Controller进行配置,获得最佳的使用效果。

索引

提升Nginx Ingress Controller的性能和稳定性

使用合适的副本数和资源限制

默认情况下,通过集群创建或从组件中心安装的Nginx Ingress Controller的副本数为2,您可以根据业务的实际需要进行调整。

在部署Nginx Ingress Controller时,请确保Nginx Ingress Controller分布在不同的节点上,避免不同Nginx Ingress Controller之间资源的抢占和单点故障。您也可以为其使用独占节点来保证性能与稳定性,具体操作,请参见 使用独占节点保证Nginx Ingress性能与稳定性 。同时建议您不要为Nginx Ingress Controller设定资源限制,避免OOM所带来的流量中断。如果确实有限制的需要,建议资源限制CPU不低于1000 Milicore(YAML配置里格式为 1000m )和内存不低于2 GiB。

使用独占节点来提升Nginx Ingress性能与稳定性

优化Nginx Ingress性能

Nginx Ingress Controller性能调优主要分为系统参数调优和Nginx参数调优:

  • 系统参数调优:阿里云上的操作系统已经默认优化了一些常见参数,其他还需要调优的系统参数主要包括系统最大Backlog数和可用端口的最大范围。系统参数调优后可以保证Nginx处理高并发请求的能力,以及在连接后端时不会因为端口耗尽而失败。

  • Nginx参数调优:

    • 调整单个Worker的最大连接数:Nginx参数主要可以调整单个Worker的最大连接数来保证Nginx Ingress Controller处理高并发请求的能力。

    • 增加连接超时时间:Nginx Ingress Controller与Nginx默认表现不同,会使用长连接对后端业务Pod发起请求,因此Nginx参数还需要增加连接超时时间来让单条连接能够处理更多的请求,减少连接创建时的开销。

    • 设置长连接超时时间:请您确保后端的业务长连接的超时时间不低于Nginx Ingress Controller的连接超时时间( ACK集群中默认为900s)。

Nginx Ingress组件默认已经置入了相关的调优项,在一般场景中能够达到较优的表现。如果您有特殊需要,可以通过ConfigMap中的相关字段进一步优化系统参数和Nginx参数。关于ConfigMap的更多信息,请参见 ConfigMaps

对Nginx Ingress Controller配置HPA进行自动扩容

一般情况下,Nginx Ingress Controller已经有足够的能力应对业务的突发流量。如果在高负载情况下仍不满足您的要求,也可以配置HPA对Nginx Ingress Controller进行扩容。具体操作,请参见 使用容器水平伸缩(HPA)

重要

在Pod扩缩容时可能会导致部分业务连接的中断情况,请谨慎配置。

配置的YAML示例如下所示:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-ingress-controller-hpa
  namespace: kube-system
spec:
   scaleTargetRef:
     apiVersion: apps/v1
     kind: Deployment
     name: nginx-ingress-controller
   minReplicas: 2
   maxReplicas: 5
   metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 50

为后端服务配置合理的preStop Hook

在后端服务滚动更新时,Nginx ingress Controller会将正在终止的Pod的端点摘除,同时保持还在处理的请求的连接。如果后端服务Pod在收到结束信号后立即退出,就可能会导致正在处理的请求失败,或者由于时序问题,部分流量仍被转发到已经退出的Pod中,导致部分流量产生损失。

为了解决滚动更新时流量产生损失的情况,推荐在后端服务的Pod中配置preStop Hook,在端点被摘除后仍继续工作一段时间,解决流量中断的情况。

在Pod模板的容器配置中加入:

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: app
        lifecycle:
          # 配置preStop Hook,等待30秒后退出。
          # 需要容器中存在sleep命令。
          preStop:
            exec:
              command:
              - sleep
              - 30

提升Nginx Ingress Controller的可观测性

使用SLS和阿里云Prometheus服务提升可观测性

Nginx Ingress Controller提供了基于SLS日志以及Prometheus的监控大盘,帮助您更好地了解业务的流量情况。

  • SLS日志:

  • 阿里云Prometheus 监控: 阿里云Prometheus 监控可以在创建集群时选择安装,或者在创建集群后通过 运维管理 > Prometheus监控 安装或查看。具体操作,请参见 使用阿里云Prometheus监控

    说明

    使用 阿里云Prometheus 监控时,请为集群中的Ingress资源添加 host 字段,否则在默认情况下,该Ingress的部分metrics将会缺失。您也可以通过在Nginx Ingress Controller的Deployment中修改 controller 启动参数,加入 --metrics-per-host=false 来解决该问题。

Nginx Ingress Controller进阶功能

使用多套Nginx Ingress Controller

在应用中,您可能会因为内外网隔离等需要,在集群中部署多套Nginx Ingress Controller。具体操作,请参见 部署多个Ingress Controller

在集群内部访问Nginx Ingress Controller

在集群中,LoadBalancer Service的外部地址(Nginx Ingress Controller的公网 IP)通常会被Iptables或IPVS拦截并转发。当 externalTrafficPolicy Local ,且节点上没有对应Nginx Ingress Pod时,会发生网络不通的问题。ACK集群中的Nginx Ingress Controller默认使用了Local模式的LoadBalancer Service,因此在集群内访问Nginx Ingress Controller绑定的CLB地址时,可能会出现网络不通的情况。

建议您在集群内部有访问Nginx Ingress Controller(通过公网IP或绑定公网IP的域名)的需要时,使用Service ClusterIP或内部域名( nginx-ingress-lb.kube-system )访问。同时请避免在Nginx Ingress Controller中对自身进行访问,也可能会因为Hairpin问题导致网络不通。关于该问题的解决方案,请参见 Kubernetes集群中访问LoadBalancer暴露出去的SLB地址不通

使用WAF或透明WAF

为了阻挡恶意请求,您可以在 Web应用防火墙控制台 应用型负载均衡ALB控制台 为集群Nginx Ingress Controller所使用的CLB开启WAF或透明WAF功能。在开启HTTPS端口上的WAF或透明WAF功能时,需要在控制台上配置所使用的证书。这种情况下,可能会出现以下问题:

  • TLS请求会在WAF或透明WAF上进行截断,因此集群内通过Secret配置的证书将不会被暴露在公网出口上。

  • 在集群内通过CLB IP或Service ClusterIP访问443端口可能不会经过WAF或透明WAF,导致证书返回错误。

  • 在开启WAF或透明WAF的情况下,Nginx Ingress Controller将默认无法获得真实的客户端IP。您可以通过在ConfigMap中 ( 通过组件管理安装的Nginx Ingress Controller默认为kube-system命名空间下的nginx-configuration)添加以下内容,配置启用Nginx的Realip模块,使用 X-Forwarded-For 头作为真实客户端地址。

    use-forwarded-headers: "true" # 0.30.0及更旧版本使用该选项。
    enable-real-ip: "true" # 0.44.0及更新版本使用该选项。
    proxy-real-ip-cidr: <您从WAF获取到的回源IP段>

通过Nginx Ingress Controller进行应用的蓝绿或灰度发布

您可以通过 容器服务管理控制台 的灰度发布或手动添加Annotation的方式来使用Nginx Ingress Controller提供的灰度功能,具体操作,请参见 通过Nginx Ingress实现灰度发布和蓝绿发布

重要

请确保需要灰度所使用的服务(包括原服务和灰度服务)没有同时被灰度Ingress以外的Ingress资源引用。否则,可能会出现灰度规则的冲突,从而引发流量路由错误。

通过Nginx Ingress Controller代理非HTTP请求

Nginx Ingress Controller默认使用HTTP协议连接到后端服务,但同时提供了对多种后端协议的支持,其中比较常用的协议有WebSocket、HTTPS和gRPC。关于支持的后端协议具体类型,请参见 Backend Protocol

  • WebSocket:Nginx Ingress Controller提供了对WebSocket的原生支持,您不需要进行任何配置即可转发WebSocket连接。如果您有持续较长的WebSocket连接,可以通过Annotation适当地调整后端连接的超时时间,防止业务因为超时而断连。关于调整的具体操作,请参见 Custom timeouts

  • HTTPS:针对使用HTTPS的后端服务,您可以在Ingress中添加 nginx.ingress.kubernetes.io/backend-protocol:"HTTPS" 的Annotation切换为HTTPS连接。

  • gRPC:gRPC仅支持通过TLS端口访问。因此,请确保您的业务通过Nginx Ingress Controller访问gRPC服务时,使用的是加密的TLS端口。关于配置gRPC的具体操作,请参见 在Nginx Ingress Controller后端部署gRPC服务