-
Notifications
You must be signed in to change notification settings - Fork 218
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
Avoid log truncation due to log-rotation delays (when logfiles exceeds 1.8GB faster than log rotation) #55
Comments
for future reference: you can reference PRs and issues by putting |
/priority important-soon |
@mborsz @tallclair @dims Move the discussion to this issue. Maciej, I tried using the same manifest to create a custom cluster. I do see the kube-apiserver.log-XXX.gz. https://user-images.githubusercontent.com/5606098/55660065-50f04280-57b9-11e9-99d5-fa2e719ccfd3.png Do you mind showing me how to recreate the scale test env so as I can reproduce the problem? |
Thanks Solly! |
There is a race between kube-logrotate and klog. Klog truncates at 1.8GB and logrotate rotates logs every hour (if log is greater than 100M). If you fill up logs slowly (less than 1.8GB per hour), the current setup will work. If faster, klog will truncate the log before logrotate even starts. To reproduce the issue, simply try creating a cluster that produces more than 1800M per hour. In scalability tests we are using --v=3 so each request is logged. This increases log volume significantly, but we need that to debug tests. |
Just my opinion here, but I think having Would it be possible to tweak the settings of |
@mattjmcnaughton as mentioned in kubernetes/kubernetes#76190 (comment) we can support the SIGHUP on logrotate using say using https://github.com/client9/reopen |
Thanks for pointing it out, Matt. You are right. I updated the title and description (will have another update after we confirm the detailed solution). |
Hi everyone, thanks for jumping in and helping on this issue. After gathering the different pieces of knowledge from everyone and discussed with @dims earlier today, I'd like to give a quick summary about what's going on here and to clarify some potential misunderstanding. Root Cause:We use logrotate to split log-files periodically (every hour) and compress the logs to a new .gz file when the log-file grows too large (exceed 100MB). At the same time, klog has its own max log size protector (in case to keep the latest log message) that cleans up the log-file completely when the file size exceeds 1.8GB. After the cleanup, the klog continues writing to the same log-file. [In certain cases](https://github.com/kubernetes/kubernetes/pull/76190) , the log-file grows to 1.8GB quickly even before the hourly logrotate runs. Thus, earlier logs are missed.Note:
Solution Option 1:Update the logrotate cronjob to run more frequently so as the log can be stored in a different file before the log-file exceeds 1.8GB . e.g. running every 20 minutes instead of hourly.
Solution Option 2:Loosen the 1.8GB limitation. Either change the constant variable to a larger number(e.g. instead of cleaning up log-files when exceeds 1.8GB, do the cleanup in 5GB) or make it as a configurable variable(e.g. --cleanup-at-size=1.8GB).
Solution Option 3:Disable the log-file cleaning up completely (No 1.8GB limitations). The klog won't have logic about how to handle large file size.
Solution Option 4:Instead of cleaning up the 1.8GB data completely, klog can rename the file to something like kube-apiserver-TIMESTAMP.log and continue writing new logs to log-file.
Solution Option 5:Abandon ubuntu logrotate. Implement a klog versioned logrotation.
This is just a rough explanation. Let me know if anything's unclear. @mborsz @wojtek-t Thoughts? Is there any concerns if we go with Solution 1? 😄 |
I would definitely support option 1 and option 2. Even if option 1 solves the problem, option 2 (i'd prefer say So between running logrotate more frequently and the specification of max size, we should be able to support the scalability use case. |
For option 1, please note that we used to logrotate every 5 minutes, but we had to revert this change to hourly (I don't know the details; see kubernetes/kubernetes#74915). Personally, I support option 3. I'm not the logging expert here, but I think the current pattern (kube-apiserver writes to stderr and we redirect to a file regardless of size) in k8s worked just fine. We can do the same here and figure out something better if needed later. It's also the simplest one and separates responsibility well between klog and logrotate. |
@jpbetz - what are the details behind reverting back to logrotate every 1h? I'm not a fan of option (2) - it introduces yet another knob to configure. Also, even if it works now, it may no longer work if we put N times more load on apiserver and I would like to avoid thinking about yet another things that should be tweaked. I actually agree with Maciej, that option (3) sounds most promissing. Option (4) and (5) mean that we simply start reimplementing log rotation in klog - I'm not sure we really want to reinvent the wheel.. |
From the input of @dims and @mborsz, I think what we can do is 1.) add the flag that allows klog owners defining the At the same time, I'd like to try increasing the logrotate frequency. From the kubernetes/kubernetes#74915, I can't find out a clear explanation about why 5-minute logrotate causes the audit log test flakiness. @jpbetz Do you mind me trying to use 20 minutes? I can revert if it continuously causes test flakiness. The thing is that this log truncation is a main blocker for the k8s image rebasing. |
+1 to for y, let's drop the logrotate 5 mins thing, i vaguely remember the problem, but don't remember that we ever got to a root cause (possibly the frequent compression was taking up cpu?) |
hmmmm, Why not for "log-dir"? |
@yuwenma we don't want to change how |
@wojtek-t The revert back to 1hr logrotate happened in the 11th hour of the 1.14 release due to some (poorly written, IMO) tests relying on on the current log containing specific information. We'd need to hunt the exact tests down since I don't have details handy. My recollection is that the tests need to be rewritten to either not rely on logs to check for conditions, or also check the rotated so they are resilient to having the log rotated out from under them. FWIW, I think if we fix the flaking tests, reapplying #72062 should get us plenty of millage. The idea is simple: Just check if the logs need to be rotated more often so that the policy we intended (new day starts, log file size > 100MB) actually gets implemented. If we need to change the policy, that's fine too.. But going from checking every 1hr to every 5m should solve the bulk of the large file problems. Sorry I haven't been able to follow up on this, if someone can pick up the task, that would be great. |
Thanks @jpbetz, sounds like it's safer to wait until the test is improved before changing the logrotate frequency. |
It looks like the test that was causing problems was the advanced audit test, which has since been marked flaky (i.e. it no longer runs as part of the blocking test suite). So it should be safe to move forward with the increased logrotate frequency. |
Thanks @timstclair, reapplying via kubernetes/kubernetes#76352 |
/kind feature
(mirrored from k/k issue 76210
Describe the solution you'd like
[A clear and concise description of what you want to happen.]
klog supports "log-file" flag to specify the log file path. However, when the logfile size reaches 1.8GiB and log-rotation hasn't happened, the older logs will be truncated. See details in PR76190.
We want to keep all the log messages. If the log file goes too large, we expect to the older logs to be stored in a separate file kube-apiserver.log,gz..
Anything else you would like to add:
[Miscellaneous information that will assist in solving the issue.]
This issue needs to be fixed at least 1 month before v1.15. Since it blocks some v1.15 release features (like rebasing images from debian/alpine to distroless heavily depends on the klog feature).
The text was updated successfully, but these errors were encountered: