Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
290786d
fix: container_fs metrics {device} has no label or info-metric to ass…
tiemma Feb 21, 2026
3aec924
fix: add in volume type field to simplify filters
tiemma Feb 21, 2026
2826591
fix: remove erroenous disk io metric
tiemma Feb 21, 2026
2d39afe
tests: update fixtures
tiemma Feb 21, 2026
e19515e
Merge branch 'google:master' into add-host-container-mountpoint
tiemma Mar 5, 2026
3364ac9
fix: export all mountpoints in container_fs_device_info
tiemma Mar 15, 2026
1365409
fix: expose volume details on container metrics directly
tiemma Mar 16, 2026
385941a
fix: fallback to major:minor format for unrecognized devices in devic…
umegbewe May 16, 2026
4b6ca67
fix: remove fsValues
tiemma May 16, 2026
b1f8581
chore: rename module and go mod tidy
tiemma May 16, 2026
b76146c
Fix start/creation time metrics in docker, podman and containerd
ultinous-akos Mar 5, 2026
2f0f2fa
deps: bump github.com/containerd/ttrpc v1.2.8
thaJeztah Apr 10, 2026
45ec1d7
deps: github.com/moby/moby/client v0.4.0, moby/api v1.54.1
thaJeztah Apr 10, 2026
d00f0ac
update k8s-staging-test-infra image in integ tests
sambhav-jain-16 Apr 13, 2026
36770de
fix(test/integration): fix TestDockerContainerSpec
sambhav-jain-16 Apr 14, 2026
98375a0
feat(manager): add constraint data in OOM events
sambhav-jain-16 Apr 1, 2026
b481ab1
test(integration): add integration test for oom constraint
sambhav-jain-16 Apr 2, 2026
23badf1
add initial splay and max jitter factors
sambhav-jain-16 Mar 17, 2026
097d28e
fix: add v-prefixed GHCR image tags for consistency with GitHub Releases
hwan515 Mar 26, 2026
5192f92
build(deps): bump the go_modules group across 2 directories with 1 up…
dependabot[bot] Mar 19, 2026
c20473b
Expose cgroup v2 memory.events as Prometheus metrics
sohankunkerkar May 7, 2026
231a236
deploy: bump base images to Alpine 3.23
dims May 14, 2026
befdcea
fix: fallback to major:minor format for unrecognized devices in devic…
umegbewe May 16, 2026
651958f
fix: PR comments
tiemma May 16, 2026
59a5c3b
fix: host container paths
tiemma May 16, 2026
216e114
fix: final PR comments
tiemma May 16, 2026
fbfa336
fix: revert go module name
tiemma May 16, 2026
d8d2703
Merge origin/master into add-host-container-mountpoint
tiemma May 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/integration-in-docker-crio.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function run_tests() {
--cgroupns=host \
--pid=host \
--entrypoint="" \
gcr.io/k8s-staging-test-infra/bootstrap:v20251209-855adc2699 \
gcr.io/k8s-staging-test-infra/bootstrap@sha256:2e537f9aea810021ecd022bf085e99099a25fc4bb95de96eeb510e92a524b471 \
bash -c "export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y $PACKAGES curl conntrack iptables dbus && \
Expand Down
8 changes: 4 additions & 4 deletions cmd/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ go 1.24.0
// The github.com/google/cadvisor/cmd module is built using the Makefile
// from a clone of the github.com/google/cadvisor repository, so we
// always use the relative local source rather than specifying a module version.
require github.com/google/cadvisor v0.0.0
require github.com/google/cadvisor v0.57.0

// Use the relative local source of the github.com/google/cadvisor library to build
replace github.com/google/cadvisor => ../
Expand Down Expand Up @@ -107,9 +107,9 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.39.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect
go.opentelemetry.io/otel/trace v1.39.0 // indirect
go.opentelemetry.io/otel v1.41.0 // indirect
go.opentelemetry.io/otel/metric v1.41.0 // indirect
go.opentelemetry.io/otel/trace v1.41.0 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sys v0.39.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions cmd/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,16 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c=
go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE=
go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ=
go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0=
go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
Expand Down
4 changes: 4 additions & 0 deletions container/common/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ func (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string
return s
}
s, _ := namer.DeviceName(major, minor)
if s == "" {
s = fmt.Sprintf("%d:%d", major, minor)
}

m[d] = s
return s
}
Expand Down
61 changes: 61 additions & 0 deletions container/common/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,67 @@ func TestRemoveNetMetrics(t *testing.T) {
}
}

