如何控制vhost_shared_traffic内存K8s nginx ingress?

How to control vhost_shared_traffic memory K8s nginx ingress?

背景

我们 运行 一个处理多个 php/lumen 微服务的 kubernetes 集群。我们开始看到应用程序 php-fpm/nginx 在其日志中报告 499 状态代码,这似乎与客户端收到空白响应 (curl returns curl: (52) Empty reply from server) 而应用程序记录 499 相对应。

10.10.x.x - - [09/Mar/2020:18:26:46 +0000] "POST /some/path/ HTTP/1.1" 499 0 "-" "curl/7.65.3"

我的理解是nginx会return客户端socket时的499码不再是open/available到return的内容。在这种情况下,在 nginx/application 层终止此连接之前似乎意味着什么。我们目前的配置是:

ELB -> k8s nginx ingress -> 应用程序

所以我的想法是 ELB 或入口,因为应用程序没有留给 return 的套接字。所以我开始访问入口日志...

潜在的核心问题?

在查看入口日志时,我看到了其中的一些:

2020/03/06 17:40:01 [crit] 11006#11006: ngx_slab_alloc() failed: no memory in vhost_traffic_status_zone "vhost_traffic_status"

可能的解决方案

我想如果我给 vhost_traffic_status_zone 一些更多的内存至少那个错误会消失并继续寻找下一个错误..但我似乎找不到任何允许的 configmap 值或注释我来控制这个。我检查了文档:

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

提前感谢您提供我可能遗漏的任何见解/建议/文档!

这是查找如何在入口控制器中修改 nginx.conf 的标准方法。之后,我将 link 在一些信息中提供有关您应该为该区域分配多少内存的建议。

首先通过检查部署上的图像版本来获取入口控制器版本 kubectl -n <namespace> get deployment <deployment-name> | grep 'image:'

从那里,您可以从以下 URL 检索您的版本的代码。在下文中,我将使用版本 0.10.2。 https://github.com/kubernetes/ingress-nginx/releases/tag/nginx-0.10.2

nginx.conf 模板可以在代码中的 rootfs/etc/nginx/template/nginx.tmpl 或 pod 中的 /etc/nginx/template/nginx.tmpl 中找到。这可以被 grepped 为感兴趣的行。在示例案例中,我们在 nginx.tmpl

中找到以下行

vhost_traffic_status_zone shared:vhost_traffic_status:{{ $cfg.VtsStatusZoneSize }};

这为我们提供了在代码中查找的配置变量。我们对 VtsStatusZoneSize 的下一个 grep 将我们带到 internal/ingress/controller/config/config.go

中的行
    // Description: Sets parameters for a shared memory zone that will keep states for various keys. The cache is shared between all worker processe
    // https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_zone
    // Default value is 10m
    VtsStatusZoneSize string `json:"vts-status-zone-size,omitempty"

这为我们提供了要添加到配置映射 "ingress-nginx-ingress-controller" 的密钥 "vts-status-zone-size"。当前值可以在 /etc/nginx/nginx.conf.

的 pod 上呈现的 nginx.conf 模板中找到

当谈到您可能想要设置区域的大小时,这里有文档建议将其设置为 2*usedSize:

If the message("ngx_slab_alloc() failed: no memory in vhost_traffic_status_zone") printed in error_log, increase to more than (usedSize * 2).

https://github.com/vozlt/nginx-module-vts#vhost_traffic_status_zone

"usedSize" 可以通过点击 nginx 的统计页面或通过 JSON 端点找到。这是获取统计数据的 JSON 版本的请求,如果您有 jq 值的路径:curl http://localhost:18080/nginx_status/format/json 2> /dev/null | jq .sharedZones.usedSize

希望对您有所帮助。