ingress-nginx 中GRPC服务延迟配置
背景
kubernetes 中部署了grpc长连接服务, 通过ingress-nginx方式对外暴露服务,在使用过程中grpc长连接没有定时发送心跳消息,在没有数据传输的情况下,grpc连接会在60s后自动断开连接。
GRPC 超时配置
出现连接超时问题,首先想到的就是ingress-nginx 配置限制导致的连接超时。
通过查询ingress-nginx官方对于grpc超时时间的配置信息,如下:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#custom-timeouts
官方解释:对于后端协议为GRPC或GRPCS,则继承proxy timeout de peizhi .
- grpc_connect_timeout=5s: from nginx.ingress.kubernetes.io/proxy-connect-timeout
- grpc_send_timeout=60s: from nginx.ingress.kubernetes.io/proxy-send-timeout
- grpc_read_timeout=60s: from nginx.ingress.kubernetes.io/proxy-read-timeout
增加如下配置:
nginx.ingress.kubernetes.io/proxy-connect-timeout: 5 # 建立 TCP 连接的超时时间
nginx.ingress.kubernetes.io/proxy-send-timeout: 60 # 请求发送阶段的超时
nginx.ingress.kubernetes.io/proxy-read-timeout: 60 # 响应接收阶段的超时
结果验证
配置完成后发现并没有解决问题。 问题出在哪里呢。
开始查看nginx配置文件。
proxy_connect_timeout 5s;proxy_send_timeout 60s;proxy_read_timeout 60s;proxy_buffering off;proxy_buffer_size 4k;proxy_buffers 4 4k;proxy_max_temp_file_size 1024m;proxy_request_buffering on;proxy_http_version 1.1;proxy_cookie_domain off;proxy_cookie_path off;
proxy time 的相关配置是正常的。 但是没有grpc timeout相关的配置, 预期与ingress-nginx官网的说法不同。 问题出现在哪了呢??
查询差异
配置问题?
在ingress-nginx中。 nginx.conf 的配置文件是通过模版的方式对ingress配置进行渲染后生成的,所以通过查看模版文件来进一步的查看grpc配置的生成逻辑。 模版文件的默认路径为/etc/nginx/template/nginx.tmpl
。
proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s;proxy_send_timeout {{ $location.Proxy.SendTimeout }}s;proxy_read_timeout {{ $location.Proxy.ReadTimeout }}s;proxy_buffering {{ $location.Proxy.ProxyBuffering }};proxy_buffer_size {{ $location.Proxy.BufferSize }};proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }};{{ if isValidByteSize $location.Proxy.ProxyMaxTempFileSize true }}proxy_max_temp_file_size {{ $location.Proxy.ProxyMaxTempFileSize }};{{ end }}proxy_request_buffering {{ $location.Proxy.RequestBuffering }};proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }};proxy_cookie_domain {{ $location.Proxy.CookieDomain }};proxy_cookie_path {{ $location.Proxy.CookiePath }};
通过模版发现并没有grpc相关的配置模版, 进而怀疑是版本问题开始比对版本。
版本问题!!!!
通过查看ingress-nginx deployment 配置镜像信息得到controller版本:
- image: registry.k8s.io/ingress-nginx/controller:v1.10.1
通过登录pod后执行nginx -v
得到nginx版本(当然这步没啥用):
- nginx version: nginx/1.25.3
对比github https://github.com/kubernetes/ingress-nginx, 当前版本确实是个老版本了。 难道有更新差异?
进一步查看 更新说明 ( https://github.com/kubernetes/ingress-nginx/releases?page=3) ,
发现在1.11.0 版本有个更新: https://github.com/kubernetes/ingress-nginx/pull/11258,添加了 grpc 超时注释 。
到此,定位到是版本差异导致的配置没有生效,那怎么办呢。 升级版本还是??
再次GRPC超时配置
既然GRPC timeout在 1.11.0 以下版本不支持。 但也有其他方式来实现。
参考官网:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#allow-snippet-annotations
首先前提条件是通过配置ingress-nginx configmap, 添加如下参数开启代码片段注释的支持:allow-snippet-annotations
然后配置annotations
支持多种自定义配置。 这里列举了三种。
- nginx.ingress.kubernetes.io/configuration-snippet: 全局http块,影响所有虚拟主机和请求处理。
- nginx.ingress.kubernetes.io/server-snippet: 特定域名的server块,仅影响当前 Ingress 规则的域名。
- nginx.ingress.kubernetes.io/stream-snippet: 添加自定义的stream配置。
nginx.ingress.kubernetes.io/server-snippet: |# gRPC连接超时配置proxy_connect_timeout 10s; # 连接超时proxy_send_timeout 600s; # 发送超时proxy_read_timeout 600s; # 读取超时
待验证。 等我验证完补充。
参考
github issues:
- https://github.com/kubernetes/ingress-nginx/issues/9063
- https://github.com/kubernetes/ingress-nginx/issues/11250