-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add support for CgroupsV2 in beats, migrate away from gosigar #27242
Conversation
Pinging @elastic/integrations (Team:Integrations) |
💚 Build Succeeded
Expand to view the summary
Build stats
Test stats 🧪
Trends 🧪💚 Flaky test reportTests succeeded. Expand to view the summary
Test stats 🧪
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks quite good. I haven't reviewed the code moved from gosigar, if we want to make any refactor there I would leave it for a separate review. If there are relevant changes there please point to them 🙂
@@ -576,19 +531,22 @@ func (procStats *Stats) getSingleProcess(pid int, newProcs ProcsMap) *Process { | |||
|
|||
err = process.getDetails(procStats.isWhitelistedEnvVar) | |||
if err != nil { | |||
procStats.logger.Debugf("Error getting details for process %s with pid=%d: %v", process.Name, process.Pid, err) | |||
procStats.logger.Errorf("Error getting details for process %s with pid=%d: %v", process.Name, process.Pid, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this was intentionally logged at the debug level? 😬 I can imagine this flooding logs in hosts with many short-lived processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, this reminds me to #9111.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yah, just decided to refactor most of this. Even if this library is going away in 7.16, it's still kind of a mess.
@jsoriano thanks for the review! addressed most of the issues, and finally tracked down the bug that was breaking CI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments added, nothing blocking, but there still seems to be related failures in CI.
libbeat/metric/system/cgroup/util.go
Outdated
@@ -202,6 +202,10 @@ func SubsystemMountpoints(rootfsMountpoint string, subsystems map[string]struct{ | |||
|
|||
// V2 option | |||
if mount.filesystemType == "cgroup2" { | |||
if len(mount.mountpoint) < 3 { | |||
// Why is this happening? I don't know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😃
Where does it happen? How does mountinfo
look in these cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think you're looking at an older version, that's while I was debugging an issue with hybrid cgroups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I was curious about what appeared in mountinfo
when this happens 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! The cgroups line just...isn't there.
result, err := provider.GetCid(1) | ||
assert.NoError(t, err) | ||
assert.Equal(t, "2dcbab615aebfa9313feffc5cfdacd381543cfa04c6be3f39ac656e55ef34805", result) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 thanks!
…c#27242) * finish first round of cgroupsv2 support * fix tests * remove old code, fix PctOpt * fix imports * go mod tidy * try to fix make notice again * try again * remove unneeded test files * fix test paths * fix crossbuild issues * fix tests, remove debug statement * change metadata, fight with mapping defs * fix v1 test, remove debug line * somewhat hacky fix for fields issues * fix v1 fetch, update fields again * fix omitempty issue * make update * remove older test * fix tests, cgv1 logic * remove old debug statement * fix issue with how ubuntu mixes cgroups * clean up error handling in libbeat * changes based on feedback, increased error verbosity to try to fix baffling CI errors * fix fields, add more error messages for weird CI bug * I give up, add tons of debug statements * fix issue with docker containers running under hybrid cgroups * fix hostfs state check * fix more broken tests * fix names, log levels * more changes, docs, test * still making the mapping checks happy * fix libbeat code I broke (cherry picked from commit d898533)
#27346) * finish first round of cgroupsv2 support * fix tests * remove old code, fix PctOpt * fix imports * go mod tidy * try to fix make notice again * try again * remove unneeded test files * fix test paths * fix crossbuild issues * fix tests, remove debug statement * change metadata, fight with mapping defs * fix v1 test, remove debug line * somewhat hacky fix for fields issues * fix v1 fetch, update fields again * fix omitempty issue * make update * remove older test * fix tests, cgv1 logic * remove old debug statement * fix issue with how ubuntu mixes cgroups * clean up error handling in libbeat * changes based on feedback, increased error verbosity to try to fix baffling CI errors * fix fields, add more error messages for weird CI bug * I give up, add tons of debug statements * fix issue with docker containers running under hybrid cgroups * fix hostfs state check * fix more broken tests * fix names, log levels * more changes, docs, test * still making the mapping checks happy * fix libbeat code I broke (cherry picked from commit d898533)
logp.L().Infof(`PID %d contains a cgroups V2 path (%s) but no V2 mountpoint was found. | ||
This may be because metricbeat is running inside a container on a hybrid system. | ||
To monitor cgroups V2 processess in this way, mount the unified (V2) hierarchy inside | ||
the container as /sys/fs/cgroup/unified and start metricbeat with --system.hostfs.`, pid, line) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fearful-symmetry in an elastic-agent started with elastic-package stack
in my laptop, I see continuously (every collection period) this message, I think we should move it to the debug level. In a system where this happens this is going to be continuosly logged.
I use a quite vanilla Ubuntu 18.04.5 LTS, with Linux 4.15, and docker 20.10.7. So maybe this is not so an edge case.
Also, as far as I know, both my host and the docker containers are using cgroups V1 (I don't see any cgroups2 mountpoint or any unified cgroup) so I wonder if this comment about hybrid systems can be misleading in this case.
For reference, this is what I see in logs:
2021-08-18T08:15:09.797Z INFO cgroup/util.go:257 PID 10 contains a cgroups V2 path (0::/system.slice/containerd.service) but no V2 mountpoint was found.
This may be because metricbeat is running inside a container on a hybrid system.
To monitor cgroups V2 processess in this way, mount the unified (V2) hierarchy inside
the container as /sys/fs/cgroup/unified and start metricbeat with --system.hostfs.
This is how /proc/10/cgroup
looks like in the container:
12:freezer:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
11:devices:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
10:cpu,cpuacct:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
9:pids:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
8:hugetlb:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
7:blkio:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
6:perf_event:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
5:cpuset:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
4:memory:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
3:net_cls,net_prio:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
2:rdma:/
1:name=systemd:/docker/b257ef6e9abdac56a8a07bf2e35abc7a064b0638e893bc54ab98d925bba13ecd
0::/system.slice/containerd.service
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0::/system.slice/containerd.service
So, that's the V2 controller there. You said you didn't see any unified mountpoint on the system? Can you get me /proc/self/mountinfo
?
However, I think you're right that we might want some kind of behavior to prevent this message from getting spammy. Unfortunately, from within a docker container it's really hard to get that info without the user mounting sysfs
inside the container. Maybe just have it print the message at startup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you are right, there is some cgroup2
around, I didn't see it.
$ cat /proc/self/mountinfo | grep cgroup2
34 33 0:29 / /sys/fs/cgroup/unified rw,nosuid,nodev,noexec,relatime shared:10 - cgroup2 cgroup rw,nsdelegate
So yeah, let's keep the message but trying to make it less verbose.
What does this PR do?
This PR accomplishes a few different things:
libbeat
. A considerable portion of the code here is pre-existing code fromgosigar
that's been reorganized.opt
library frommetricbeat/internal/metrics
tolibbeat
, since we use it here too.MapStr
manipulation code in favor of having the data format hard-coded into the structs, and makes the cgroups code overall more "metrics first"Note that supporting cgroups V1 and V2 involves some compromises, as the two versions structure themselves and report data fairly differently, and as such, most of the metrics APIs require the consumer to differentiate between V1 and V2 if they want to access raw metrics. V1 and V2 can also cooexist on the same system, so this must happen on a pid-by-pid basis.
Also, I'm still testing this on V1 and mixed v1/v2 systems, but the code is otherwise ready for review.
There's also the issue of dashboards. The system Docker dashboard relies on many of the V1 fields that aren't present in V2, and I'm not really sure how to deal with them. Last I tried, we don't really have any mechanism for dashboards to operate with the logic of "use this field if present, otherwise use this other field." We may also just want to re-write the dashboard entirely to just use fields that are present in V1 and V2, at the expense of losing some of the visualizations.
Also keep in mind that most of
system/process
is going to be aggressively refactored after this, so any issues, unless they're serious, with the code inlibbeat/metric/system/process
andmetricbeat/system/process
will almost certainly be fixed as part of 7.16.What's up with cgroupsV2
Cgroups V2 introduces a few major changes compared to cgroups V1, which necessitated a lot of extra code:
cpuacct
,memory
, etc) have changed dramatically, and in a few cases have merged with other controllers for V2. This requires entirely new metrics code.File structure
For ease of browsing through this PR (Github honestly isn't great at presenting large PRs), here's the breakdown of what's in here:
This also includes:
libbeat/opt
Which is mostly existing code that was moved frommetricbeat/internal
.cmd/instance
,add_process_metadata
andadd_docker_metadata
to migrate away fromgosigar
metricbeat/internal
to deal with moving thelibbeat/opt
code.Why is it important?
Cgroups V2 is coming, and is already default on Fedora. It's supported by most other software at this point.
Checklist
CHANGELOG.next.asciidoc
orCHANGELOG-developer.next.asciidoc
.How to test this PR locally
grep cgroup /proc/self/mountinfo
system/process
metricset, as well asadd_process_metadata
andadd_docker_metadata