type deviceNamerFunc func(major, minor uint64) (string, bool)

func (f deviceNamerFunc) DeviceName(major, minor uint64) (string, bool) {
return f(major, minor)
}

func TestDeviceIdentifierMapFindFallsBackToMajorMinor(t *testing.T) {
for _, tc := range []struct {
name string
namer DeviceNamer
expected string
}{
{
name: "unrecognized device",
namer: deviceNamerFunc(func(_, _ uint64) (string, bool) {
return "", false
}),
expected: "8:0",
},
{
name: "recognized empty device",
namer: deviceNamerFunc(func(_, _ uint64) (string, bool) {
return "", true
}),
expected: "8:0",
},
{
name: "recognized device",
namer: deviceNamerFunc(func(_, _ uint64) (string, bool) {
return "/dev/sda", true
}),
expected: "/dev/sda",
},
} {
t.Run(tc.name, func(t *testing.T) {
devices := make(deviceIdentifierMap)
assert.Equal(t, tc.expected, devices.Find(8, 0, tc.namer))
})
}
}

func TestAssignDeviceNamesToDiskStatsKeepsUnresolvedDevicesUnique(t *testing.T) {
stats := &info.DiskIoStats{
IoServiceBytes: []info.PerDiskStats{
{Major: 8, Minor: 0},
{Major: 259, Minor: 1},
},
IoServiced: []info.PerDiskStats{
{Major: 8, Minor: 0},
},
}

AssignDeviceNamesToDiskStats(deviceNamerFunc(func(_, _ uint64) (string, bool) {
return "", false
}), stats)

assert.Equal(t, "8:0", stats.IoServiceBytes[0].Device)
assert.Equal(t, "259:1", stats.IoServiceBytes[1].Device)
assert.Equal(t, "8:0", stats.IoServiced[0].Device)
}

