diff --git a/lib/container/containerd/factory.go b/lib/container/containerd/factory.go index 7d7ca2e126..da21cbda0e 100644 --- a/lib/container/containerd/factory.go +++ b/lib/container/containerd/factory.go @@ -41,9 +41,13 @@ var containerdEnvMetadataWhiteList = flag.String("containerd_env_metadata_whitel // The namespace under which containerd aliases are unique. const k8sContainerdNamespace = "containerd" +const defaultContainerdCgroupPattern = `([a-z0-9]{64})` + +var ArgContainerdCgroupPattern = flag.String("containerd_cgroup_pattern", defaultContainerdCgroupPattern, "regexp identifying the cgroups of containerd containers. If the regexp has a capturing group, the first submatch of the cgroup's base name is used as the containerd container ID, otherwise the base name itself is used") + // Regexp that identifies containerd cgroups, containers started with // --cgroup-parent have another prefix than 'containerd' -var containerdCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`) +var containerdCgroupRegexp = regexp.MustCompile(defaultContainerdCgroupPattern) type containerdFactory struct { machineInfoFactory info.MachineInfoFactory @@ -88,7 +92,7 @@ func (f *containerdFactory) NewContainerHandler(name string, metadataEnvAllowLis // Returns the containerd ID from the full container name. func ContainerNameToContainerdID(name string) string { id := path.Base(name) - if matches := containerdCgroupRegexp.FindStringSubmatch(id); matches != nil { + if matches := containerdCgroupRegexp.FindStringSubmatch(id); len(matches) > 1 { return matches[1] } return id @@ -145,6 +149,14 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics return fmt.Errorf("failed to get cgroup subsystems: %v", err) } + if *ArgContainerdCgroupPattern != defaultContainerdCgroupPattern { + re, err := regexp.Compile(*ArgContainerdCgroupPattern) + if err != nil { + return fmt.Errorf("invalid containerd_cgroup_pattern %q: %v", *ArgContainerdCgroupPattern, err) + } + containerdCgroupRegexp = re + } + klog.V(1).Infof("Registering containerd factory") f := &containerdFactory{ cgroupSubsystems: cgroupSubsystems, diff --git a/lib/container/containerd/factory_test.go b/lib/container/containerd/factory_test.go index 2f7918eb01..0992007f4b 100644 --- a/lib/container/containerd/factory_test.go +++ b/lib/container/containerd/factory_test.go @@ -17,6 +17,7 @@ package containerd import ( + "regexp" "testing" "github.com/containerd/typeurl/v2" @@ -47,6 +48,28 @@ func TestIsContainerName(t *testing.T) { } } +func TestContainerdCgroupPattern(t *testing.T) { + as := assert.New(t) + orig := containerdCgroupRegexp + defer func() { containerdCgroupRegexp = orig }() + + // On ECS Managed Instances, containerd names cgroups + // "<32 hex task id>-", which the default + // 64-hex-character pattern does not match. + const ecsCgroup = "/ecs/0a5094e2e49648f7917fdb417ca220ef/0a5094e2e49648f7917fdb417ca220ef-0484428261" + as.False(isContainerName(ecsCgroup)) + + containerdCgroupRegexp = regexp.MustCompile(`^[a-f0-9]{32}-\d+$`) + as.True(isContainerName(ecsCgroup)) + // A pattern without a capturing group falls back to the base name. + as.Equal("0a5094e2e49648f7917fdb417ca220ef-0484428261", ContainerNameToContainerdID(ecsCgroup)) + as.False(isContainerName("/ecs/0a5094e2e49648f7917fdb417ca220ef")) + as.False(isContainerName(ecsCgroup + "-rootfs.mount")) + + containerdCgroupRegexp = regexp.MustCompile(`^([a-f0-9]{32})-\d+$`) + as.Equal("0a5094e2e49648f7917fdb417ca220ef", ContainerNameToContainerdID(ecsCgroup)) +} + func TestCanHandleAndAccept(t *testing.T) { as := assert.New(t) testContainers := make(map[string]*containers.Container)