From 719b211845f4581e59f5706cf3c78b917fc9a1d4 Mon Sep 17 00:00:00 2001 From: Mario Macias Date: Tue, 29 Oct 2024 16:04:13 +0100 Subject: [PATCH] Fixes cgroup ID parsing in newer docker versions (#1287) --- pkg/internal/helpers/container/container.go | 47 +++++++++++-------- .../helpers/container/container_test.go | 2 + 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/pkg/internal/helpers/container/container.go b/pkg/internal/helpers/container/container.go index c4cce0348..df877894f 100644 --- a/pkg/internal/helpers/container/container.go +++ b/pkg/internal/helpers/container/container.go @@ -24,17 +24,22 @@ type Info struct { PIDNamespace uint32 } -// A docker cgroup entry is a string like - when running beyla as a process on the node: -// 0::/docker//kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-besteffort.slice/kubelet-kubepods-besteffort-pod.slice/cri-containerd-.scope -// where the last chain is the container ID inside its Pod -var dockerCgroup = regexp.MustCompile(`^\d+:.*:.*/.*-([\da-fA-F]+)\.scope`) +var cgroupFormats = []*regexp.Regexp{ + // 0::/docker//kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-besteffort.slice/kubelet-kubepods-besteffort-pod.slice/cri-containerd-.scope + // where the last chain is the container ID inside its Pod + regexp.MustCompile(`^\d+:.*:.*/.*-([\da-fA-F]+)\.scope`), -// A k8s cgroup entry is a string like - when running beyla as daemonset in k8s: -// GKE: /kubepods/burstable/pod4a163a05-439d-484b-8e53-2968bc15824f/cde6dfaf5007ed65aad2d6aed72af91b0f3d95813492f773286e29ae145d20f4 -// GKE-containerd: /kubepods/burstable/podb53dfa9e2dc9b890f7fadb2770857b03/bb959773d06ad1a07d469bced637bbc49b6f8573c493fd0548d7f5810eb3e5a8 -// EKS: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poddde1244b_5bb5_4297_b544_85f3bc0d80bf.slice/cri-containerd-acb62391578595ec849d87d8556369cee7f935f0425097fd5f870df0e8aabd3c.scope -// Containerd: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod7260904bbd08e72e4dff95d9fccd2ee8.slice/cri-containerd-d36686f9785534531160dc936aec9d711a26eb37f4fc7752a2ae27d0a24345c1.scope -var k8sCgroup = regexp.MustCompile(`^\d+:.*:/kubepods.*([0-9a-f]{64})`) + // formats for other Kubernetes distributions + // GKE: /kubepods/burstable/pod4a163a05-439d-484b-8e53-2968bc15824f/cde6dfaf5007ed65aad2d6aed72af91b0f3d95813492f773286e29ae145d20f4 + // GKE-containerd: /kubepods/burstable/podb53dfa9e2dc9b890f7fadb2770857b03/bb959773d06ad1a07d469bced637bbc49b6f8573c493fd0548d7f5810eb3e5a8 + // EKS: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poddde1244b_5bb5_4297_b544_85f3bc0d80bf.slice/cri-containerd-acb62391578595ec849d87d8556369cee7f935f0425097fd5f870df0e8aabd3c.scope + // Containerd: /kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod7260904bbd08e72e4dff95d9fccd2ee8.slice/cri-containerd-d36686f9785534531160dc936aec9d711a26eb37f4fc7752a2ae27d0a24345c1.scope + regexp.MustCompile(`^\d+:.*:/kubepods.*([0-9a-f]{64})`), + + // as fallback, other formats for cgroup which might appear in other Docker implementations + // 0::/../../pode039200acb850c82bb901653cc38ff6e/58452031ab6dcaa4fe3ff91f8a46fd41a4a2405586f3cf3d5cb9c93b5bcf62cc + regexp.MustCompile(`^\d+:.*:.*/.*/.*/([0-9a-fA-F]{64})`), +} // InfoForPID returns the container ID and PID namespace for the given PID. func InfoForPID(pid uint32) (Info, error) { @@ -47,21 +52,23 @@ func InfoForPID(pid uint32) (Info, error) { if err != nil { return Info{}, fmt.Errorf("reading %s: %w", cgroupFile, err) } - // We look for the docker cgroup entry first, as it's the most common + for _, cgroupEntry := range bytes.Split(cgroupBytes, []byte{'\n'}) { - submatches := dockerCgroup.FindSubmatch(cgroupEntry) - if len(submatches) < 2 { - continue + if cgroupID, ok := findCgroup(string(cgroupEntry)); ok { + return Info{PIDNamespace: ns, ContainerID: cgroupID}, nil } - return Info{PIDNamespace: ns, ContainerID: string(submatches[1])}, nil } - // If we didn't find a docker entry, we look for a k8s entry - for _, cgroupEntry := range bytes.Split(cgroupBytes, []byte{'\n'}) { - submatches := k8sCgroup.FindSubmatch(cgroupEntry) + return Info{}, fmt.Errorf("%s: couldn't find any docker entry for process with PID %d", cgroupFile, pid) +} + +// look for a cgroup ID on all the possible formats +func findCgroup(cgroupEntry string) (string, bool) { + for _, re := range cgroupFormats { + submatches := re.FindStringSubmatch(cgroupEntry) if len(submatches) < 2 { continue } - return Info{PIDNamespace: ns, ContainerID: string(submatches[1])}, nil + return submatches[1], true } - return Info{}, fmt.Errorf("%s: couldn't find any docker entry for process with PID %d", cgroupFile, pid) + return "", false } diff --git a/pkg/internal/helpers/container/container_test.go b/pkg/internal/helpers/container/container_test.go index 513155273..6880f65e4 100644 --- a/pkg/internal/helpers/container/container_test.go +++ b/pkg/internal/helpers/container/container_test.go @@ -39,6 +39,8 @@ var fixturesWithContainer = map[uint32]string{ 788: `0::/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-poddde1244b_5bb5_4297_b544_85f3bc0d80bf.slice/cri-containerd-40c03570b6f4c30bc8d69923d37ee698f5cfcced92c7b7df1c47f6f7887378a9.scope`, // Containerd cgroup entry 889: `0::/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod7260904bbd08e72e4dff95d9fccd2ee8.slice/cri-containerd-40c03570b6f4c30bc8d69923d37ee698f5cfcced92c7b7df1c47f6f7887378a9.scope`, + // Docker 27+ + 899: `0::/../../pode039200acb850c82bb901653cc38ff6e/40c03570b6f4c30bc8d69923d37ee698f5cfcced92c7b7df1c47f6f7887378a9`, } var fixturesWithoutContainer = map[uint32]string{