Skip to content
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

[CONTINT-4105] Support arbitrary container-ids to collect container metrics #25515

Merged
merged 16 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@
/pkg/util/pdhutil/ @DataDog/windows-agent
/pkg/util/winutil/ @DataDog/windows-agent
/pkg/util/testutil/flake @DataDog/agent-developer-tools
/pkg/util/trie @DataDog/container-integrations
/pkg/languagedetection @DataDog/processes @DataDog/universal-service-monitoring
/pkg/logs/ @DataDog/agent-metrics-logs
/pkg/logs/launchers/windowsevent @DataDog/agent-metrics-logs @DataDog/windows-agent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ func buildWorkloadMetaContainer(namespace string, container containerd.Container

workloadContainer.EnvVars = envs
workloadContainer.Hostname = spec.Hostname
if spec.Linux != nil {
workloadContainer.CgroupPath = extractCgroupPath(spec.Linux.CgroupsPath)
}
} else if errors.Is(err, cutil.ErrSpecTooLarge) {
log.Warnf("Skipping parsing of container spec for container id: %s, spec is bigger than: %d", info.ID, cutil.DefaultAllowedSpecMaxSize)
} else {
Expand All @@ -144,6 +147,17 @@ func buildWorkloadMetaContainer(namespace string, container containerd.Container
return workloadContainer, nil
}

// Containerd applies some transformations to the cgroup path, we need to revert them
// https://github.com/containerd/containerd/blob/b168147ca8fccf05003117324f493d40f97b6077/internal/cri/server/podsandbox/helpers_linux.go#L64-L65
// See https://github.com/opencontainers/runc/blob/main/docs/systemd.md
func extractCgroupPath(path string) string {
res := path
if l := strings.Split(path, ":"); len(l) == 3 {
res = l[0] + "/" + l[1] + "-" + l[2] + ".scope"
}
return res
}

func extractStatus(status containerd.ProcessStatus) workloadmeta.ContainerStatus {
switch status {
case containerd.Paused, containerd.Pausing:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ func TestBuildWorkloadMetaContainer(t *testing.T) {
}, nil
},
MockSpec: func(namespace string, ctn containers.Container) (*oci.Spec, error) {
return &oci.Spec{Hostname: hostName, Process: &specs.Process{Env: envVarStrs}}, nil
return &oci.Spec{Hostname: hostName, Process: &specs.Process{Env: envVarStrs}, Linux: &specs.Linux{
CgroupsPath: "kubelet-kubepods-burstable-pod99dcb84d2a34f7e338778606703258c4.slice:cri-containerd:ec9ea0ad54dd0d96142d5dbe11eb3f1509e12ba9af739620c7b5ad377ce94602",
}}, nil
},
MockStatus: func(namespace string, ctn containerd.Container) (containerd.ProcessStatus, error) {
return containerd.Running, nil
Expand Down Expand Up @@ -175,10 +177,49 @@ func TestBuildWorkloadMetaContainer(t *testing.T) {
NetworkIPs: make(map[string]string), // Not available
Hostname: hostName,
PID: 0, // Not available
CgroupPath: "kubelet-kubepods-burstable-pod99dcb84d2a34f7e338778606703258c4.slice/cri-containerd-ec9ea0ad54dd0d96142d5dbe11eb3f1509e12ba9af739620c7b5ad377ce94602.scope",
}
assert.Equal(t, expected, result)
}

func TestExtractCgroupPath(t *testing.T) {
tests := []struct {
name string
path string
expected string
}{
// cgroupfs retrieved using minikube + qemu2 driver
{
name: "cgroupfs + kubernetes pod",
path: "/kubepods/burstable/pod84a7cac1-5690-4935-bffc-4b808e0240e4/0af39253daf5d1054519efdd054023e929785c2813c29f6a0ce887f652e1a997",
expected: "/kubepods/burstable/pod84a7cac1-5690-4935-bffc-4b808e0240e4/0af39253daf5d1054519efdd054023e929785c2813c29f6a0ce887f652e1a997",
},
// systemd retrieved using kind
{
name: "systemd + kubernetes pod",
path: "kubelet-kubepods-burstable-pod99dcb84d2a34f7e338778606703258c4.slice:cri-containerd:ec9ea0ad54dd0d96142d5dbe11eb3f1509e12ba9af739620c7b5ad377ce94602",
expected: "kubelet-kubepods-burstable-pod99dcb84d2a34f7e338778606703258c4.slice/cri-containerd-ec9ea0ad54dd0d96142d5dbe11eb3f1509e12ba9af739620c7b5ad377ce94602.scope",
},
// custom retrieved using ctr run
{
name: "systemd/cgroupfs + container",
path: "/default/redis",
expected: "/default/redis",
},
// garden
{
name: "garden",
path: "/garden/1a65c217-84b2-8d13-3d78-46b14b6c7ea1",
expected: "/garden/1a65c217-84b2-8d13-3d78-46b14b6c7ea1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, extractCgroupPath(tt.path))
})
}
}

func TestExtractRuntimeFlavor(t *testing.T) {
tests := []struct {
name string
Expand Down
7 changes: 6 additions & 1 deletion comp/core/workloadmeta/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/DataDog/datadog-agent/comp/core/config"
"github.com/DataDog/datadog-agent/comp/core/log/logimpl"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"

"github.com/stretchr/testify/assert"
"go.uber.org/fx"
)
Expand Down Expand Up @@ -59,7 +60,8 @@ func TestDump(t *testing.T) {
Image: ContainerImage{
Tag: "latest",
},
PID: 1,
PID: 1,
CgroupPath: "/default/ctr-id",
}

s.handleEvents([]CollectorEvent{
Expand Down Expand Up @@ -134,6 +136,7 @@ Allowed env variables: DD_SERVICE:my-svc DD_ENV:prod DD_VERSION:v1
Hostname:
Network IPs:
PID: 0
Cgroup path:
`,
"source:source2 id: ctr-id": `----------- Entity ID -----------
Kind: container ID: ctr-id
Expand Down Expand Up @@ -163,6 +166,7 @@ Allowed env variables:
Hostname:
Network IPs:
PID: 1
Cgroup path: /default/ctr-id
`,
"sources(merged):[source1 source2] id: ctr-id": `----------- Entity ID -----------
Kind: container ID: ctr-id
Expand Down Expand Up @@ -192,6 +196,7 @@ Allowed env variables: DD_SERVICE:my-svc DD_ENV:prod DD_VERSION:v1
Hostname:
Network IPs:
PID: 1
Cgroup path: /default/ctr-id
`,
},
},
Expand Down
5 changes: 5 additions & 0 deletions comp/core/workloadmeta/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,10 @@ type Container struct {
Owner *EntityID
SecurityContext *ContainerSecurityContext
Resources ContainerResources
// CgroupPath is a path to the cgroup of the container.
// It can be relative to the cgroup parent.
// Linux only.
CgroupPath string
AliDatadog marked this conversation as resolved.
Show resolved Hide resolved
}

// GetID implements Entity#GetID.
Expand Down Expand Up @@ -575,6 +579,7 @@ func (c Container) String(verbose bool) string {
_, _ = fmt.Fprintln(&sb, "Hostname:", c.Hostname)
_, _ = fmt.Fprintln(&sb, "Network IPs:", mapToString(c.NetworkIPs))
_, _ = fmt.Fprintln(&sb, "PID:", c.PID)
_, _ = fmt.Fprintln(&sb, "Cgroup path:", c.CgroupPath)
}

if len(c.Ports) > 0 && verbose {
Expand Down
2 changes: 1 addition & 1 deletion comp/dogstatsd/server/convert_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,5 @@ type ServerDeps struct {
}

func newServerDeps(t testing.TB, options ...fx.Option) ServerDeps {
return fxutil.Test[ServerDeps](t, core.MockBundle(), workloadmeta.MockModule(), fx.Supply(workloadmeta.NewParams()), fx.Options(options...))
return fxutil.Test[ServerDeps](t, core.MockBundle(), workloadmeta.MockModuleV2(), fx.Supply(workloadmeta.NewParams()), fx.Options(options...))
}
3 changes: 2 additions & 1 deletion pkg/proto/datadog/workloadmeta/workloadmeta.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ message ContainerImage {
string name = 3;
string shortName = 4;
string tag = 5;
string repo_digest = 6;
string repo_digest = 6;
}

message ContainerPort {
Expand Down Expand Up @@ -106,6 +106,7 @@ message Container {
Runtime runtime = 9;
ContainerState state = 10;
repeated string collectorTags = 11;
string cgroupPath = 12;
}

message KubernetesPodOwner {
Expand Down
4 changes: 2 additions & 2 deletions pkg/proto/pbgo/core/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 0 additions & 28 deletions pkg/proto/pbgo/core/api.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/proto/pbgo/core/model.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/proto/pbgo/core/remoteconfig.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.