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有较高稳定性要求,可以为其分配独占节点以避免资源的抢占。具体操作,请参见 部署高可靠的Nginx 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的具体操作,请参见 在Nginx Ingress Controller后端部署gRPC服务 。