Skip to content

Commit

Permalink
Fixes cgroup ID parsing in newer docker versions (grafana#1287)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariomac authored Oct 29, 2024
1 parent 5c93589 commit 719b211
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
47 changes: 27 additions & 20 deletions pkg/internal/helpers/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/<hex...>/kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-besteffort.slice/kubelet-kubepods-besteffort-pod<hex...>.slice/cri-containerd-<hex...>.scope
// where the last <hex...> chain is the container ID inside its Pod
var dockerCgroup = regexp.MustCompile(`^\d+:.*:.*/.*-([\da-fA-F]+)\.scope`)
var cgroupFormats = []*regexp.Regexp{
// 0::/docker/<hex...>/kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-besteffort.slice/kubelet-kubepods-besteffort-pod<hex...>.slice/cri-containerd-<hex...>.scope
// where the last <hex...> 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) {
Expand All @@ -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
}
2 changes: 2 additions & 0 deletions pkg/internal/helpers/container/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down

0 comments on commit 719b211

Please sign in to comment.