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性能与稳定性
如果您对Ingress Controller有较高稳定性要求,可以为其分配独占节点以避免资源的抢占。具体操作,请参见部署高可靠Ingress Controller。
对于高负载场景,您也可以通过设置Ingress Controller来支撑高负载应用。具体操作,请参见部署高负载场景的Nginx Ingress Controller。
优化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日志:
创建集群时,如果您已经选中了启用日志组件及Ingress Dashboard,您就可以直接通过容器服务管理控制台 页面的Ingress概览中查看到基于SLS日志服务提供的大盘服务;您也可以直接在 查看到Nginx Ingress Controller产生的相关日志。具体操作,请参见Nginx Ingress访问日志分析与监控。
如果您在创建时没有选中日志以及Ingress的相关选项,也可以手动配置日志收集组件和规则。具体操作,请参见Nginx Ingress访问日志分析与监控。关于监控的更多信息,请参见Ingress Dashboard监控。
阿里云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的具体操作,请参见通过Ingress Controller实现gRPC服务访问。