-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nginx Ingress Pods Consuming Too Much Memory #8166
Comments
@ParagPatil96: The label(s) In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/remove-kind bug What other info is available ? |
NGINX Ingress controller |
@longwuyuan I posted the details here as I found the issue similar to ours. Let me know if you would want me to open a new one with all the details. |
Can you upgrade to latest release and kindly answer the questions I asked earlier. Thank you. |
@longwuyuan I am a co-worker of @rmathagiarun . The details shared by @rmathagiarun were from the latest released controller version v1.1.1, and we see this issue happening frequently. |
Some questions I asked earlier are not answered. Basically, some digging is required and specifics on which process was using memory high should be determined. Along with checking node resources at that point of time. |
I can see that you have suggested us to test using controller version 0.5.x - We have been using v0.48.1 for a long time and have never faced this issue. We had to upgrade to v1.1.1 as v0.48.1(even the suggested version v0.50.x) is not compatible with K8s Version 1.22 and 1.23. The core components of our product has remained the same on both the versions(0.48.1 and v1.1.1) and we are facing this memory issue only with v1.1.1. Unfortunately, the logs doesn't have much info on this memory leak. We were able to find the OOM issue only by using dmesg command inside the pod. I have already shared the ingress logs and Grafana screenshots for the same. Nodes all along had sufficient resources and as you can see from the Grafana Screenshot that the pod is constantly consuming close to 4GB and spike is not specific only during certain operations. |
@longwuyuan Any update on this. I have answered all the queries that you have posted, Let me know if you need any additional info. What other info is available ? You can get some info if you use the documented prometheus+grafana config. Does it happen on controller version 0.50.X What do the logs contain relevant to this. |
@longwuyuan Any update on this. We have been hitting this issue quite frequently. |
Hi, its unfortunate that you have a problem. I have made some attempts to drive this to some resolution but failed. So next attempt I can make is suggest some info gathering. You will requires some kind of a background or will have to get someone who has some kind of a history with performance related troubleshooting. Basically there are some steps like preparations to capture related information on the processes. Then there are some steps for the actual processes running. That is all too elaborate or "unixy" so to speak. Please look at the history of issues weorked on here. We did discover some issues in Lua and nginx and some singnificant changes were made to the base image and components like Lua. Please find those issues and checkout the procedures described there. It included attaching debuggers for specific processes and regular trace/ptrace for controller process. Also, I have no clue as to how many replicas you are running and/or if you are using a daemonset. Maybe its in the info in this issue but its not glaring. My comment summary is get the info likes trace, trace, debugger, and then relate that with statistics from monitoring. Once you can provide a precise step-by-step instruction here, someone can try to reproduce the problem. |
Hi @longwuyuan, The issue can be reproduced by following the below steps,
In our case, the memory spiked from around 0.75GB to 2GB. We also noticed the Nginx process continued to retain the 2GB memory without releasing it back after successful reloads. Attached Prometheus Screenshot for reference
In our case, the memory was back at 0.75GB. However, Nginx required multiple restarts as it wasn't able to load the backend configs. Attaching sample logs and Prometheus screenshot for reference. We tried simulating the same scenario with the latest release helm-chart-4.0.18 and the result was same. Notably, the spike was observed only with backend reloads and without sending any load to endpoints. |
Hi @rmathagiarun , Spike in memory usage is expected in the procedure you have described. I don't see a memory leak or bug in that procedure. Would you like to make the reproduce steps more elaborate and detailed. Something closer to real-use would help the developers. |
Agree that spike in memory usage is expected due to multiple backend reloads. Our concern is why is the Pod not releasing the memory back even after successful reload. The Pod continues to hold the memory until it is restarted. This is a real-case scenario, as we can have multiple ingresses created over a period of time on a cluster. Meanwhile, the Pod will continue to block the memory it consumed during each re-load ultimately causing the Pod to crash due to OOM. |
|
@rmathagiarun @longwuyuan we see the same behavior after upgrading the ingress helm chart to 4.0.17. |
I am not certain how to proceed. We need a step-by-step procedure to reproduce the problem and then gather information as to where the memory is getting used. |
@rmathagiarun You can use kubectl top to check pod memory usage |
@bmv126 We already tried this and it didn't work out. I can see few others have also reported this issue, but, the response from community always seems to not to agree that Nginx has an issue during backend reload. Alternatively, We are in the process of migrating to envoy based ingress controllers. |
@rmathagiarun backend reload is a event that would occur on vanilla nginx as well as the nginx component of the ingress-nginx-controller and that implies that based on the size of the data that needs to be be read and reloaded, has a direct relevance to the impact on the usage of cpu/memory resources, which impacts the user experience ultimately. If you add configuration to vanilla nginx, without Kubernetes, in a infinite while true loop, with each loop adding a a new virtual host with custom directives, I am sure you will experience the same issue. Hence, the deep dive into a reproduce procedure becomes critically important to make progress here. The project faced performance issues earlier, and that was addressed by clearly arriving at a reproduce procedure. We even got core dumps, created during those reproduce efforts. |
@longwuyuan would it be possible to add the steps to get all the core dumps, attaching debuggers to get traces in the Troubleshooting Guide so that people facing such problems can give the community adequate information to debug and analyze? |
@ramanNarasimhan77 I think that requires some deep dive work. It will help someone if they don't know how to get info out of a core file. But not sure if one doc here will apply to all scenarios. But this is not a trivial process. I think that someone taking up this task will either already know how to work with core files, and very likely have some dev skills in C/C++ etc. On a different note, the reproduce procedure described earlier was generating ingress objects in a while loop, with no sleep. That seems to far away from real use case. If we can come up with a practical & real use case test, it could help make progress. One observation, rather obvious, is that if there is a bug, then many people report experiences related to it and personally I don't see several reports of this high memory usage. That is why my comments on coming up with a practical real use test. I did a search on the issue list and found at least one issue which describes some steps on how others worked on core files. For example #7080 . There are other issues as well. |
Hey guys, NGINX Ingress controller Cluster 1 Version: Server Version: version.Info{Major:"1", Minor:"19+", GitVersion:"v1.19.16-eks-25803e", GitCommit:"25803e8d008d5fa99b8a35a77d99b705722c0c8c", GitTreeState:"clean", BuildDate:"2022-02-16T23:37:16Z", GoVersion:"go1.15.15", Compiler:"gc", Platform:"linux/amd64"} Cluster 2 Version: Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.9", GitCommit:"9dd794e454ac32d97cde41ae10be801ae98f75df", GitTreeState:"clean", BuildDate:"2021-04-05T13:26:12Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"} Find below average memory consumption within a 4 day period. Peaks in both graphs represents each NGINX config reload, while baseline growing indicates a memory leak. Cluster 1 Average Memory Consumption Cluster 2 Average Memory Consumption Just wanted to highlight this while we get more info as mentioned by @longwuyuan. If anyone has found some reasonable explanation on this, could you please update us? Thank you for all your support! |
/remove-kind bug |
@longwuyuan: Those labels are not set on the issue: In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@longwuyuan: Closing this issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
100% understandable 💙 I will try to test it with main chart and image.
Can you give me a link for this known issue?
There's a few like this, about 10. |
/re-open I will have to search for the issues. But I want to avoid hard quoting. Reason is that the details differ and makes it difficult to have conversations that are practical. The gist though, is that if you have a vanilla nginx server, without kubernetes, and a config file that was relatively large like huge Megs, then reloading that config file, with multiple factors involved (containerization, platforming of some sort, live traffic, established connections, cpu/memory availability for bursts etc etc), you would observe similar delays in reload. And then if you factor in state mainenance of platform like kubernetes, you add another oddity. At least one issue we have dealt with in the past, was related to a bug outside kubernetes. That was worked on by the developer of the related project. Can't recall if the buggy component was lua or nginx or something else. A search of issues will take effort but yield that info. Hence all such performance issues make for 2 aspect of diligence. One is to triage until the smallest possible detail is clear on root-cause, like a bug or a resource crunch or something else. On the other hand some work is being done on splitting control-plane and data-plane, that will bring in design changes to the workflow and hence, improve things for sure, at least from instrumentation angle. |
/reopen I was talking about 33 ingress resources and 88 ingresses resources where you have multiple paths in one ingress. That would make for a large data-structure to be re-read even if one path was changed. Saying that event will be different from one small ingress with one small path being-re-read. |
@longwuyuan: Reopened this issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Thank you very much for taking the time to reply, it's very much appreciated, I know supporting such a popular project must be a lot of work 🙂
What is "hard quoting"?
Ours is 64MB. Is that huge?
Delays are fine. There is free CPU for the controllers, many of them, but each controller pod is not consuming more than 1 CPU core during reload.
Sure. We are just wanting perhaps some steps for how we can debug it further ourselves.
Do you mean in #8034 ?
OK well perhaps some basic debugging we can do is just delete half of them and see if behaviour changes. |
@odinsy @max-rocket-internet @procinger @bo-tu @moraesjeremias @ramanNarasimhan77 @rmathagiarun @bmv126 @venkatmarella This issue should largely be resolved in the next release of Ingress NGINX as #9330 made it so that the bundled version of ModSecurity points to a fixed commit which has the memory leak fix but has not been released yet. The release has been delayed due to a breaking change, but should be rolling out not too late from now. Hope that helps. |
@odinsy thanks for update. Seems an important update. |
/close |
@Volatus: Closing this issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Just to add some more details for those finding this thread in the future: in our case (see what @max-rocket-internet posted above), the memory issues weren't from modsecurity, as we don't have that enabled. In our metrics we observed correlations between the memory spikes and the number of worker processes. Since nginx reloads will leave old processes hanging in graceful shutdown for a little while this is to be expected. The usage spikes got especially bad when multiple reloads were triggered in short succession of each other (e.g. through deploying multiple ingress changes in short intervals). We ended up changing two settings which ended up making memory use much less spiky, which have been running smoothly for about a month now. They are:
|
worker_processes 96; kubectl top po -n ingress-nginx
NAME CPU(cores) MEMORY(bytes)
ingress-nginx-controller-k7nts 11m 1438Mi In the same boat, tried 8 workers just like you: worker_processes 8; kubectl top po -n ingress-nginx master
NAME CPU(cores) MEMORY(bytes)
ingress-nginx-controller-k7nts 3m 167Mi Oh lala! 😏 |
We had changes to our environment so the physical nodes were being rolled with more CPU cores, and no explicit configuration of |
For people that find this in the future: We tried updating
The dynamic LUA is maybe also not updating backends frequently enough with this setting? |
Ingress-nginx watches for K8S Endpoints to get the real Pod IP instead of using the K8S ClusterIP as upstream server, and for many reasons. If you are using only basic ingress-nginx features, I think you can avoid those 5XX errors by telling ingress-nginx to use the K8S ClusterIP as upstream instead of watching for every Endpoints : https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#service-upstream |
Also cap controller sync rate. See kubernetes/ingress-nginx#8166 (comment)
NGINX Ingress controller version
NGINX Ingress controller
Release: v1.1.1
Build: a17181e
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.9
Kubernetes version
Environment:
Cloud provider or hardware configuration: GCP
OS : Container-Optimized OS from Google
Kernel : 5.4.129+
How was the ingress-nginx-controller installed:
Current State of the controller:
kubectl describe ingressclasses
Current state of ingress object, if applicable:
kubectl -n <appnamespace> describe ing <ingressname>
What happened:
Our Ingress controller is serving ~1500 RPS
But over time ingress controller memory gets continuously increase but never goes down when it crosses the node limitation ~15GB pods gets evicted.
What you expected to happen:
We expect memory to get stablizise at some point.
profiling heap export:
high_mem.txt
For now we are manually restarting worker processes inorder to realise the memory
The text was updated successfully, but these errors were encountered: