-
Notifications
You must be signed in to change notification settings - Fork 169
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
[WIP] new(libsinsp): extract pod_uid
from cgroups
#1377
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Andreagit97 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
3c5deae
to
8ccc958
Compare
@@ -200,11 +200,10 @@ endif() | |||
set_sinsp_target_properties(sinsp) | |||
|
|||
target_link_libraries(sinsp | |||
PUBLIC scap | |||
PUBLIC scap "${RE2_LIB}" |
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.
This is needed so that unit-test-libsinsp is able to correctly link re2
since it is now needed.
1edd185
to
50080ae
Compare
// If `this->cgroups()` is not empty we should have at least the first element | ||
// An example of `this->cgroups()[0].second` layout is: | ||
// /kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-pod1b011081_6e8e_4839_b225_4685eae5fd59.slice/cri-containerd-2f92446a3fbfd0b7a73457b45e96c75a25c5e44e7b1bcec165712b906551c261.scope | ||
if(!re2::RE2::PartialMatch(this->cgroups()[0].second, pattern, &m_pod_uid)) |
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.
Are we sure we want to add a regex match in the hot path for processes? What type of performance hit do we expect from this? Would you mind providing an easy way to disable this check at runtime just in case? Maybe since it looks like heavily related to k8s, could we move it somewhere in the k8s specific code?
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.
Good point! Let's say the alternative would be to loop over some prefixes like in the container engine
libs/userspace/libsinsp/runc.cpp
Line 41 in 3d1f481
bool match_one_container_id(const std::string &cgroup, const std::string &prefix, const std::string &suffix, std::string &container_id) |
I'm ok with disabling it at runtime, but not sure what is the best way to disable it (cmake?some flags provided to sinsp?) Any ideas?
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.
Couldn't this be done by a container engine thread as an async event? Just thinking out loud.
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.
I don't think this needs to be in the process hot path at all, at least thinking from my use case, we have a separate process that gets this information from the kube api, so this are just compute cycles being wasted. Since it's for k8s, I insist it might be better placed somewhere closer to the k8s specific code, but I'm not familiar enough with that code to suggest where to place it.
As for how to enable it at runtime, a simple bool m_pod_uid_enabled
flag and a setter alongside the set_pod_uid
definition is more than enough IMO, set_pod_uid
would just check that flag before doing anything else and return if it's set to false.
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.
👋 happy to help as I have been sifting through the container engine on multiple occasions.
First, yes plz no additional regexes on the hot path.
A few pointers:
I usually use crictl
to spin up test pods as that allows for easy testing of both containerd and crio. Example inspection outputs of both the pod / sandbox or the container show that if it's a sandbox the container id is the same as the pod / sandbox id.
INSPECT POD / SANDBOX
sudo crictl pods
sudo crictl inspectp 95120af54b0d1
crio
"io.kubernetes.cri-o.SandboxID": "95120af54b0d102cc259e906f9aea0423ea7a5dd87ae458567f93cd453b944b1",
"io.kubernetes.cri-o.ContainerID": "95120af54b0d102cc259e906f9aea0423ea7a5dd87ae458567f93cd453b944b1",
containerd
"status": {
"id": "c28089bf708270613d27c409a4aaa5679537e8cbe54993ee3749038811cc8d97",
"io.kubernetes.cri.container-type": "sandbox",
"io.kubernetes.cri.sandbox-id": "c28089bf708270613d27c409a4aaa5679537e8cbe54993ee3749038811cc8d97",
INSPECT CONTAINER
sudo crictl ps
sudo crictl inspect 84d2897a399b0
crio
"io.kubernetes.cri-o.SandboxID": "95120af54b0d102cc259e906f9aea0423ea7a5dd87ae458567f93cd453b944b1",
"io.kubernetes.cri-o.ContainerID": "84d2897a399b0026499e93f490f47304818eb77868b23634f397a50bcedadb77",
String search for m_is_pod_sandbox
in the code base and I think that will direct you to the relevant code blocks to make minor adjustments. Basically perhaps it's just about returning the existing container id already extracted from the current cgroups parsing logic if it's a sandbox (without needing the API call against the container runtime socket to know if it's a sandbox or container). And since I haven't looked myself I don't know what all needs to be adjusted to get this, just suspecting it could be easier and less intrusive in the container engine code base (echoing @FedeDP and @Molter73 feedback).
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.
I don't think this is much heavier than lots of things already happening in the main thread after all. I see the use case and it makes sense IMO.
I'd only enable this behavior (ie: the regex match) when either the k8s client is enabled or the new plugin is enabled, so that people that don't use it don't pay the (small) extra cost.
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.
I don't think this needs to be in the process hot path at all, at least thinking from my use case, we have a separate process that gets this information from the kube api, so this are just compute cycles being wasted
@Molter73 Just for curiosity, how do you associate the pod_uid
extracted from the kube API to a sinsp thread?
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.
I don't think this needs to be in the process hot path at all, at least thinking from my use case, we have a separate process that gets this information from the kube api, so this are just compute cycles being wasted. Since it's for k8s, I insist it might be better placed somewhere closer to the k8s specific code, but I'm not familiar enough with that code to suggest where to place it.
Hi @Molter73 , we are writing a plugin to handle the kubernetes metadata. But we need to associate a process/thread with those metadata. The best is to leverage the
pod UID
and extract it from thecgroup path
. Thecgroup path
is already there, just need to extract thepod UID
substring from it. We can consider moving the extraction of thepod UID
to the plugin code but performances would be impacted too much since the extraction would be done each time we need to associate asyscall
to its k8s metadata. Keep in mind that plugin logic would block all the processing on thesinsp
side.
Well, that's all fine, but we can still probably move it to the container engine. Even if most of the heavy lifting by container engines is done asynchronously, getting the container ID is done in line by the resolve
members, so by making the check there you can limit the search to engines that actually make sense and you could potentially use the already matched container ID in some cases as @incertum suggests. At the very least, if it's going to be a costly operation, an enable flag for adopters to opt out would be appreciated.
I don't think this needs to be in the process hot path at all, at least thinking from my use case, we have a separate process that gets this information from the kube api, so this are just compute cycles being wasted
@Molter73 Just for curiosity, how do you associate the
pod_uid
extracted from the kube API to a sinsp thread?
Have to admit I'm not 100% sure how this process works, it's a completely separate process from the one I usually work on, but basically we inform data about the process and the container ID it belongs to and the other process does its thing to get information about the resource the container belongs to from the API. I'd have to dig deeper to understand it better, but at that point the data is no longer a sinsp_thread
.
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.
@alacuku thanks for adding more context around why you would want this outside the container engine. It was not clear to me before you shared this additional context. I was wondering why we actually cannot use the container engine API calls to get the sandbox id like we currently do as the id itself has not too much value without the pod name anyways. But now I see the use case. Just double checking: The new k8s client definitely and absolutely would only work with the sandbox id and we couldn't pivot from container id to sandbox id like we for example do today with the container runtime API calls?
Yes the tree would need to be formed - it would still be more effective in the container engine portions, but as you explained the ultimate goal would be to bypass the container engine.
Question:
How urgent is this patch now? Are we planning the k8s client refactor for Falco 0.37? What are the performance improvement hopes compared to extracting the most critical information from the container runtime socket today? Are we just planning to replace the mechanisms of getting the k8s fields we support today or are we planning to extend capabilities?
For example, would support for extracting info from for example https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook be possible with the new framework down the road? That would get me definitely "hooked" and in favor.
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.
@Andreagit97 and @alacuku re to what was mentioned above Omar opened a new issue falcosecurity/falco#2895. It would propose adding some similar (not necessarily regex), but string checks on the hot path.
@Andreagit97 you mentioned you wanted to explore more options, curious to hear more. I liked to hear that the refactor could potentially be more performant and more reliable than the current container engine. In that case we could also win in terms of using the k8s client to already gather container image and other fields we currently only fetch from the container runtime socket.
Signed-off-by: Andrea Terzolo <[email protected]> Co-authored-by: Aldo Lacuku <[email protected]>
Signed-off-by: Andrea Terzolo <[email protected]>
Signed-off-by: Andrea Terzolo <[email protected]>
50080ae
to
b0fdb31
Compare
|
||
#pragma once | ||
|
||
#define RGX_POD "(pod[a-z0-9]{8}[-_][a-z0-9]{4}[-_][a-z0-9]{4}[-_][a-z0-9]{4}[-_][a-z0-9]{12})" |
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.
Why can't this live closer to the set_pod_uid
definition in threadinfo.h
? A full header file for a single define seems overkill.
pod_uid
from cgroupspod_uid
from cgroups
We will evaluate other possible solutions |
this is now integrated into the new plugin, we can close this |
What type of PR is this?
/kind feature
Any specific area of the project related to this PR?
/area libsinsp
Does this PR require a change in the driver versions?
No
What this PR does / why we need it:
This PR allows us to extract the
pod_uid
directly from the cgroups paths obtained from our drivers (kmod/bpf).Which issue(s) this PR fixes:
This is necessary to unblock falcosecurity/falco#2973
Special notes for your reviewer:
Does this PR introduce a user-facing change?: