如果您的Nginx Ingress Controller经常面临高负载,可以从集群网络插件、节点规格和Controller配置等方面进行调整以提高性能。本文介绍如何配置高性能Nginx Ingress Controller。
本文中的配置方法仅供您参考思路,具体是否使用某个配置,以及各项参数与规格的选择,请您实际结合Controller负载进行选择。
容器网络插件
集群的容器网络插件(CNI Plugin)配置会影响集群内网络通信性能,进而影响Nginx Ingress Controller的性能表现。推荐您使用Terway作为容器网络插件。如果您对网络性能有更高要求,可以考虑使用Terway独占ENI模式,但该模式会导致单节点Pod上限较少。关于Terway的更多信息,请参见使用Terway网络插件。
节点规格选择
Nginx Ingress Controller所属Pod的网络性能受节点规格限制。例如,节点PPS为30万时,Controller单Pod的PPS上限即为30万。建议选择以下高性能ECS规格:
计算型实例:ecs.c6e.8xlarge(32核64GB,600万PPS)
网络型实例:ecs.g6e.8xlarge(32核128GB,600万PPS)
关于ECS实例规格的更多信息,请参见实例规格族。
Nginx Ingress Controller组件配置
负载均衡实例规格
Nginx Ingress Controller使用一个CLB实例对外接收请求,CLB实例的规格会影响Controller的性能。您可在Nginx Ingress Controller所属的Service中使用Annotations指定CLB规格。
Pod独占节点
由于Nginx的基础开销,在资源总量相同的情况下,单个高规格Pod(例如32核)的性能表现优于多个低规格Pod(例如两个16核的Pod)。因此,在保证高可用的前提下,您可使用少量高规格Pod而不是多个更低规格的Pod。
例如,您可创建一个高规格但仅有少量节点的节点池,并通过污点与容忍度配置使其中的每个节点被单个Controller Pod独占。这样的部署方式可以使Nginx Ingress Controller最大化利用资源,并且不受集群内其他应用的影响。
关闭指标采集
Nginx Ingress Controller默认采集指标供其他组件使用,但采集消耗一定的CPU资源,如果不需要获取指标,建议关闭采集。通过在Nginx启动参数中添加--enable-metrics=false
,即可关闭所有指标采集。
v1.9.3以上版本的Nginx Ingress Controller还添加了一些自定义指标采集参数。例如,添加--exclude-socket-metrics
后,即可停止采集Socket相关指标。关于启动参数的更多信息,请参见cli-arguments。
调整超时策略
您可通过减少FIN_WAIT2与TIME_WAIT状态的超时时间,使Nginx Ingress Controller更快地关闭已完成数据发送的连接,降低资源占用。
在Nginx Ingress Controller中,相关的配置为:
net.ipv4.tcp_fin_timeout
:FIN_WAIT2状态的超时时间,默认为60秒。net.netfilter.nf_conntrack_tcp_timeout_time_wait
:TIME_WAIT状态下的连接保持时间,默认为60秒。
FIN_WAIT2与TIME_WAIT是容器内核的配置,修改后会显著影响Nginx Ingress Controller的表现。如果您需要对此进行修改,请确保您已经了解TCP连接相关原理,并在修改后持续观察连接状态和资源使用情况,确保调整安全有效。
ConfigMap配置
Nginx Ingress Controller的全局配置保存在ConfigMap中。您可执行以下命令,编辑ConfigMap。
kubectl edit cm -n kube-system nginx-configuration
配置项说明
ConfigMap中的关键配置项说明如下。
配置项 | 配置参数 | 描述 |
下游 |
| 下游 |
| 下游 | |
上游 |
| 最大上游 |
| 允许的最大上游 | |
| 上游 | |
| 上游 | |
单个Worker最大连接 |
| 单个Worker支持的最大连接数。 |
超时配置 说明 可根据实际业务场景调整,按需配置。 |
| 建立TCP连接的超时时间,单位为秒。 |
| 读取数据的超时时间,单位为秒。 | |
| 发送数据的超时时间,单位为秒。 | |
优化重试机制 说明 当后端服务异常情况下,多级重试的过多请求可能加重后端服务的负载引发雪崩问题。更多详情请参见Ingress-nginx官方文档。 |
| 失败后的重试次数,默认为3次,包括1次初始请求和2次重试。 |
| 指定重试条件,设置为off则关闭重试功能。 | |
| 指定请求重试的超时时间,单位为秒,根据实际应用场景进行调整。 |
配置日志自动轮转
Nginx Ingress Controller Pod默认将日志记录到/dev/stdout
。随着日志文件逐渐增大,记录新日志耗费的资源也会更多。通过定时轮转日志,即将一个时间段中的日志保存到独立文件中,并清除原有日志记录的方法,可降低记录日志的资源消耗。
以SSH方式登录部署Nginx Ingress Controller Pod的ECS节点。具体操作,请参见通过密钥认证登录Linux实例。
在
/root
目录下添加文件nginx-log-rotate.sh
。containerd节点
#!/bin/bash # 最多保留日志文件个数,可根据需求进行调整。 keep_log_num=5 #获取所有运行中的ingress-nginx容器ID ingress_nginx_container_ids=$(crictl ps | grep nginx-ingress-controller | grep -v pause | awk '{print $1}') if [[ -z "$ingress_nginx_container_ids" ]]; then echo "error: failed to get ingress nginx container ids" exit 1 fi # 随机睡眠5~10秒。 sleep $(( RANDOM % (10 - 5 + 1 ) + 5 )) for id in $ingress_nginx_container_ids; do crictl exec $id bash -c "cd /var/log/nginx; if [[ \$(ls access.log-* | wc -l) -gt $keep_log_num ]]; then rm -f \$(ls -t access.log-* | tail -1); fi ; mv access.log access.log-\$(date +%F:%T) ; kill -USR1 \$(cat /tmp/nginx/nginx.pid)" done
Docker节点
#!/bin/bash # 最多保留日志文件个数,可根据需求进行调整。 keep_log_num=5 #获取所有运行中的ingress-nginx容器ID ingress_nginx_container_ids=$(docker ps | grep nginx-ingress-controller | grep -v pause | awk '{print $1}') if [[ -z "$ingress_nginx_container_ids" ]]; then echo "error: failed to get ingress nginx container ids" exit 1 fi # 随机睡眠5~10秒。 sleep $(( RANDOM % (10 - 5 + 1 ) + 5 )) for id in $ingress_nginx_container_ids; do docker exec $id bash -c "cd /var/log/nginx; if [[ \$(ls access.log-* | wc -l) -gt $keep_log_num ]]; then rm -f \$(ls -t access.log-* | tail -1); fi ; mv access.log access.log-\$(date +%F:%T) ; kill -USR1 \$(cat /tmp/nginx/nginx.pid)" done
执行以下命令,对
nginx-log-rotate.sh
文件添加可执行权限。chmod 755 /root/nginx-log-rotate.sh
在
/etc/crontab
文件结尾添加以下内容:*/15 * * * * root /root/nginx-log-rotate.sh
说明此示例使用Cron表达式,每15分钟对日志轮转一次,您可根据实际需求进行调整。
启用Brotli压缩
压缩是一种通过牺牲CPU时间来节省大量网络带宽的通用方法,能够提升吞吐量。Brotli是Google开发的一种压缩算法。相较于常用的gzip
压缩算法(Nginx Ingress Controller默认使用gzip
),Brotli在文本类数据(如网页资源)上的压缩率通常比 gzip 高约 15%~30%,但具体提升取决场景的详细情况。在Nginx Ingress中启用Brotli压缩,需要配置以下参数。
enable-brotli
: 是否启用Brotli压缩算法,取值为true
或false
。brotli-level
: 压缩级别,范围是1到11,默认是4。级别越高,CPU性能消耗越大。brotli-types
: 指定使用Brotli即时压缩的MIME类型。
您可通过在ConfigMap中添加以下配置启用Brotli压缩:
data:
enable-brotli: "true"
brotli-level: "6"
brotli-types: "text/xml image/svg+xml application/x-font-ttf image/vnd.microsoft.icon application/x-font-opentype application/json font/eot application/vnd.ms-fontobject application/javascript font/otf application/xml application/xhtml+xml text/javascript application/x-javascript text/plain application/x-font-truetype application/xml+rss image/x-icon font/opentype text/css image/x-win-bitmap"
HTTPS性能优化
为了提升Nginx ingress Controller的HTTPS的性能,可以配置以下参数:SSL 会话缓存、OCSP Stapling、TLS 1.3 早期数据以及调整密码套件优先级。
SSL会话缓存与超时
设置SSL 共享会话缓存的大小以及重用缓存中存储的会话参数的时间,可以减少SSL握手的开销。
ConfigMap配置:
data: ssl-session-cache-size: "10m" ssl-session-timeout: "10m"
对应Nginx侧的
nginx.conf
配置,可以根据实际场景需求调整。ssl_session_cache shared:SSL:120m; # 1m 4000个。 ssl_session_timeout 1h; # 会话超时时间为1小时。
启用OCSP Stapling
使用OCSP Stapling可以减少客户端证书验证的时间。
data: enable-ocsp: "true"
支持TLS 1.3早期数据(0-RTT)
启用TLS 1.3的0-RTT功能可以允许客户端在握手完成之前就发送数据,从而减少连接建立的延迟。
data: ssl-early-data: "true" ssl-protocols: "TLSv1.3"
调整Cipher优先级(无需手动调优)
通过调整加密套件的优先级,可以有效降低延迟。Nginx Ingress Controller的默认配置已进行了优化。
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers on; # 优先使用服务器端的Cipher配置。