func BenchmarkGetSpecCgroupV2(b *testing.B) {
root, err := os.Getwd()
if err != nil {
Expand Down
26 changes: 24 additions & 2 deletions container/raw/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ func fsToFsStats(fs *fs.Fs) info.FsStats {
Inodes: inodes,
InodesFree: inodesFree,
Available: fs.Available,
Mountpoint: fs.Mountpoint,
AllMountpoints: fs.AllMountpoints,
ReadsCompleted: fs.DiskStats.ReadsCompleted,
ReadsMerged: fs.DiskStats.ReadsMerged,
SectorsRead: fs.DiskStats.SectorsRead,
Expand Down Expand Up @@ -215,9 +217,29 @@ func (h *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
}

if h.includedMetrics.Has(container.DiskUsageMetrics) {
// Build a map from host-side mount directory to container-side path
// from the external mounts (container hints) configuration.
hostToContainerPath := make(map[string]string, len(h.externalMounts))
for _, m := range h.externalMounts {
if m.HostDir != "" && m.ContainerDir != "" {
hostToContainerPath[m.HostDir] = m.ContainerDir
}
}

for i := range filesystems {
fs := filesystems[i]
stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
fsCopy := filesystems[i]
fsstat := fsToFsStats(&fsCopy)
if containerPath, ok := hostToContainerPath[fsstat.Mountpoint]; ok {
fsstat.ContainerPath = containerPath
} else {
for _, mountpoint := range fsstat.AllMountpoints {
if containerPath, ok := hostToContainerPath[mountpoint]; ok {
fsstat.ContainerPath = containerPath
break
}
}
}
stats.Filesystem = append(stats.Filesystem, fsstat)
}
}

Expand Down
94 changes: 94 additions & 0 deletions container/raw/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ func TestFsToFsStats(t *testing.T) {
WeightedIoTime: uint64(100),
},
},
"has_mountpoint": {
fs: &fs.Fs{
DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb"},
Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
Type: fs.VFS,
Capacity: uint64(1024 * 1024),
Free: uint64(1024),
Available: uint64(1024),
},
expected: info.FsStats{
Device: "/dev/sdb",
Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
Type: fs.VFS.String(),
Limit: uint64(1024 * 1024),
Usage: uint64(1024*1024) - uint64(1024),
Available: uint64(1024),
},
},
}
for testName, testCase := range testCases {
actual := fsToFsStats(testCase.fs)
Expand Down Expand Up @@ -381,6 +399,82 @@ func TestGetFsStats(t *testing.T) {
},
},
},
"random container with mountpoint and container path": {
name: "/random/container",
includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}},
externalMounts: []common.Mount{
{
HostDir: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
ContainerDir: "/data",
},
},
getFsInfoForPath: func(mountSet map[string]struct{}) ([]fs.Fs, error) {
return []fs.Fs{{
DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb", Major: 8, Minor: 0},
Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
Type: "ext4",
Capacity: 1000,
Free: 500,
Available: 450,
Inodes: &inodes,
InodesFree: &inodesFree,
}}, nil
},
expectedFilesystems: []info.FsStats{{
Device: "/dev/sdb",
Mountpoint: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
ContainerPath: "/data",
Type: "ext4",
Limit: 1000,
Usage: 500,
Available: 450,
HasInodes: true,
Inodes: 2000,
InodesFree: 1000,
}},
},
"random container with all mountpoints container path": {
name: "/random/container",
includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}},
externalMounts: []common.Mount{
{
HostDir: "/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
ContainerDir: "/data",
},
},
getFsInfoForPath: func(mountSet map[string]struct{}) ([]fs.Fs, error) {
return []fs.Fs{{
DeviceInfo: fs.DeviceInfo{Device: "/dev/sdb", Major: 8, Minor: 0},
Mountpoint: "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount",
AllMountpoints: []string{
"/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount",
"/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
},
Type: "ext4",
Capacity: 1000,
Free: 500,
Available: 450,
Inodes: &inodes,
InodesFree: &inodesFree,
}}, nil
},
expectedFilesystems: []info.FsStats{{
Device: "/dev/sdb",
Mountpoint: "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount",
AllMountpoints: []string{
"/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc/globalmount",
"/var/lib/kubelet/pods/abc123/volumes/kubernetes.io~csi/my-pvc/mount",
},
ContainerPath: "/data",
Type: "ext4",
Limit: 1000,
Usage: 500,
Available: 450,
HasInodes: true,
Inodes: 2000,
InodesFree: 1000,
}},
},
"random container with disk metrics enabled": {
name: "/random/container",
includedMetrics: container.MetricSet{container.DiskUsageMetrics: struct{}{}, container.DiskIOMetrics: struct{}{}},
Expand Down
5 changes: 2 additions & 3 deletions deploy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM registry.hub.docker.com/library/golang:1.25-alpine3.23 AS build
FROM registry.hub.docker.com/library/golang:1.25-alpine3.23@sha256:8d22e29d960bc50cd025d93d5b7c7d220b1ee9aa7a239b3c8f55a57e987e8d45 AS build

# Install build depdencies for all supported arches
RUN apk --no-cache add bash build-base cmake device-mapper findutils git \
Expand Down Expand Up @@ -49,7 +49,7 @@ RUN export GO_TAGS="libpfm,netgo"; \
fi; \
GO_FLAGS="-tags=$GO_TAGS" ./build/build.sh

FROM mirror.gcr.io/library/alpine:3.23
FROM mirror.gcr.io/library/alpine:3.23@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11
MAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com jimmidyson@gmail.com stclair@google.com

RUN apk --no-cache add libc6-compat device-mapper findutils ndctl thin-provisioning-tools zfs && \
Expand Down Expand Up @@ -77,4 +77,3 @@ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \

# Use entrypoint wrapper
ENTRYPOINT ["/usr/bin/entrypoint.sh"]

Loading