diff --git a/go.mod b/go.mod
index f641d852b78..5ccb8ee8574 100644
--- a/go.mod
+++ b/go.mod
@@ -32,7 +32,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.0
github.com/davecgh/go-spew v1.1.1
github.com/docker/distribution v2.7.1+incompatible
- github.com/docker/docker v20.10.2+incompatible
+ github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.4.0
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153
@@ -45,7 +45,7 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
github.com/golang/mock v1.5.0
github.com/golang/protobuf v1.5.2
- github.com/google/cadvisor v0.39.2
+ github.com/google/cadvisor v0.43.0
github.com/google/go-cmp v0.5.5
github.com/google/gofuzz v1.1.0
github.com/google/uuid v1.1.2
@@ -78,6 +78,7 @@ require (
github.com/storageos/go-api v2.2.0+incompatible
github.com/stretchr/testify v1.7.0
github.com/vishvananda/netlink v1.1.0
+ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
github.com/vmware/govmomi v0.20.3
go.etcd.io/etcd/api/v3 v3.5.0
go.etcd.io/etcd/client/pkg/v3 v3.5.0
@@ -198,7 +199,7 @@ replace (
github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.5.0
github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1
github.com/containerd/console => github.com/containerd/console v1.0.2
- github.com/containerd/containerd => github.com/containerd/containerd v1.4.9
+ github.com/containerd/containerd => github.com/containerd/containerd v1.4.11
github.com/containerd/continuity => github.com/containerd/continuity v0.1.0
github.com/containerd/fifo => github.com/containerd/fifo v1.0.0
github.com/containerd/go-runc => github.com/containerd/go-runc v1.0.0
@@ -217,7 +218,7 @@ replace (
github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd
github.com/dnaeon/go-vcr => github.com/dnaeon/go-vcr v1.0.1
github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
- github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible
+ github.com/docker/docker => github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections => github.com/docker/go-connections v0.4.0
github.com/docker/go-units => github.com/docker/go-units v0.4.0
github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
@@ -262,7 +263,7 @@ replace (
github.com/golang/protobuf => github.com/golang/protobuf v1.5.2
github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e
github.com/google/btree => github.com/google/btree v1.0.1
- github.com/google/cadvisor => github.com/google/cadvisor v0.39.2
+ github.com/google/cadvisor => github.com/google/cadvisor v0.43.0
github.com/google/go-cmp => github.com/google/go-cmp v0.5.5
github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
github.com/google/martian/v3 => github.com/google/martian/v3 v3.1.0
diff --git a/go.sum b/go.sum
index 89251bd0ef0..4b7230d69a0 100644
--- a/go.sum
+++ b/go.sum
@@ -101,8 +101,8 @@ github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
-github.com/containerd/containerd v1.4.9 h1:JIw9mjVw4LsGmnA/Bqg9j9e+XB7soOJufrKUpA6n2Ns=
-github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/containerd v1.4.11 h1:QCGOUN+i70jEEL/A6JVIbhy4f4fanzAzSR4kNG7SlcE=
+github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
@@ -136,8 +136,8 @@ github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw=
-github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
+github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
@@ -212,8 +212,8 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZ
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
-github.com/google/cadvisor v0.39.2 h1:SzgL5IYoMZEFVA9usi0xCy8SXSVXKQ6aL/rYs/kQjXE=
-github.com/google/cadvisor v0.39.2/go.mod h1:kN93gpdevu+bpS227TyHVZyCU5bbqCzTj5T9drl34MI=
+github.com/google/cadvisor v0.43.0 h1:z0ULgYPKZ7L/c7Zjq+ZD6ltklWwYdCSvBMgSjNC/hGo=
+github.com/google/cadvisor v0.43.0/go.mod h1:+RdMSbc3FVr5NYCD2dOEJy/LI0jYJ/0xJXkzWXEyiFQ=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml
index 9f1019681af..1294e5a22cf 100644
--- a/vendor/github.com/docker/docker/api/swagger.yaml
+++ b/vendor/github.com/docker/docker/api/swagger.yaml
@@ -560,7 +560,7 @@ definitions:
format: "int64"
minimum: 0
maximum: 100
- NanoCPUs:
+ NanoCpus:
description: "CPU quota in units of 10-9 CPUs."
type: "integer"
format: "int64"
@@ -5466,7 +5466,7 @@ paths:
MemorySwap: 0
MemoryReservation: 0
KernelMemory: 0
- NanoCPUs: 500000
+ NanoCpus: 500000
CpuPercent: 80
CpuShares: 512
CpuPeriod: 100000
@@ -7310,7 +7310,7 @@ paths:
For example, the build arg `FOO=bar` would become `{"FOO":"bar"}` in JSON. This would result in the
- the query parameter `buildargs={"FOO":"bar"}`. Note that `{"FOO":"bar"}` should be URI component encoded.
+ query parameter `buildargs={"FOO":"bar"}`. Note that `{"FOO":"bar"}` should be URI component encoded.
[Read more about the buildargs instruction.](https://docs.docker.com/engine/reference/builder/#arg)
diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go
index 68064ca9c5f..21edf1fa1fc 100644
--- a/vendor/github.com/docker/docker/client/client.go
+++ b/vendor/github.com/docker/docker/client/client.go
@@ -2,7 +2,7 @@
Package client is a Go client for the Docker Engine API.
For more information about the Engine API, see the documentation:
-https://docs.docker.com/engine/reference/api/
+https://docs.docker.com/engine/api/
Usage
diff --git a/vendor/github.com/google/cadvisor/client/v2/client.go b/vendor/github.com/google/cadvisor/client/v2/client.go
index 91e183aa096..ecd68cf21ae 100644
--- a/vendor/github.com/google/cadvisor/client/v2/client.go
+++ b/vendor/github.com/google/cadvisor/client/v2/client.go
@@ -27,7 +27,7 @@ import (
"strings"
v1 "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/info/v2"
+ v2 "github.com/google/cadvisor/info/v2"
)
// Client represents the base URL for a cAdvisor client.
diff --git a/vendor/github.com/google/cadvisor/collector/collector_manager.go b/vendor/github.com/google/cadvisor/collector/collector_manager.go
index e2ccd80d512..bb8ee27c97e 100644
--- a/vendor/github.com/google/cadvisor/collector/collector_manager.go
+++ b/vendor/github.com/google/cadvisor/collector/collector_manager.go
@@ -19,7 +19,7 @@ import (
"strings"
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
const metricLabelPrefix = "io.cadvisor.metric."
diff --git a/vendor/github.com/google/cadvisor/collector/config.go b/vendor/github.com/google/cadvisor/collector/config.go
index 5c7cc77f947..27df0672b1a 100644
--- a/vendor/github.com/google/cadvisor/collector/config.go
+++ b/vendor/github.com/google/cadvisor/collector/config.go
@@ -18,7 +18,8 @@ import (
"time"
"encoding/json"
- "github.com/google/cadvisor/info/v1"
+
+ v1 "github.com/google/cadvisor/info/v1"
)
type Config struct {
diff --git a/vendor/github.com/google/cadvisor/collector/fakes.go b/vendor/github.com/google/cadvisor/collector/fakes.go
index 28606ad051e..cc61cf5bff1 100644
--- a/vendor/github.com/google/cadvisor/collector/fakes.go
+++ b/vendor/github.com/google/cadvisor/collector/fakes.go
@@ -17,7 +17,7 @@ package collector
import (
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
type FakeCollectorManager struct {
diff --git a/vendor/github.com/google/cadvisor/collector/generic_collector.go b/vendor/github.com/google/cadvisor/collector/generic_collector.go
index 27483018ebe..07e26a2dab0 100644
--- a/vendor/github.com/google/cadvisor/collector/generic_collector.go
+++ b/vendor/github.com/google/cadvisor/collector/generic_collector.go
@@ -25,7 +25,7 @@ import (
"time"
"github.com/google/cadvisor/container"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
type GenericCollector struct {
diff --git a/vendor/github.com/google/cadvisor/collector/prometheus_collector.go b/vendor/github.com/google/cadvisor/collector/prometheus_collector.go
index 17249da61ac..cd653dd8f60 100644
--- a/vendor/github.com/google/cadvisor/collector/prometheus_collector.go
+++ b/vendor/github.com/google/cadvisor/collector/prometheus_collector.go
@@ -28,7 +28,7 @@ import (
"github.com/prometheus/common/model"
"github.com/google/cadvisor/container"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
type PrometheusCollector struct {
diff --git a/vendor/github.com/google/cadvisor/collector/types.go b/vendor/github.com/google/cadvisor/collector/types.go
index 5416a3dd360..e03b40003c0 100644
--- a/vendor/github.com/google/cadvisor/collector/types.go
+++ b/vendor/github.com/google/cadvisor/collector/types.go
@@ -17,7 +17,7 @@ package collector
import (
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
// TODO(vmarmol): Export to a custom metrics type when that is available.
diff --git a/vendor/github.com/google/cadvisor/container/common/fsHandler.go b/vendor/github.com/google/cadvisor/container/common/fsHandler.go
index 5b506b04a1e..f944b2277a4 100644
--- a/vendor/github.com/google/cadvisor/container/common/fsHandler.go
+++ b/vendor/github.com/google/cadvisor/container/common/fsHandler.go
@@ -96,7 +96,12 @@ func (fh *realFsHandler) update() error {
fh.usage.TotalUsageBytes = rootUsage.Bytes
}
if fh.extraDir != "" && extraErr == nil {
- fh.usage.TotalUsageBytes += extraUsage.Bytes
+ if fh.rootfs != "" {
+ fh.usage.TotalUsageBytes += extraUsage.Bytes
+ } else {
+ // rootfs is empty, totalUsageBytes use extra usage bytes
+ fh.usage.TotalUsageBytes = extraUsage.Bytes
+ }
}
// Combine errors into a single error to return
diff --git a/vendor/github.com/google/cadvisor/container/common/helpers.go b/vendor/github.com/google/cadvisor/container/common/helpers.go
index 19241e7937f..03d055f93b9 100644
--- a/vendor/github.com/google/cadvisor/container/common/helpers.go
+++ b/vendor/github.com/google/cadvisor/container/common/helpers.go
@@ -24,14 +24,15 @@ import (
"strings"
"time"
- "github.com/google/cadvisor/container"
- info "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/utils"
"github.com/karrick/godirwalk"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
+ "github.com/google/cadvisor/container"
+ info "github.com/google/cadvisor/info/v1"
+ "github.com/google/cadvisor/utils"
+
"k8s.io/klog/v2"
)
@@ -104,7 +105,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
}
// CPU.
- cpuRoot, ok := cgroupPaths["cpu"]
+ cpuRoot, ok := getControllerPath(cgroupPaths, "cpu", cgroup2UnifiedMode)
if ok {
if utils.FileExists(cpuRoot) {
if cgroup2UnifiedMode {
@@ -151,7 +152,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
// Cpu Mask.
// This will fail for non-unified hierarchies. We'll return the whole machine mask in that case.
- cpusetRoot, ok := cgroupPaths["cpuset"]
+ cpusetRoot, ok := getControllerPath(cgroupPaths, "cpuset", cgroup2UnifiedMode)
if ok {
if utils.FileExists(cpusetRoot) {
spec.HasCpu = true
@@ -166,7 +167,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
}
// Memory
- memoryRoot, ok := cgroupPaths["memory"]
+ memoryRoot, ok := getControllerPath(cgroupPaths, "memory", cgroup2UnifiedMode)
if ok {
if cgroup2UnifiedMode {
if utils.FileExists(path.Join(memoryRoot, "memory.max")) {
@@ -194,7 +195,7 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
}
// Processes, read it's value from pids path directly
- pidsRoot, ok := cgroupPaths["pids"]
+ pidsRoot, ok := getControllerPath(cgroupPaths, "pids", cgroup2UnifiedMode)
if ok {
if utils.FileExists(pidsRoot) {
spec.HasProcesses = true
@@ -216,6 +217,19 @@ func getSpecInternal(cgroupPaths map[string]string, machineInfoFactory info.Mach
return spec, nil
}
+func getControllerPath(cgroupPaths map[string]string, controllerName string, cgroup2UnifiedMode bool) (string, bool) {
+
+ ok := false
+ path := ""
+
+ if cgroup2UnifiedMode {
+ path, ok = cgroupPaths[""]
+ } else {
+ path, ok = cgroupPaths[controllerName]
+ }
+ return path, ok
+}
+
func readString(dirpath string, file string) string {
cgroupFile := path.Join(dirpath, file)
diff --git a/vendor/github.com/google/cadvisor/container/containerd/client.go b/vendor/github.com/google/cadvisor/container/containerd/client.go
index 47eaffad7bd..02fd8ce782d 100644
--- a/vendor/github.com/google/cadvisor/container/containerd/client.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/client.go
@@ -24,10 +24,10 @@ import (
containersapi "github.com/containerd/containerd/api/services/containers/v1"
tasksapi "github.com/containerd/containerd/api/services/tasks/v1"
versionapi "github.com/containerd/containerd/api/services/version/v1"
- "github.com/containerd/containerd/containers"
- "github.com/containerd/containerd/errdefs"
- "github.com/containerd/containerd/pkg/dialer"
ptypes "github.com/gogo/protobuf/types"
+ "github.com/google/cadvisor/container/containerd/containers"
+ "github.com/google/cadvisor/container/containerd/errdefs"
+ "github.com/google/cadvisor/container/containerd/pkg/dialer"
"google.golang.org/grpc"
"google.golang.org/grpc/backoff"
)
diff --git a/vendor/github.com/containerd/containerd/containers/containers.go b/vendor/github.com/google/cadvisor/container/containerd/containers/containers.go
similarity index 85%
rename from vendor/github.com/containerd/containerd/containers/containers.go
rename to vendor/github.com/google/cadvisor/container/containerd/containers/containers.go
index 7174bbd6aa6..3e6467ffd56 100644
--- a/vendor/github.com/containerd/containerd/containers/containers.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/containers/containers.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/google/cadvisor/container/containerd/errdefs/errors.go b/vendor/github.com/google/cadvisor/container/containerd/errdefs/errors.go
new file mode 100644
index 00000000000..cbee285e09b
--- /dev/null
+++ b/vendor/github.com/google/cadvisor/container/containerd/errdefs/errors.go
@@ -0,0 +1,106 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+// Package errdefs defines the common errors used throughout containerd
+// packages.
+//
+// Use with errors.Wrap and error.Wrapf to add context to an error.
+//
+// To detect an error class, use the IsXXX functions to tell whether an error
+// is of a certain type.
+//
+// The functions ToGRPC and FromGRPC can be used to map server-side and
+// client-side errors to the correct types.
+package errdefs
+
+import (
+ "context"
+
+ "github.com/pkg/errors"
+)
+
+// Definitions of common error types used throughout containerd. All containerd
+// errors returned by most packages will map into one of these errors classes.
+// Packages should return errors of these types when they want to instruct a
+// client to take a particular action.
+//
+// For the most part, we just try to provide local grpc errors. Most conditions
+// map very well to those defined by grpc.
+var (
+ ErrUnknown = errors.New("unknown") // used internally to represent a missed mapping.
+ ErrInvalidArgument = errors.New("invalid argument")
+ ErrNotFound = errors.New("not found")
+ ErrAlreadyExists = errors.New("already exists")
+ ErrFailedPrecondition = errors.New("failed precondition")
+ ErrUnavailable = errors.New("unavailable")
+ ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented
+)
+
+// IsInvalidArgument returns true if the error is due to an invalid argument
+func IsInvalidArgument(err error) bool {
+ return errors.Is(err, ErrInvalidArgument)
+}
+
+// IsNotFound returns true if the error is due to a missing object
+func IsNotFound(err error) bool {
+ return errors.Is(err, ErrNotFound)
+}
+
+// IsAlreadyExists returns true if the error is due to an already existing
+// metadata item
+func IsAlreadyExists(err error) bool {
+ return errors.Is(err, ErrAlreadyExists)
+}
+
+// IsFailedPrecondition returns true if an operation could not proceed to the
+// lack of a particular condition
+func IsFailedPrecondition(err error) bool {
+ return errors.Is(err, ErrFailedPrecondition)
+}
+
+// IsUnavailable returns true if the error is due to a resource being unavailable
+func IsUnavailable(err error) bool {
+ return errors.Is(err, ErrUnavailable)
+}
+
+// IsNotImplemented returns true if the error is due to not being implemented
+func IsNotImplemented(err error) bool {
+ return errors.Is(err, ErrNotImplemented)
+}
+
+// IsCanceled returns true if the error is due to `context.Canceled`.
+func IsCanceled(err error) bool {
+ return errors.Is(err, context.Canceled)
+}
+
+// IsDeadlineExceeded returns true if the error is due to
+// `context.DeadlineExceeded`.
+func IsDeadlineExceeded(err error) bool {
+ return errors.Is(err, context.DeadlineExceeded)
+}
diff --git a/vendor/github.com/google/cadvisor/container/containerd/errdefs/grpc.go b/vendor/github.com/google/cadvisor/container/containerd/errdefs/grpc.go
new file mode 100644
index 00000000000..65795e9c868
--- /dev/null
+++ b/vendor/github.com/google/cadvisor/container/containerd/errdefs/grpc.go
@@ -0,0 +1,160 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+/*
+ Copyright The containerd Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package errdefs
+
+import (
+ "context"
+ "strings"
+
+ "github.com/pkg/errors"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+// ToGRPC will attempt to map the backend containerd error into a grpc error,
+// using the original error message as a description.
+//
+// Further information may be extracted from certain errors depending on their
+// type.
+//
+// If the error is unmapped, the original error will be returned to be handled
+// by the regular grpc error handling stack.
+func ToGRPC(err error) error {
+ if err == nil {
+ return nil
+ }
+
+ if isGRPCError(err) {
+ // error has already been mapped to grpc
+ return err
+ }
+
+ switch {
+ case IsInvalidArgument(err):
+ return status.Errorf(codes.InvalidArgument, err.Error())
+ case IsNotFound(err):
+ return status.Errorf(codes.NotFound, err.Error())
+ case IsAlreadyExists(err):
+ return status.Errorf(codes.AlreadyExists, err.Error())
+ case IsFailedPrecondition(err):
+ return status.Errorf(codes.FailedPrecondition, err.Error())
+ case IsUnavailable(err):
+ return status.Errorf(codes.Unavailable, err.Error())
+ case IsNotImplemented(err):
+ return status.Errorf(codes.Unimplemented, err.Error())
+ case IsCanceled(err):
+ return status.Errorf(codes.Canceled, err.Error())
+ case IsDeadlineExceeded(err):
+ return status.Errorf(codes.DeadlineExceeded, err.Error())
+ }
+
+ return err
+}
+
+// ToGRPCf maps the error to grpc error codes, assembling the formatting string
+// and combining it with the target error string.
+//
+// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
+func ToGRPCf(err error, format string, args ...interface{}) error {
+ return ToGRPC(errors.Wrapf(err, format, args...))
+}
+
+// FromGRPC returns the underlying error from a grpc service based on the grpc error code
+func FromGRPC(err error) error {
+ if err == nil {
+ return nil
+ }
+
+ var cls error // divide these into error classes, becomes the cause
+
+ switch code(err) {
+ case codes.InvalidArgument:
+ cls = ErrInvalidArgument
+ case codes.AlreadyExists:
+ cls = ErrAlreadyExists
+ case codes.NotFound:
+ cls = ErrNotFound
+ case codes.Unavailable:
+ cls = ErrUnavailable
+ case codes.FailedPrecondition:
+ cls = ErrFailedPrecondition
+ case codes.Unimplemented:
+ cls = ErrNotImplemented
+ case codes.Canceled:
+ cls = context.Canceled
+ case codes.DeadlineExceeded:
+ cls = context.DeadlineExceeded
+ default:
+ cls = ErrUnknown
+ }
+
+ msg := rebaseMessage(cls, err)
+ if msg != "" {
+ err = errors.Wrap(cls, msg)
+ } else {
+ err = errors.WithStack(cls)
+ }
+
+ return err
+}
+
+// rebaseMessage removes the repeats for an error at the end of an error
+// string. This will happen when taking an error over grpc then remapping it.
+//
+// Effectively, we just remove the string of cls from the end of err if it
+// appears there.
+func rebaseMessage(cls error, err error) string {
+ desc := errDesc(err)
+ clss := cls.Error()
+ if desc == clss {
+ return ""
+ }
+
+ return strings.TrimSuffix(desc, ": "+clss)
+}
+
+func isGRPCError(err error) bool {
+ _, ok := status.FromError(err)
+ return ok
+}
+
+func code(err error) codes.Code {
+ if s, ok := status.FromError(err); ok {
+ return s.Code()
+ }
+ return codes.Unknown
+}
+
+func errDesc(err error) string {
+ if s, ok := status.FromError(err); ok {
+ return s.Message()
+ }
+ return err.Error()
+}
diff --git a/vendor/github.com/google/cadvisor/container/containerd/factory.go b/vendor/github.com/google/cadvisor/container/containerd/factory.go
index 56e45c412ef..d44abc4eac7 100644
--- a/vendor/github.com/google/cadvisor/container/containerd/factory.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/factory.go
@@ -34,6 +34,8 @@ import (
var ArgContainerdEndpoint = flag.String("containerd", "/run/containerd/containerd.sock", "containerd endpoint")
var ArgContainerdNamespace = flag.String("containerd-namespace", "k8s.io", "containerd namespace")
+var containerdEnvMetadataWhiteList = flag.String("containerd_env_metadata_whitelist", "", "DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for containerd containers")
+
// The namespace under which containerd aliases are unique.
const k8sContainerdNamespace = "containerd"
@@ -46,7 +48,7 @@ type containerdFactory struct {
client ContainerdClient
version string
// Information about the mounted cgroup subsystems.
- cgroupSubsystems libcontainer.CgroupSubsystems
+ cgroupSubsystems map[string]string
// Information about mounted filesystems.
fsInfo fs.FsInfo
includedMetrics container.MetricSet
@@ -56,21 +58,27 @@ func (f *containerdFactory) String() string {
return k8sContainerdNamespace
}
-func (f *containerdFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
+func (f *containerdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
client, err := Client(*ArgContainerdEndpoint, *ArgContainerdNamespace)
if err != nil {
return
}
- metadataEnvs := []string{}
+ containerdMetadataEnvAllowList := strings.Split(*containerdEnvMetadataWhiteList, ",")
+
+ // prefer using the unified metadataEnvAllowList
+ if len(metadataEnvAllowList) != 0 {
+ containerdMetadataEnvAllowList = metadataEnvAllowList
+ }
+
return newContainerdContainerHandler(
client,
name,
f.machineInfoFactory,
f.fsInfo,
- &f.cgroupSubsystems,
+ f.cgroupSubsystems,
inHostNamespace,
- metadataEnvs,
+ containerdMetadataEnvAllowList,
f.includedMetrics,
)
}
diff --git a/vendor/github.com/google/cadvisor/container/containerd/grpc.go b/vendor/github.com/google/cadvisor/container/containerd/grpc.go
index ba04eb1e238..9765a66bd18 100644
--- a/vendor/github.com/google/cadvisor/container/containerd/grpc.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/grpc.go
@@ -16,7 +16,7 @@
package containerd
import (
- "github.com/containerd/containerd/namespaces"
+ "github.com/google/cadvisor/container/containerd/namespaces"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
diff --git a/vendor/github.com/google/cadvisor/container/containerd/handler.go b/vendor/github.com/google/cadvisor/container/containerd/handler.go
index c213979027b..0fc88035420 100644
--- a/vendor/github.com/google/cadvisor/container/containerd/handler.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/handler.go
@@ -21,15 +21,17 @@ import (
"strings"
"time"
- "github.com/containerd/containerd/errdefs"
+ "github.com/google/cadvisor/container/containerd/errdefs"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
"golang.org/x/net/context"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
containerlibcontainer "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
- specs "github.com/opencontainers/runtime-spec/specs-go"
)
type containerdContainerHandler struct {
@@ -58,13 +60,13 @@ func newContainerdContainerHandler(
name string,
machineInfoFactory info.MachineInfoFactory,
fsInfo fs.FsInfo,
- cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
+ cgroupSubsystems map[string]string,
inHostNamespace bool,
- metadataEnvs []string,
+ metadataEnvAllowList []string,
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
- cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
+ cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
@@ -133,11 +135,19 @@ func newContainerdContainerHandler(
}
// Add the name and bare ID as aliases of the container.
handler.image = cntr.Image
- for _, envVar := range spec.Process.Env {
- if envVar != "" {
- splits := strings.SplitN(envVar, "=", 2)
- if len(splits) == 2 {
- handler.envs[splits[0]] = splits[1]
+
+ for _, exposedEnv := range metadataEnvAllowList {
+ if exposedEnv == "" {
+ // if no containerdEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == ""
+ continue
+ }
+
+ for _, envVar := range spec.Process.Env {
+ if envVar != "" {
+ splits := strings.SplitN(envVar, "=", 2)
+ if len(splits) == 2 && strings.HasPrefix(splits[0], exposedEnv) {
+ handler.envs[splits[0]] = splits[1]
+ }
}
}
}
@@ -207,7 +217,11 @@ func (h *containerdContainerHandler) ListContainers(listType container.ListType)
}
func (h *containerdContainerHandler) GetCgroupPath(resource string) (string, error) {
- path, ok := h.cgroupPaths[resource]
+ var res string
+ if !cgroups.IsCgroup2UnifiedMode() {
+ res = resource
+ }
+ path, ok := h.cgroupPaths[res]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
}
diff --git a/vendor/github.com/containerd/containerd/identifiers/validate.go b/vendor/github.com/google/cadvisor/container/containerd/identifiers/validate.go
similarity index 76%
rename from vendor/github.com/containerd/containerd/identifiers/validate.go
rename to vendor/github.com/google/cadvisor/container/containerd/identifiers/validate.go
index f52317b491b..a3cea8ec981 100644
--- a/vendor/github.com/containerd/containerd/identifiers/validate.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/identifiers/validate.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
@@ -27,7 +40,7 @@ package identifiers
import (
"regexp"
- "github.com/containerd/containerd/errdefs"
+ "github.com/google/cadvisor/container/containerd/errdefs"
"github.com/pkg/errors"
)
diff --git a/vendor/github.com/google/cadvisor/container/containerd/install/install.go b/vendor/github.com/google/cadvisor/container/containerd/install/install.go
index b5b0a941405..274357cb0b6 100644
--- a/vendor/github.com/google/cadvisor/container/containerd/install/install.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/install/install.go
@@ -16,9 +16,10 @@
package install
import (
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/containerd"
- "k8s.io/klog/v2"
)
func init() {
diff --git a/vendor/github.com/containerd/containerd/namespaces/context.go b/vendor/github.com/google/cadvisor/container/containerd/namespaces/context.go
similarity index 76%
rename from vendor/github.com/containerd/containerd/namespaces/context.go
rename to vendor/github.com/google/cadvisor/container/containerd/namespaces/context.go
index b53c9012c1b..87a9654e23e 100644
--- a/vendor/github.com/containerd/containerd/namespaces/context.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/namespaces/context.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
@@ -20,8 +33,8 @@ import (
"context"
"os"
- "github.com/containerd/containerd/errdefs"
- "github.com/containerd/containerd/identifiers"
+ "github.com/google/cadvisor/container/containerd/errdefs"
+ "github.com/google/cadvisor/container/containerd/identifiers"
"github.com/pkg/errors"
)
diff --git a/vendor/github.com/containerd/containerd/namespaces/grpc.go b/vendor/github.com/google/cadvisor/container/containerd/namespaces/grpc.go
similarity index 73%
rename from vendor/github.com/containerd/containerd/namespaces/grpc.go
rename to vendor/github.com/google/cadvisor/container/containerd/namespaces/grpc.go
index 6991460da6e..e7f59215898 100644
--- a/vendor/github.com/containerd/containerd/namespaces/grpc.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/namespaces/grpc.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/containerd/namespaces/store.go b/vendor/github.com/google/cadvisor/container/containerd/namespaces/store.go
similarity index 73%
rename from vendor/github.com/containerd/containerd/namespaces/store.go
rename to vendor/github.com/google/cadvisor/container/containerd/namespaces/store.go
index 5936772cb4c..67f49b52fe5 100644
--- a/vendor/github.com/containerd/containerd/namespaces/store.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/namespaces/store.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/containerd/namespaces/ttrpc.go b/vendor/github.com/google/cadvisor/container/containerd/namespaces/ttrpc.go
similarity index 68%
rename from vendor/github.com/containerd/containerd/namespaces/ttrpc.go
rename to vendor/github.com/google/cadvisor/container/containerd/namespaces/ttrpc.go
index bcd2643cf5e..60a175e0452 100644
--- a/vendor/github.com/containerd/containerd/namespaces/ttrpc.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/namespaces/ttrpc.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer.go
similarity index 75%
rename from vendor/github.com/containerd/containerd/pkg/dialer/dialer.go
rename to vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer.go
index aa604baab92..b13208d6900 100644
--- a/vendor/github.com/containerd/containerd/pkg/dialer/dialer.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go
similarity index 66%
rename from vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go
rename to vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go
index e7d19583395..f03945ba9af 100644
--- a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_unix.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go
@@ -1,3 +1,17 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//go:build !windows
// +build !windows
/*
diff --git a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_windows.go b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_windows.go
similarity index 61%
rename from vendor/github.com/containerd/containerd/pkg/dialer/dialer_windows.go
rename to vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_windows.go
index 4dd296ebc3e..84b4942258f 100644
--- a/vendor/github.com/containerd/containerd/pkg/dialer/dialer_windows.go
+++ b/vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_windows.go
@@ -1,3 +1,16 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
/*
Copyright The containerd Authors.
diff --git a/vendor/github.com/google/cadvisor/container/crio/factory.go b/vendor/github.com/google/cadvisor/container/crio/factory.go
index 32f607680f6..e16b68a2a0a 100644
--- a/vendor/github.com/google/cadvisor/container/crio/factory.go
+++ b/vendor/github.com/google/cadvisor/container/crio/factory.go
@@ -32,6 +32,9 @@ import (
// The namespace under which crio aliases are unique.
const CrioNamespace = "crio"
+// The namespace systemd runs components under.
+const SystemdNamespace = "system-systemd"
+
// Regexp that identifies CRI-O cgroups
var crioCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
@@ -50,7 +53,7 @@ type crioFactory struct {
storageDir string
// Information about the mounted cgroup subsystems.
- cgroupSubsystems libcontainer.CgroupSubsystems
+ cgroupSubsystems map[string]string
// Information about mounted filesystems.
fsInfo fs.FsInfo
@@ -64,13 +67,11 @@ func (f *crioFactory) String() string {
return CrioNamespace
}
-func (f *crioFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
+func (f *crioFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
client, err := Client()
if err != nil {
return
}
- // TODO are there any env vars we need to white list, if so, do it here...
- metadataEnvs := []string{}
handler, err = newCrioContainerHandler(
client,
name,
@@ -78,9 +79,9 @@ func (f *crioFactory) NewContainerHandler(name string, inHostNamespace bool) (ha
f.fsInfo,
f.storageDriver,
f.storageDir,
- &f.cgroupSubsystems,
+ f.cgroupSubsystems,
inHostNamespace,
- metadataEnvs,
+ metadataEnvAllowList,
f.includedMetrics,
)
return
@@ -116,6 +117,9 @@ func (f *crioFactory) CanHandleAndAccept(name string) (bool, bool, error) {
if !strings.HasPrefix(path.Base(name), CrioNamespace) {
return false, false, nil
}
+ if strings.HasPrefix(path.Base(name), SystemdNamespace) {
+ return true, false, nil
+ }
// if the container is not associated with CRI-O, we can't handle it or accept it.
if !isContainerName(name) {
return false, false, nil
diff --git a/vendor/github.com/google/cadvisor/container/crio/handler.go b/vendor/github.com/google/cadvisor/container/crio/handler.go
index b1ef5b045de..9a06cac3533 100644
--- a/vendor/github.com/google/cadvisor/container/crio/handler.go
+++ b/vendor/github.com/google/cadvisor/container/crio/handler.go
@@ -21,12 +21,13 @@ import (
"strconv"
"strings"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
containerlibcontainer "github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
- "github.com/opencontainers/runc/libcontainer/cgroups"
)
type crioContainerHandler struct {
@@ -83,13 +84,13 @@ func newCrioContainerHandler(
fsInfo fs.FsInfo,
storageDriver storageDriver,
storageDir string,
- cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
+ cgroupSubsystems map[string]string,
inHostNamespace bool,
- metadataEnvs []string,
+ metadataEnvAllowList []string,
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
- cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
+ cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
@@ -186,7 +187,7 @@ func newCrioContainerHandler(
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, rootfsStorageDir, storageLogDir, fsInfo)
}
// TODO for env vars we wanted to show from container.Config.Env from whitelist
- //for _, exposedEnv := range metadataEnvs {
+ //for _, exposedEnv := range metadataEnvAllowList {
//klog.V(4).Infof("TODO env whitelist: %v", exposedEnv)
//}
@@ -327,7 +328,11 @@ func (h *crioContainerHandler) ListContainers(listType container.ListType) ([]in
}
func (h *crioContainerHandler) GetCgroupPath(resource string) (string, error) {
- path, ok := h.cgroupPaths[resource]
+ var res string
+ if !cgroups.IsCgroup2UnifiedMode() {
+ res = resource
+ }
+ path, ok := h.cgroupPaths[res]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
}
diff --git a/vendor/github.com/google/cadvisor/container/crio/install/install.go b/vendor/github.com/google/cadvisor/container/crio/install/install.go
index dac0e423248..c49df71f60a 100644
--- a/vendor/github.com/google/cadvisor/container/crio/install/install.go
+++ b/vendor/github.com/google/cadvisor/container/crio/install/install.go
@@ -16,9 +16,10 @@
package install
import (
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/crio"
- "k8s.io/klog/v2"
)
func init() {
diff --git a/vendor/github.com/google/cadvisor/container/crio/plugin.go b/vendor/github.com/google/cadvisor/container/crio/plugin.go
index 84e55075877..8937d0680a8 100644
--- a/vendor/github.com/google/cadvisor/container/crio/plugin.go
+++ b/vendor/github.com/google/cadvisor/container/crio/plugin.go
@@ -15,11 +15,12 @@
package crio
import (
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
- "k8s.io/klog/v2"
)
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
diff --git a/vendor/github.com/google/cadvisor/container/docker/docker.go b/vendor/github.com/google/cadvisor/container/docker/docker.go
index 0f49c9d3330..05934bf9705 100644
--- a/vendor/github.com/google/cadvisor/container/docker/docker.go
+++ b/vendor/github.com/google/cadvisor/container/docker/docker.go
@@ -25,7 +25,7 @@ import (
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine"
)
diff --git a/vendor/github.com/google/cadvisor/container/docker/factory.go b/vendor/github.com/google/cadvisor/container/docker/factory.go
index 1490a88f41b..287563dac4d 100644
--- a/vendor/github.com/google/cadvisor/container/docker/factory.go
+++ b/vendor/github.com/google/cadvisor/container/docker/factory.go
@@ -26,6 +26,7 @@ import (
"github.com/blang/semver"
dockertypes "github.com/docker/docker/api/types"
+
"github.com/google/cadvisor/container"
dockerutil "github.com/google/cadvisor/container/docker/utils"
"github.com/google/cadvisor/container/libcontainer"
@@ -47,21 +48,21 @@ var ArgDockerCert = flag.String("docker-tls-cert", "cert.pem", "path to client c
var ArgDockerKey = flag.String("docker-tls-key", "key.pem", "path to private key")
var ArgDockerCA = flag.String("docker-tls-ca", "ca.pem", "path to trusted CA")
+var dockerEnvMetadataWhiteList = flag.String("docker_env_metadata_whitelist", "", "DEPRECATED: this flag will be removed, please use `env_metadata_whitelist`. A comma-separated list of environment variable keys matched with specified prefix that needs to be collected for docker containers")
+
// The namespace under which Docker aliases are unique.
const DockerNamespace = "docker"
// The retry times for getting docker root dir
const rootDirRetries = 5
-//The retry period for getting docker root dir, Millisecond
+// The retry period for getting docker root dir, Millisecond
const rootDirRetryPeriod time.Duration = 1000 * time.Millisecond
// Regexp that identifies docker cgroups, containers started with
// --cgroup-parent have another prefix than 'docker'
var dockerCgroupRegexp = regexp.MustCompile(`([a-z0-9]{64})`)
-var dockerEnvWhitelist = flag.String("docker_env_metadata_whitelist", "", "a comma-separated list of environment variable keys matched with specified prefix that needs to be collected for docker containers")
-
var (
// Basepath to all container specific information that libcontainer stores.
dockerRootDir string
@@ -115,7 +116,7 @@ type dockerFactory struct {
client *docker.Client
// Information about the mounted cgroup subsystems.
- cgroupSubsystems libcontainer.CgroupSubsystems
+ cgroupSubsystems map[string]string
// Information about mounted filesystems.
fsInfo fs.FsInfo
@@ -136,13 +137,18 @@ func (f *dockerFactory) String() string {
return DockerNamespace
}
-func (f *dockerFactory) NewContainerHandler(name string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
+func (f *dockerFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (handler container.ContainerHandler, err error) {
client, err := Client()
if err != nil {
return
}
- metadataEnvs := strings.Split(*dockerEnvWhitelist, ",")
+ dockerMetadataEnvAllowList := strings.Split(*dockerEnvMetadataWhiteList, ",")
+
+ // prefer using the unified metadataEnvAllowList
+ if len(metadataEnvAllowList) != 0 {
+ dockerMetadataEnvAllowList = metadataEnvAllowList
+ }
handler, err = newDockerContainerHandler(
client,
@@ -151,9 +157,9 @@ func (f *dockerFactory) NewContainerHandler(name string, inHostNamespace bool) (
f.fsInfo,
f.storageDriver,
f.storageDir,
- &f.cgroupSubsystems,
+ f.cgroupSubsystems,
inHostNamespace,
- metadataEnvs,
+ dockerMetadataEnvAllowList,
f.dockerVersion,
f.includedMetrics,
f.thinPoolName,
diff --git a/vendor/github.com/google/cadvisor/container/docker/handler.go b/vendor/github.com/google/cadvisor/container/docker/handler.go
index e9afc752446..bfb8e381659 100644
--- a/vendor/github.com/google/cadvisor/container/docker/handler.go
+++ b/vendor/github.com/google/cadvisor/container/docker/handler.go
@@ -31,6 +31,7 @@ import (
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/zfs"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
dockercontainer "github.com/docker/docker/api/types/container"
docker "github.com/docker/docker/client"
@@ -121,9 +122,9 @@ func newDockerContainerHandler(
fsInfo fs.FsInfo,
storageDriver storageDriver,
storageDir string,
- cgroupSubsystems *containerlibcontainer.CgroupSubsystems,
+ cgroupSubsystems map[string]string,
inHostNamespace bool,
- metadataEnvs []string,
+ metadataEnvAllowList []string,
dockerVersion []int,
includedMetrics container.MetricSet,
thinPoolName string,
@@ -131,7 +132,7 @@ func newDockerContainerHandler(
zfsWatcher *zfs.ZfsWatcher,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
- cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
+ cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager, err := containerlibcontainer.NewCgroupManager(name, cgroupPaths)
@@ -249,9 +250,9 @@ func newDockerContainerHandler(
}
// split env vars to get metadata map.
- for _, exposedEnv := range metadataEnvs {
+ for _, exposedEnv := range metadataEnvAllowList {
if exposedEnv == "" {
- // if no dockerEnvWhitelist provided, len(metadataEnvs) == 1, metadataEnvs[0] == ""
+ // if no dockerEnvWhitelist provided, len(metadataEnvAllowList) == 1, metadataEnvAllowList[0] == ""
continue
}
@@ -484,7 +485,11 @@ func (h *dockerContainerHandler) ListContainers(listType container.ListType) ([]
}
func (h *dockerContainerHandler) GetCgroupPath(resource string) (string, error) {
- path, ok := h.cgroupPaths[resource]
+ var res string
+ if !cgroups.IsCgroup2UnifiedMode() {
+ res = resource
+ }
+ path, ok := h.cgroupPaths[res]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.reference.Name)
}
diff --git a/vendor/github.com/google/cadvisor/container/docker/install/install.go b/vendor/github.com/google/cadvisor/container/docker/install/install.go
index 58de720923e..81346f68806 100644
--- a/vendor/github.com/google/cadvisor/container/docker/install/install.go
+++ b/vendor/github.com/google/cadvisor/container/docker/install/install.go
@@ -16,9 +16,10 @@
package install
import (
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/docker"
- "k8s.io/klog/v2"
)
func init() {
diff --git a/vendor/github.com/google/cadvisor/container/docker/plugin.go b/vendor/github.com/google/cadvisor/container/docker/plugin.go
index 2f5f0986e63..07e471a732f 100644
--- a/vendor/github.com/google/cadvisor/container/docker/plugin.go
+++ b/vendor/github.com/google/cadvisor/container/docker/plugin.go
@@ -17,12 +17,13 @@ package docker
import (
"time"
+ "golang.org/x/net/context"
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/watcher"
- "golang.org/x/net/context"
- "k8s.io/klog/v2"
)
const dockerClientTimeout = 10 * time.Second
diff --git a/vendor/github.com/google/cadvisor/container/factory.go b/vendor/github.com/google/cadvisor/container/factory.go
index 56d198976ef..8f32f8c6af7 100644
--- a/vendor/github.com/google/cadvisor/container/factory.go
+++ b/vendor/github.com/google/cadvisor/container/factory.go
@@ -16,6 +16,8 @@ package container
import (
"fmt"
+ "sort"
+ "strings"
"sync"
"github.com/google/cadvisor/fs"
@@ -27,7 +29,7 @@ import (
type ContainerHandlerFactory interface {
// Create a new ContainerHandler using this factory. CanHandleAndAccept() must have returned true.
- NewContainerHandler(name string, inHostNamespace bool) (c ContainerHandler, err error)
+ NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (c ContainerHandler, err error)
// Returns whether this factory can handle and accept the specified container.
CanHandleAndAccept(name string) (handle bool, accept bool, err error)
@@ -64,6 +66,7 @@ const (
CPUTopologyMetrics MetricKind = "cpu_topology"
ResctrlMetrics MetricKind = "resctrl"
CPUSetMetrics MetricKind = "cpuset"
+ OOMMetrics MetricKind = "oom_event"
)
// AllMetrics represents all kinds of metrics that cAdvisor supported.
@@ -89,6 +92,7 @@ var AllMetrics = MetricSet{
CPUTopologyMetrics: struct{}{},
ResctrlMetrics: struct{}{},
CPUSetMetrics: struct{}{},
+ OOMMetrics: struct{}{},
}
func (mk MetricKind) String() string {
@@ -102,15 +106,50 @@ func (ms MetricSet) Has(mk MetricKind) bool {
return exists
}
-func (ms MetricSet) Add(mk MetricKind) {
+func (ms MetricSet) add(mk MetricKind) {
ms[mk] = struct{}{}
}
+func (ms MetricSet) String() string {
+ values := make([]string, 0, len(ms))
+ for metric := range ms {
+ values = append(values, string(metric))
+ }
+ sort.Strings(values)
+ return strings.Join(values, ",")
+}
+
+// Not thread-safe, exported only for https://pkg.go.dev/flag#Value
+func (ms *MetricSet) Set(value string) error {
+ *ms = MetricSet{}
+ if value == "" {
+ return nil
+ }
+ for _, metric := range strings.Split(value, ",") {
+ if AllMetrics.Has(MetricKind(metric)) {
+ (*ms).add(MetricKind(metric))
+ } else {
+ return fmt.Errorf("unsupported metric %q specified", metric)
+ }
+ }
+ return nil
+}
+
func (ms MetricSet) Difference(ms1 MetricSet) MetricSet {
result := MetricSet{}
for kind := range ms {
if !ms1.Has(kind) {
- result.Add(kind)
+ result.add(kind)
+ }
+ }
+ return result
+}
+
+func (ms MetricSet) Append(ms1 MetricSet) MetricSet {
+ result := ms
+ for kind := range ms1 {
+ if !ms.Has(kind) {
+ result.add(kind)
}
}
return result
@@ -198,12 +237,15 @@ func HasFactories() bool {
}
// Create a new ContainerHandler for the specified container.
-func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, inHostNamespace bool) (ContainerHandler, bool, error) {
+func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, metadataEnvAllowList []string, inHostNamespace bool) (ContainerHandler, bool, error) {
factoriesLock.RLock()
defer factoriesLock.RUnlock()
// Create the ContainerHandler with the first factory that supports it.
- for _, factory := range factories[watchType] {
+ // Note that since RawContainerHandler can support a wide range of paths,
+ // it's evaluated last just to make sure if any other ContainerHandler
+ // can support it.
+ for _, factory := range GetReorderedFactoryList(watchType) {
canHandle, canAccept, err := factory.CanHandleAndAccept(name)
if err != nil {
klog.V(4).Infof("Error trying to work out if we can handle %s: %v", name, err)
@@ -214,7 +256,7 @@ func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, in
return nil, false, nil
}
klog.V(3).Infof("Using factory %q for container %q", factory, name)
- handle, err := factory.NewContainerHandler(name, inHostNamespace)
+ handle, err := factory.NewContainerHandler(name, metadataEnvAllowList, inHostNamespace)
return handle, canAccept, err
}
klog.V(4).Infof("Factory %q was unable to handle container %q", factory, name)
@@ -246,3 +288,26 @@ func DebugInfo() map[string][]string {
}
return out
}
+
+// GetReorderedFactoryList returns the list of ContainerHandlerFactory where the
+// RawContainerHandler is always the last element.
+func GetReorderedFactoryList(watchType watcher.ContainerWatchSource) []ContainerHandlerFactory {
+ ContainerHandlerFactoryList := make([]ContainerHandlerFactory, 0, len(factories))
+
+ var rawFactory ContainerHandlerFactory
+ for _, v := range factories[watchType] {
+ if v != nil {
+ if v.String() == "raw" {
+ rawFactory = v
+ continue
+ }
+ ContainerHandlerFactoryList = append(ContainerHandlerFactoryList, v)
+ }
+ }
+
+ if rawFactory != nil {
+ ContainerHandlerFactoryList = append(ContainerHandlerFactoryList, rawFactory)
+ }
+
+ return ContainerHandlerFactoryList
+}
diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go
index 4bfb6aef88a..e599029386d 100644
--- a/vendor/github.com/google/cadvisor/container/libcontainer/handler.go
+++ b/vendor/github.com/google/cadvisor/container/libcontainer/handler.go
@@ -54,7 +54,10 @@ type Handler struct {
rootFs string
pid int
includedMetrics container.MetricSet
+ // pidMetricsCache holds CPU scheduler stats for existing processes (map key is PID) between calls to schedulerStatsFromProcs.
pidMetricsCache map[int]*info.CpuSchedstat
+ // pidMetricsSaved holds accumulated CPU scheduler stats for processes that no longer exist.
+ pidMetricsSaved info.CpuSchedstat
cycles uint64
}
@@ -93,14 +96,9 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
stats := newContainerStats(libcontainerStats, h.includedMetrics)
if h.includedMetrics.Has(container.ProcessSchedulerMetrics) {
- pids, err := h.cgroupManager.GetAllPids()
+ stats.Cpu.Schedstat, err = h.schedulerStatsFromProcs()
if err != nil {
- klog.V(4).Infof("Could not get PIDs for container %d: %v", h.pid, err)
- } else {
- stats.Cpu.Schedstat, err = schedulerStatsFromProcs(h.rootFs, pids, h.pidMetricsCache)
- if err != nil {
- klog.V(4).Infof("Unable to get Process Scheduler Stats: %v", err)
- }
+ klog.V(4).Infof("Unable to get Process Scheduler Stats: %v", err)
}
}
@@ -314,9 +312,14 @@ func processStatsFromProcs(rootFs string, cgroupPath string, rootPid int) (info.
return processStats, nil
}
-func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]*info.CpuSchedstat) (info.CpuSchedstat, error) {
+func (h *Handler) schedulerStatsFromProcs() (info.CpuSchedstat, error) {
+ pids, err := h.cgroupManager.GetAllPids()
+ if err != nil {
+ return info.CpuSchedstat{}, fmt.Errorf("Could not get PIDs for container %d: %w", h.pid, err)
+ }
+ alivePids := make(map[int]struct{}, len(pids))
for _, pid := range pids {
- f, err := os.Open(path.Join(rootFs, "proc", strconv.Itoa(pid), "schedstat"))
+ f, err := os.Open(path.Join(h.rootFs, "proc", strconv.Itoa(pid), "schedstat"))
if err != nil {
return info.CpuSchedstat{}, fmt.Errorf("couldn't open scheduler statistics for process %d: %v", pid, err)
}
@@ -325,14 +328,15 @@ func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]
if err != nil {
return info.CpuSchedstat{}, fmt.Errorf("couldn't read scheduler statistics for process %d: %v", pid, err)
}
+ alivePids[pid] = struct{}{}
rawMetrics := bytes.Split(bytes.TrimRight(contents, "\n"), []byte(" "))
if len(rawMetrics) != 3 {
return info.CpuSchedstat{}, fmt.Errorf("unexpected number of metrics in schedstat file for process %d", pid)
}
- cacheEntry, ok := pidMetricsCache[pid]
+ cacheEntry, ok := h.pidMetricsCache[pid]
if !ok {
cacheEntry = &info.CpuSchedstat{}
- pidMetricsCache[pid] = cacheEntry
+ h.pidMetricsCache[pid] = cacheEntry
}
for i, rawMetric := range rawMetrics {
metric, err := strconv.ParseUint(string(rawMetric), 10, 64)
@@ -349,11 +353,20 @@ func schedulerStatsFromProcs(rootFs string, pids []int, pidMetricsCache map[int]
}
}
}
- schedstats := info.CpuSchedstat{}
- for _, v := range pidMetricsCache {
+ schedstats := h.pidMetricsSaved // copy
+ for p, v := range h.pidMetricsCache {
schedstats.RunPeriods += v.RunPeriods
schedstats.RunqueueTime += v.RunqueueTime
schedstats.RunTime += v.RunTime
+ if _, alive := alivePids[p]; !alive {
+ // PID p is gone: accumulate its stats ...
+ h.pidMetricsSaved.RunPeriods += v.RunPeriods
+ h.pidMetricsSaved.RunqueueTime += v.RunqueueTime
+ h.pidMetricsSaved.RunTime += v.RunTime
+ // ... and remove its cache entry, to prevent
+ // pidMetricsCache from growing.
+ delete(h.pidMetricsCache, p)
+ }
}
return schedstats, nil
}
@@ -383,7 +396,7 @@ func getReferencedKBytes(pids []int) (uint64, error) {
if err != nil {
klog.V(5).Infof("Cannot read %s file, err: %s", smapsFilePath, err)
if os.IsNotExist(err) {
- continue //smaps file does not exists for all PIDs
+ continue // smaps file does not exists for all PIDs
}
return 0, err
}
@@ -426,7 +439,7 @@ func clearReferencedBytes(pids []int, cycles uint64, resetInterval uint64) error
if cycles%resetInterval == 0 {
for _, pid := range pids {
clearRefsFilePath := fmt.Sprintf(clearRefsFilePathPattern, pid)
- clerRefsFile, err := os.OpenFile(clearRefsFilePath, os.O_WRONLY, 0644)
+ clerRefsFile, err := os.OpenFile(clearRefsFilePath, os.O_WRONLY, 0o644)
if err != nil {
// clear_refs file may not exist for all PIDs
continue
@@ -455,9 +468,7 @@ func networkStatsFromProc(rootFs string, pid int) ([]info.InterfaceStats, error)
return ifaceStats, nil
}
-var (
- ignoredDevicePrefixes = []string{"lo", "veth", "docker"}
-)
+var ignoredDevicePrefixes = []string{"lo", "veth", "docker"}
func isIgnoredDevice(ifName string) bool {
for _, prefix := range ignoredDevicePrefixes {
@@ -615,11 +626,9 @@ func scanAdvancedTCPStats(advancedStats *info.TcpAdvancedStat, advancedTCPStatsF
}
return scanner.Err()
-
}
func scanTCPStats(tcpStatsFile string) (info.TcpStat, error) {
-
var stats info.TcpStat
data, err := ioutil.ReadFile(tcpStatsFile)
@@ -628,17 +637,17 @@ func scanTCPStats(tcpStatsFile string) (info.TcpStat, error) {
}
tcpStateMap := map[string]uint64{
- "01": 0, //ESTABLISHED
- "02": 0, //SYN_SENT
- "03": 0, //SYN_RECV
- "04": 0, //FIN_WAIT1
- "05": 0, //FIN_WAIT2
- "06": 0, //TIME_WAIT
- "07": 0, //CLOSE
- "08": 0, //CLOSE_WAIT
- "09": 0, //LAST_ACK
- "0A": 0, //LISTEN
- "0B": 0, //CLOSING
+ "01": 0, // ESTABLISHED
+ "02": 0, // SYN_SENT
+ "03": 0, // SYN_RECV
+ "04": 0, // FIN_WAIT1
+ "05": 0, // FIN_WAIT2
+ "06": 0, // TIME_WAIT
+ "07": 0, // CLOSE
+ "08": 0, // CLOSE_WAIT
+ "09": 0, // LAST_ACK
+ "0A": 0, // LISTEN
+ "0B": 0, // CLOSING
}
reader := strings.NewReader(string(data))
@@ -779,14 +788,14 @@ func setCPUStats(s *cgroups.Stats, ret *info.ContainerStats, withPerCPU bool) {
}
func setDiskIoStats(s *cgroups.Stats, ret *info.ContainerStats) {
- ret.DiskIo.IoServiceBytes = DiskStatsCopy(s.BlkioStats.IoServiceBytesRecursive)
- ret.DiskIo.IoServiced = DiskStatsCopy(s.BlkioStats.IoServicedRecursive)
- ret.DiskIo.IoQueued = DiskStatsCopy(s.BlkioStats.IoQueuedRecursive)
- ret.DiskIo.Sectors = DiskStatsCopy(s.BlkioStats.SectorsRecursive)
- ret.DiskIo.IoServiceTime = DiskStatsCopy(s.BlkioStats.IoServiceTimeRecursive)
- ret.DiskIo.IoWaitTime = DiskStatsCopy(s.BlkioStats.IoWaitTimeRecursive)
- ret.DiskIo.IoMerged = DiskStatsCopy(s.BlkioStats.IoMergedRecursive)
- ret.DiskIo.IoTime = DiskStatsCopy(s.BlkioStats.IoTimeRecursive)
+ ret.DiskIo.IoServiceBytes = diskStatsCopy(s.BlkioStats.IoServiceBytesRecursive)
+ ret.DiskIo.IoServiced = diskStatsCopy(s.BlkioStats.IoServicedRecursive)
+ ret.DiskIo.IoQueued = diskStatsCopy(s.BlkioStats.IoQueuedRecursive)
+ ret.DiskIo.Sectors = diskStatsCopy(s.BlkioStats.SectorsRecursive)
+ ret.DiskIo.IoServiceTime = diskStatsCopy(s.BlkioStats.IoServiceTimeRecursive)
+ ret.DiskIo.IoWaitTime = diskStatsCopy(s.BlkioStats.IoWaitTimeRecursive)
+ ret.DiskIo.IoMerged = diskStatsCopy(s.BlkioStats.IoMergedRecursive)
+ ret.DiskIo.IoTime = diskStatsCopy(s.BlkioStats.IoTimeRecursive)
}
func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
@@ -797,7 +806,7 @@ func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
if cgroups.IsCgroup2UnifiedMode() {
ret.Memory.Cache = s.MemoryStats.Stats["file"]
ret.Memory.RSS = s.MemoryStats.Stats["anon"]
- ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage
+ ret.Memory.Swap = s.MemoryStats.SwapUsage.Usage - s.MemoryStats.Usage.Usage
ret.Memory.MappedFile = s.MemoryStats.Stats["file_mapped"]
} else if s.MemoryStats.UseHierarchy {
ret.Memory.Cache = s.MemoryStats.Stats["total_cache"]
@@ -896,7 +905,6 @@ func setThreadsStats(s *cgroups.Stats, ret *info.ContainerStats) {
ret.Processes.ThreadsCurrent = s.PidsStats.Current
ret.Processes.ThreadsMax = s.PidsStats.Limit
}
-
}
func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats {
diff --git a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
index 030504373f2..e0d7718c876 100644
--- a/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
+++ b/vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
@@ -19,71 +19,49 @@ import (
info "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/container"
"github.com/opencontainers/runc/libcontainer/cgroups"
+ "github.com/google/cadvisor/container"
+
fs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
fs2 "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
configs "github.com/opencontainers/runc/libcontainer/configs"
"k8s.io/klog/v2"
)
-type CgroupSubsystems struct {
- // Cgroup subsystem mounts.
- // e.g.: "/sys/fs/cgroup/cpu" -> ["cpu", "cpuacct"]
- Mounts []cgroups.Mount
-
- // Cgroup subsystem to their mount location.
- // e.g.: "cpu" -> "/sys/fs/cgroup/cpu"
- MountPoints map[string]string
-}
-
-// Get information about the cgroup subsystems those we want
-func GetCgroupSubsystems(includedMetrics container.MetricSet) (CgroupSubsystems, error) {
+// GetCgroupSubsystems returns information about the cgroup subsystems that are
+// of interest as a map of cgroup controllers to their mount points.
+// For example, "cpu" -> "/sys/fs/cgroup/cpu".
+//
+// The incudeMetrics arguments specifies which metrics are requested,
+// and is used to filter out some cgroups and their mounts. If nil,
+// all supported cgroup subsystems are included.
+//
+// For cgroup v2, includedMetrics argument is unused, the only map key is ""
+// (empty string), and the value is the unified cgroup mount point.
+func GetCgroupSubsystems(includedMetrics container.MetricSet) (map[string]string, error) {
+ if cgroups.IsCgroup2UnifiedMode() {
+ return map[string]string{"": fs2.UnifiedMountpoint}, nil
+ }
// Get all cgroup mounts.
allCgroups, err := cgroups.GetCgroupMounts(true)
if err != nil {
- return CgroupSubsystems{}, err
+ return nil, err
}
- disableCgroups := map[string]struct{}{}
-
- //currently we only support disable blkio subsystem
- if !includedMetrics.Has(container.DiskIOMetrics) {
- disableCgroups["blkio"] = struct{}{}
- disableCgroups["io"] = struct{}{}
- }
- return getCgroupSubsystemsHelper(allCgroups, disableCgroups)
+ return getCgroupSubsystemsHelper(allCgroups, includedMetrics)
}
-// Get information about all the cgroup subsystems.
-func GetAllCgroupSubsystems() (CgroupSubsystems, error) {
- // Get all cgroup mounts.
- allCgroups, err := cgroups.GetCgroupMounts(true)
- if err != nil {
- return CgroupSubsystems{}, err
- }
-
- emptyDisableCgroups := map[string]struct{}{}
- return getCgroupSubsystemsHelper(allCgroups, emptyDisableCgroups)
-}
-
-func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[string]struct{}) (CgroupSubsystems, error) {
+func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, includedMetrics container.MetricSet) (map[string]string, error) {
if len(allCgroups) == 0 {
- return CgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts")
+ return nil, fmt.Errorf("failed to find cgroup mounts")
}
// Trim the mounts to only the subsystems we care about.
- supportedCgroups := make([]cgroups.Mount, 0, len(allCgroups))
- recordedMountpoints := make(map[string]struct{}, len(allCgroups))
mountPoints := make(map[string]string, len(allCgroups))
for _, mount := range allCgroups {
for _, subsystem := range mount.Subsystems {
- if _, exists := disableCgroups[subsystem]; exists {
- continue
- }
- if _, ok := supportedSubsystems[subsystem]; !ok {
- // Unsupported subsystem
+ if !needSubsys(subsystem, includedMetrics) {
continue
}
if _, ok := mountPoints[subsystem]; ok {
@@ -91,36 +69,44 @@ func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[st
klog.V(5).Infof("skipping %s, already using mount at %s", mount.Mountpoint, mountPoints[subsystem])
continue
}
- if _, ok := recordedMountpoints[mount.Mountpoint]; !ok {
- // avoid appending the same mount twice in e.g. `cpu,cpuacct` case
- supportedCgroups = append(supportedCgroups, mount)
- recordedMountpoints[mount.Mountpoint] = struct{}{}
- }
mountPoints[subsystem] = mount.Mountpoint
}
}
- return CgroupSubsystems{
- Mounts: supportedCgroups,
- MountPoints: mountPoints,
- }, nil
+ return mountPoints, nil
}
-// Cgroup subsystems we support listing (should be the minimal set we need stats from).
-var supportedSubsystems map[string]struct{} = map[string]struct{}{
- "cpu": {},
- "cpuacct": {},
- "memory": {},
- "hugetlb": {},
- "pids": {},
- "cpuset": {},
- "blkio": {},
- "io": {},
- "devices": {},
- "perf_event": {},
+// A map of cgroup subsystems we support listing (should be the minimal set
+// we need stats from) to a respective MetricKind.
+var supportedSubsystems = map[string]container.MetricKind{
+ "cpu": container.CpuUsageMetrics,
+ "cpuacct": container.CpuUsageMetrics,
+ "memory": container.MemoryUsageMetrics,
+ "hugetlb": container.HugetlbUsageMetrics,
+ "pids": container.ProcessMetrics,
+ "cpuset": container.CPUSetMetrics,
+ "blkio": container.DiskIOMetrics,
+ "io": container.DiskIOMetrics,
+ "devices": "",
+ "perf_event": container.PerfMetrics,
}
-func DiskStatsCopy0(major, minor uint64) *info.PerDiskStats {
+// Check if this cgroup subsystem/controller is of use.
+func needSubsys(name string, metrics container.MetricSet) bool {
+ // Check if supported.
+ metric, supported := supportedSubsystems[name]
+ if !supported {
+ return false
+ }
+ // Check if needed.
+ if metrics == nil || metric == "" {
+ return true
+ }
+
+ return metrics.Has(metric)
+}
+
+func diskStatsCopy0(major, minor uint64) *info.PerDiskStats {
disk := info.PerDiskStats{
Major: major,
Minor: minor,
@@ -129,12 +115,12 @@ func DiskStatsCopy0(major, minor uint64) *info.PerDiskStats {
return &disk
}
-type DiskKey struct {
+type diskKey struct {
Major uint64
Minor uint64
}
-func DiskStatsCopy1(diskStat map[DiskKey]*info.PerDiskStats) []info.PerDiskStats {
+func diskStatsCopy1(diskStat map[diskKey]*info.PerDiskStats) []info.PerDiskStats {
i := 0
stat := make([]info.PerDiskStats, len(diskStat))
for _, disk := range diskStat {
@@ -144,21 +130,21 @@ func DiskStatsCopy1(diskStat map[DiskKey]*info.PerDiskStats) []info.PerDiskStats
return stat
}
-func DiskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) {
+func diskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStats) {
if len(blkioStats) == 0 {
return
}
- diskStat := make(map[DiskKey]*info.PerDiskStats)
+ diskStat := make(map[diskKey]*info.PerDiskStats)
for i := range blkioStats {
major := blkioStats[i].Major
minor := blkioStats[i].Minor
- key := DiskKey{
+ key := diskKey{
Major: major,
Minor: minor,
}
diskp, ok := diskStat[key]
if !ok {
- diskp = DiskStatsCopy0(major, minor)
+ diskp = diskStatsCopy0(major, minor)
diskStat[key] = diskp
}
op := blkioStats[i].Op
@@ -167,12 +153,12 @@ func DiskStatsCopy(blkioStats []cgroups.BlkioStatEntry) (stat []info.PerDiskStat
}
diskp.Stats[op] = blkioStats[i].Value
}
- return DiskStatsCopy1(diskStat)
+ return diskStatsCopy1(diskStat)
}
func NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, error) {
if cgroups.IsCgroup2UnifiedMode() {
- path := paths["cpu"]
+ path := paths[""]
return fs2.NewManager(nil, path, false)
}
@@ -180,5 +166,4 @@ func NewCgroupManager(name string, paths map[string]string) (cgroups.Manager, er
Name: name,
}
return fs.NewManager(&config, paths, false), nil
-
}
diff --git a/vendor/github.com/google/cadvisor/container/raw/factory.go b/vendor/github.com/google/cadvisor/container/raw/factory.go
index aa022529c92..0db2b995d3f 100644
--- a/vendor/github.com/google/cadvisor/container/raw/factory.go
+++ b/vendor/github.com/google/cadvisor/container/raw/factory.go
@@ -29,15 +29,17 @@ import (
"k8s.io/klog/v2"
)
-var dockerOnly = flag.Bool("docker_only", false, "Only report docker containers in addition to root stats")
-var disableRootCgroupStats = flag.Bool("disable_root_cgroup_stats", false, "Disable collecting root Cgroup stats")
+var (
+ DockerOnly = flag.Bool("docker_only", false, "Only report docker containers in addition to root stats")
+ disableRootCgroupStats = flag.Bool("disable_root_cgroup_stats", false, "Disable collecting root Cgroup stats")
+)
type rawFactory struct {
// Factory for machine information.
machineInfoFactory info.MachineInfoFactory
// Information about the cgroup subsystems.
- cgroupSubsystems *libcontainer.CgroupSubsystems
+ cgroupSubsystems map[string]string
// Information about mounted filesystems.
fsInfo fs.FsInfo
@@ -56,7 +58,7 @@ func (f *rawFactory) String() string {
return "raw"
}
-func (f *rawFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
+func (f *rawFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {
rootFs := "/"
if !inHostNamespace {
rootFs = "/rootfs"
@@ -69,7 +71,7 @@ func (f *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) {
if name == "/" {
return true, true, nil
}
- if *dockerOnly && f.rawPrefixWhiteList[0] == "" {
+ if *DockerOnly && f.rawPrefixWhiteList[0] == "" {
return true, false, nil
}
for _, prefix := range f.rawPrefixWhiteList {
@@ -89,7 +91,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
- if len(cgroupSubsystems.Mounts) == 0 {
+ if len(cgroupSubsystems) == 0 {
return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
}
@@ -102,7 +104,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl
factory := &rawFactory{
machineInfoFactory: machineInfoFactory,
fsInfo: fsInfo,
- cgroupSubsystems: &cgroupSubsystems,
+ cgroupSubsystems: cgroupSubsystems,
watcher: watcher,
includedMetrics: includedMetrics,
rawPrefixWhiteList: rawPrefixWhiteList,
diff --git a/vendor/github.com/google/cadvisor/container/raw/handler.go b/vendor/github.com/google/cadvisor/container/raw/handler.go
index d9eae2199c4..67a75c3d51e 100644
--- a/vendor/github.com/google/cadvisor/container/raw/handler.go
+++ b/vendor/github.com/google/cadvisor/container/raw/handler.go
@@ -24,6 +24,7 @@ import (
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine"
+ "github.com/opencontainers/runc/libcontainer/cgroups"
"k8s.io/klog/v2"
)
@@ -48,13 +49,13 @@ func isRootCgroup(name string) bool {
return name == "/"
}
-func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSubsystems, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
+func newRawContainerHandler(name string, cgroupSubsystems map[string]string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) {
cHints, err := common.GetContainerHintsFromFile(*common.ArgContainerHints)
if err != nil {
return nil, err
}
- cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
+ cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems, name)
cgroupManager, err := libcontainer.NewCgroupManager(name, cgroupPaths)
if err != nil {
@@ -244,7 +245,11 @@ func (h *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
}
func (h *rawContainerHandler) GetCgroupPath(resource string) (string, error) {
- path, ok := h.cgroupPaths[resource]
+ var res string
+ if !cgroups.IsCgroup2UnifiedMode() {
+ res = resource
+ }
+ path, ok := h.cgroupPaths[res]
if !ok {
return "", fmt.Errorf("could not find path for resource %q for container %q", resource, h.name)
}
diff --git a/vendor/github.com/google/cadvisor/container/raw/watcher.go b/vendor/github.com/google/cadvisor/container/raw/watcher.go
index 26dab7a07e6..6b2a250d78e 100644
--- a/vendor/github.com/google/cadvisor/container/raw/watcher.go
+++ b/vendor/github.com/google/cadvisor/container/raw/watcher.go
@@ -23,10 +23,11 @@ import (
"path"
"strings"
+ inotify "k8s.io/utils/inotify"
+
"github.com/google/cadvisor/container/common"
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/watcher"
- inotify "k8s.io/utils/inotify"
"k8s.io/klog/v2"
)
@@ -35,8 +36,6 @@ type rawContainerWatcher struct {
// Absolute path to the root of the cgroup hierarchies
cgroupPaths map[string]string
- cgroupSubsystems *libcontainer.CgroupSubsystems
-
// Inotify event watcher.
watcher *common.InotifyWatcher
@@ -45,11 +44,11 @@ type rawContainerWatcher struct {
}
func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
- cgroupSubsystems, err := libcontainer.GetAllCgroupSubsystems()
+ cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(nil)
if err != nil {
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
- if len(cgroupSubsystems.Mounts) == 0 {
+ if len(cgroupSubsystems) == 0 {
return nil, fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
}
@@ -59,10 +58,9 @@ func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
}
rawWatcher := &rawContainerWatcher{
- cgroupPaths: common.MakeCgroupPaths(cgroupSubsystems.MountPoints, "/"),
- cgroupSubsystems: &cgroupSubsystems,
- watcher: watcher,
- stopWatcher: make(chan error),
+ cgroupPaths: cgroupSubsystems,
+ watcher: watcher,
+ stopWatcher: make(chan error),
}
return rawWatcher, nil
@@ -195,8 +193,8 @@ func (w *rawContainerWatcher) processEvent(event *inotify.Event, events chan wat
// Derive the container name from the path name.
var containerName string
- for _, mount := range w.cgroupSubsystems.Mounts {
- mountLocation := path.Clean(mount.Mountpoint) + "/"
+ for _, mount := range w.cgroupPaths {
+ mountLocation := path.Clean(mount) + "/"
if strings.HasPrefix(event.Name, mountLocation) {
containerName = event.Name[len(mountLocation)-1:]
break
diff --git a/vendor/github.com/google/cadvisor/container/systemd/factory.go b/vendor/github.com/google/cadvisor/container/systemd/factory.go
index 0d5fc68e0b9..e33f698657e 100644
--- a/vendor/github.com/google/cadvisor/container/systemd/factory.go
+++ b/vendor/github.com/google/cadvisor/container/systemd/factory.go
@@ -32,7 +32,7 @@ func (f *systemdFactory) String() string {
return "systemd"
}
-func (f *systemdFactory) NewContainerHandler(name string, inHostNamespace bool) (container.ContainerHandler, error) {
+func (f *systemdFactory) NewContainerHandler(name string, metadataEnvAllowList []string, inHostNamespace bool) (container.ContainerHandler, error) {
return nil, fmt.Errorf("Not yet supported")
}
diff --git a/vendor/github.com/google/cadvisor/container/systemd/install/install.go b/vendor/github.com/google/cadvisor/container/systemd/install/install.go
index 36f63c5393e..383d7c07b8b 100644
--- a/vendor/github.com/google/cadvisor/container/systemd/install/install.go
+++ b/vendor/github.com/google/cadvisor/container/systemd/install/install.go
@@ -16,9 +16,10 @@
package install
import (
+ "k8s.io/klog/v2"
+
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/systemd"
- "k8s.io/klog/v2"
)
func init() {
diff --git a/vendor/github.com/google/cadvisor/fs/fs.go b/vendor/github.com/google/cadvisor/fs/fs.go
index 91a2d1f2649..f5d4e49ada9 100644
--- a/vendor/github.com/google/cadvisor/fs/fs.go
+++ b/vendor/github.com/google/cadvisor/fs/fs.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build linux
// +build linux
// Provides Filesystem Stats
@@ -19,6 +20,7 @@ package fs
import (
"bufio"
+ "errors"
"fmt"
"io/ioutil"
"os"
@@ -30,11 +32,12 @@ import (
"strings"
"syscall"
- "github.com/google/cadvisor/devicemapper"
- "github.com/google/cadvisor/utils"
zfs "github.com/mistifyio/go-zfs"
mount "github.com/moby/sys/mountinfo"
+ "github.com/google/cadvisor/devicemapper"
+ "github.com/google/cadvisor/utils"
+
"k8s.io/klog/v2"
)
@@ -56,6 +59,9 @@ const (
// A pool for restricting the number of consecutive `du` and `find` tasks running.
var pool = make(chan struct{}, maxConcurrentOps)
+// ErrDeviceNotInPartitionsMap is the error resulting if a device could not be found in the partitions map.
+var ErrDeviceNotInPartitionsMap = errors.New("could not find device in cached partitions map")
+
func init() {
for i := 0; i < maxConcurrentOps; i++ {
releaseToken()
@@ -279,15 +285,17 @@ func (i *RealFsInfo) addSystemRootLabel(mounts []*mount.Info) {
// addDockerImagesLabel attempts to determine which device contains the mount for docker images.
func (i *RealFsInfo) addDockerImagesLabel(context Context, mounts []*mount.Info) {
- dockerDev, dockerPartition, err := i.getDockerDeviceMapperInfo(context.Docker)
- if err != nil {
- klog.Warningf("Could not get Docker devicemapper device: %v", err)
- }
- if len(dockerDev) > 0 && dockerPartition != nil {
- i.partitions[dockerDev] = *dockerPartition
- i.labels[LabelDockerImages] = dockerDev
- } else {
- i.updateContainerImagesPath(LabelDockerImages, mounts, getDockerImagePaths(context))
+ if context.Docker.Driver != "" {
+ dockerDev, dockerPartition, err := i.getDockerDeviceMapperInfo(context.Docker)
+ if err != nil {
+ klog.Warningf("Could not get Docker devicemapper device: %v", err)
+ }
+ if len(dockerDev) > 0 && dockerPartition != nil {
+ i.partitions[dockerDev] = *dockerPartition
+ i.labels[LabelDockerImages] = dockerDev
+ } else {
+ i.updateContainerImagesPath(LabelDockerImages, mounts, getDockerImagePaths(context))
+ }
}
}
@@ -582,15 +590,20 @@ func (i *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
}
mnt, found := i.mountInfoFromDir(dir)
- if found && mnt.FSType == "btrfs" && mnt.Major == 0 && strings.HasPrefix(mnt.Source, "/dev/") {
- major, minor, err := getBtrfsMajorMinorIds(mnt)
- if err != nil {
- klog.Warningf("%s", err)
- } else {
- return &DeviceInfo{mnt.Source, uint(major), uint(minor)}, nil
+ if found && strings.HasPrefix(mnt.Source, "/dev/") {
+ major, minor := mnt.Major, mnt.Minor
+
+ if mnt.FSType == "btrfs" && major == 0 {
+ major, minor, err = getBtrfsMajorMinorIds(mnt)
+ if err != nil {
+ klog.Warningf("Unable to get btrfs mountpoint IDs: %v", err)
+ }
}
+
+ return &DeviceInfo{mnt.Source, uint(major), uint(minor)}, nil
}
- return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
+
+ return nil, fmt.Errorf("with major: %d, minor: %d: %w", major, minor, ErrDeviceNotInPartitionsMap)
}
func GetDirUsage(dir string) (UsageInfo, error) {
diff --git a/vendor/github.com/google/cadvisor/info/v1/container.go b/vendor/github.com/google/cadvisor/info/v1/container.go
index 9fe04fddea2..e44f50edfb1 100644
--- a/vendor/github.com/google/cadvisor/info/v1/container.go
+++ b/vendor/github.com/google/cadvisor/info/v1/container.go
@@ -963,6 +963,8 @@ type ContainerStats struct {
Resctrl ResctrlStats `json:"resctrl,omitempty"`
CpuSet CPUSetStats `json:"cpuset,omitempty"`
+
+ OOMEvents uint64 `json:"oom_events,omitempty"`
}
func timeEq(t1, t2 time.Time, tolerance time.Duration) bool {
diff --git a/vendor/github.com/google/cadvisor/info/v1/machine.go b/vendor/github.com/google/cadvisor/info/v1/machine.go
index 22c9ff8c29e..108089bc221 100644
--- a/vendor/github.com/google/cadvisor/info/v1/machine.go
+++ b/vendor/github.com/google/cadvisor/info/v1/machine.go
@@ -47,13 +47,16 @@ type Node struct {
}
type Core struct {
- Id int `json:"core_id"`
- Threads []int `json:"thread_ids"`
- Caches []Cache `json:"caches"`
- SocketID int `json:"socket_id"`
+ Id int `json:"core_id"`
+ Threads []int `json:"thread_ids"`
+ Caches []Cache `json:"caches"`
+ UncoreCaches []Cache `json:"uncore_caches"`
+ SocketID int `json:"socket_id"`
}
type Cache struct {
+ // Id of memory cache
+ Id int `json:"id"`
// Size of memory cache in bytes.
Size uint64 `json:"size"`
// Type of memory cache: data, instruction, or unified.
@@ -175,6 +178,9 @@ type MachineInfo struct {
// The time of this information point.
Timestamp time.Time `json:"timestamp"`
+ // Vendor id of CPU.
+ CPUVendorID string `json:"vendor_id"`
+
// The number of cores in this machine.
NumCores int `json:"num_cores"`
@@ -246,6 +252,7 @@ func (m *MachineInfo) Clone() *MachineInfo {
}
}
copy := MachineInfo{
+ CPUVendorID: m.CPUVendorID,
Timestamp: m.Timestamp,
NumCores: m.NumCores,
NumPhysicalCores: m.NumPhysicalCores,
diff --git a/vendor/github.com/google/cadvisor/info/v2/container.go b/vendor/github.com/google/cadvisor/info/v2/container.go
index a80fb5598d6..4ee3b817939 100644
--- a/vendor/github.com/google/cadvisor/info/v2/container.go
+++ b/vendor/github.com/google/cadvisor/info/v2/container.go
@@ -263,7 +263,7 @@ type FsInfo struct {
}
type RequestOptions struct {
- // Type of container identifier specified - "name", "dockerid", dockeralias"
+ // Type of container identifier specified - TypeName (default) or TypeDocker
IdType string `json:"type"`
// Number of stats to return
Count int `json:"count"`
diff --git a/vendor/github.com/google/cadvisor/info/v2/conversion.go b/vendor/github.com/google/cadvisor/info/v2/conversion.go
index f9a95a03501..41da7ea4a90 100644
--- a/vendor/github.com/google/cadvisor/info/v2/conversion.go
+++ b/vendor/github.com/google/cadvisor/info/v2/conversion.go
@@ -18,8 +18,9 @@ import (
"fmt"
"time"
- "github.com/google/cadvisor/info/v1"
"k8s.io/klog/v2"
+
+ v1 "github.com/google/cadvisor/info/v1"
)
func machineFsStatsFromV1(fsStats []v1.FsStats) []MachineFsStats {
diff --git a/vendor/github.com/google/cadvisor/info/v2/machine.go b/vendor/github.com/google/cadvisor/info/v2/machine.go
index c33ec691d37..fa6f38c0ed0 100644
--- a/vendor/github.com/google/cadvisor/info/v2/machine.go
+++ b/vendor/github.com/google/cadvisor/info/v2/machine.go
@@ -18,7 +18,7 @@ import (
// TODO(rjnagal): Move structs from v1.
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
)
type Attributes struct {
diff --git a/vendor/github.com/google/cadvisor/machine/info.go b/vendor/github.com/google/cadvisor/machine/info.go
index 8db8a7e76d9..0550a5fa299 100644
--- a/vendor/github.com/google/cadvisor/machine/info.go
+++ b/vendor/github.com/google/cadvisor/machine/info.go
@@ -121,6 +121,7 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
machineInfo := &info.MachineInfo{
Timestamp: time.Now(),
+ CPUVendorID: GetCPUVendorID(cpuinfo),
NumCores: numCores,
NumPhysicalCores: GetPhysicalCores(cpuinfo),
NumSockets: GetSockets(cpuinfo),
diff --git a/vendor/github.com/google/cadvisor/machine/machine.go b/vendor/github.com/google/cadvisor/machine/machine.go
index 706bba63782..41bff7cdfe7 100644
--- a/vendor/github.com/google/cadvisor/machine/machine.go
+++ b/vendor/github.com/google/cadvisor/machine/machine.go
@@ -21,6 +21,7 @@ import (
"os"
"path"
"regexp"
+
// s390/s390x changes
"runtime"
"strconv"
@@ -43,6 +44,7 @@ var (
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|CPU MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
swapCapacityRegexp = regexp.MustCompile(`SwapTotal:\s*([0-9]+) kB`)
+ vendorIDRegexp = regexp.MustCompile(`vendor_id\s*:\s*(\w+)`)
cpuBusPath = "/sys/bus/cpu/devices/"
isMemoryController = regexp.MustCompile("mc[0-9]+")
@@ -54,6 +56,21 @@ var (
const memTypeFileName = "dimm_mem_type"
const sizeFileName = "size"
+// GetCPUVendorID returns "vendor_id" reading /proc/cpuinfo file.
+func GetCPUVendorID(procInfo []byte) string {
+ vendorID := ""
+
+ matches := vendorIDRegexp.FindSubmatch(procInfo)
+ if len(matches) != 2 {
+ klog.Warning("Cannot read vendor id correctly, set empty.")
+ return vendorID
+ }
+
+ vendorID = string(matches[1])
+
+ return vendorID
+}
+
// GetPhysicalCores returns number of CPU cores reading /proc/cpuinfo file or if needed information from sysfs cpu path
func GetPhysicalCores(procInfo []byte) int {
numCores := getUniqueMatchesCount(string(procInfo), coreRegExp)
diff --git a/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go b/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
index 106c47e128c..37a4cc53611 100644
--- a/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
+++ b/vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+//go:build freebsd || darwin || linux
// +build freebsd darwin linux
package machine
diff --git a/vendor/github.com/google/cadvisor/manager/container.go b/vendor/github.com/google/cadvisor/manager/container.go
index c776e10d640..db2e2b113b1 100644
--- a/vendor/github.com/google/cadvisor/manager/container.go
+++ b/vendor/github.com/google/cadvisor/manager/container.go
@@ -27,6 +27,7 @@ import (
"strconv"
"strings"
"sync"
+ "sync/atomic"
"time"
"github.com/google/cadvisor/cache/memory"
@@ -102,6 +103,8 @@ type containerData struct {
// resctrlCollector updates stats for resctrl controller.
resctrlCollector stats.Collector
+
+ oomEvents uint64
}
// jitter returns a time.Duration between duration and duration + maxFactor * duration,
@@ -127,6 +130,7 @@ func (cd *containerData) Stop() error {
}
close(cd.stop)
cd.perfCollector.Destroy()
+ cd.resctrlCollector.Destroy()
return nil
}
@@ -668,6 +672,9 @@ func (cd *containerData) updateStats() error {
klog.V(2).Infof("Failed to add summary stats for %q: %v", cd.info.Name, err)
}
}
+
+ stats.OOMEvents = atomic.LoadUint64(&cd.oomEvents)
+
var customStatsErr error
cm := cd.collectorManager.(*collector.GenericCollectorManager)
if len(cm.Collectors) > 0 {
@@ -721,7 +728,7 @@ func (cd *containerData) updateStats() error {
return perfStatsErr
}
if resctrlStatsErr != nil {
- klog.Errorf("error occurred while collecting resctrl stats for container %s: %s", cInfo.Name, err)
+ klog.Errorf("error occurred while collecting resctrl stats for container %s: %s", cInfo.Name, resctrlStatsErr)
return resctrlStatsErr
}
return customStatsErr
diff --git a/vendor/github.com/google/cadvisor/manager/manager.go b/vendor/github.com/google/cadvisor/manager/manager.go
index cf6a8a1a100..ca55537c5be 100644
--- a/vendor/github.com/google/cadvisor/manager/manager.go
+++ b/vendor/github.com/google/cadvisor/manager/manager.go
@@ -24,18 +24,18 @@ import (
"strconv"
"strings"
"sync"
+ "sync/atomic"
"time"
"github.com/google/cadvisor/accelerators"
"github.com/google/cadvisor/cache/memory"
"github.com/google/cadvisor/collector"
"github.com/google/cadvisor/container"
- "github.com/google/cadvisor/container/docker"
"github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/events"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/info/v2"
+ v2 "github.com/google/cadvisor/info/v2"
"github.com/google/cadvisor/machine"
"github.com/google/cadvisor/nvm"
"github.com/google/cadvisor/perf"
@@ -47,8 +47,6 @@ import (
"github.com/google/cadvisor/watcher"
"github.com/opencontainers/runc/libcontainer/cgroups"
- "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
"k8s.io/klog/v2"
"k8s.io/utils/clock"
@@ -61,6 +59,14 @@ var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h",
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
var applicationMetricsCountLimit = flag.Int("application_metrics_count_limit", 100, "Max number of application metrics to store (per container)")
+// The namespace under which Docker aliases are unique.
+const DockerNamespace = "docker"
+
+var HousekeepingConfigFlags = HouskeepingConfig{
+ flag.Duration("max_housekeeping_interval", 60*time.Second, "Largest interval to allow between container housekeepings"),
+ flag.Bool("allow_dynamic_housekeeping", true, "Whether to allow the housekeeping interval to be dynamic"),
+}
+
// The Manager interface defines operations for starting a manager and getting
// container and machine information.
type Manager interface {
@@ -129,12 +135,6 @@ type Manager interface {
CloseEventChannel(watchID int)
- // Get status information about docker.
- DockerInfo() (info.DockerStatus, error)
-
- // Get details about interesting docker images.
- DockerImages() ([]info.DockerImage, error)
-
// Returns debugging information. Map of lines per category.
DebugInfo() map[string][]string
}
@@ -146,7 +146,7 @@ type HouskeepingConfig = struct {
}
// New takes a memory storage and returns a new manager.
-func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig HouskeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string, perfEventsFile string) (Manager, error) {
+func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig HouskeepingConfig, includedMetricsSet container.MetricSet, collectorHTTPClient *http.Client, rawContainerCgroupPathPrefixWhiteList, containerEnvMetadataWhiteList []string, perfEventsFile string, resctrlInterval time.Duration) (Manager, error) {
if memoryCache == nil {
return nil, fmt.Errorf("manager requires memory storage")
}
@@ -203,6 +203,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig
collectorHTTPClient: collectorHTTPClient,
nvidiaManager: accelerators.NewNvidiaManager(includedMetricsSet),
rawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,
+ containerEnvMetadataWhiteList: containerEnvMetadataWhiteList,
}
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
@@ -217,7 +218,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, houskeepingConfig
return nil, err
}
- newManager.resctrlManager, err = resctrl.NewManager(selfContainer)
+ newManager.resctrlManager, err = resctrl.NewManager(resctrlInterval, resctrl.Setup, machineInfo.CPUVendorID, inHostNamespace)
if err != nil {
klog.V(4).Infof("Cannot gather resctrl metrics: %v", err)
}
@@ -262,9 +263,11 @@ type manager struct {
collectorHTTPClient *http.Client
nvidiaManager stats.Manager
perfManager stats.Manager
- resctrlManager stats.Manager
+ resctrlManager resctrl.Manager
// List of raw container cgroup path prefix whitelist.
rawContainerCgroupPathPrefixWhiteList []string
+ // List of container env prefix whitelist, the matched container envs would be collected into metrics as extra labels.
+ containerEnvMetadataWhiteList []string
}
// Start the container manager.
@@ -327,7 +330,7 @@ func (m *manager) Start() error {
func (m *manager) Stop() error {
defer m.nvidiaManager.Destroy()
- defer m.destroyPerfCollectors()
+ defer m.destroyCollectors()
// Stop and wait on all quit channels.
for i, c := range m.quitChannels {
// Send the exit signal and wait on the thread to exit (by closing the channel).
@@ -345,9 +348,10 @@ func (m *manager) Stop() error {
return nil
}
-func (m *manager) destroyPerfCollectors() {
+func (m *manager) destroyCollectors() {
for _, container := range m.containers {
container.perfCollector.Destroy()
+ container.resctrlCollector.Destroy()
}
}
@@ -590,7 +594,7 @@ func (m *manager) getAllDockerContainers() map[string]*containerData {
// Get containers in the Docker namespace.
for name, cont := range m.containers {
- if name.Namespace == docker.DockerNamespace {
+ if name.Namespace == DockerNamespace {
containers[cont.info.Name] = cont
}
}
@@ -622,14 +626,14 @@ func (m *manager) getDockerContainer(containerName string) (*containerData, erro
// Check for the container in the Docker container namespace.
cont, ok := m.containers[namespacedContainerName{
- Namespace: docker.DockerNamespace,
+ Namespace: DockerNamespace,
Name: containerName,
}]
// Look for container by short prefix name if no exact match found.
if !ok {
for contName, c := range m.containers {
- if contName.Namespace == docker.DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
+ if contName.Namespace == DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
if cont == nil {
cont = c
} else {
@@ -692,6 +696,10 @@ func (m *manager) GetRequestedContainersInfo(containerName string, options v2.Re
for name, data := range containers {
info, err := m.containerDataToContainerInfo(data, &query)
if err != nil {
+ if err == memory.ErrDataNotFound {
+ klog.Warningf("Error getting data for container %s because of race condition", name)
+ continue
+ }
errs.append(name, "containerDataToContainerInfo", err)
}
containersMap[name] = info
@@ -908,7 +916,7 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
return nil
}
- handler, accept, err := container.NewContainerHandler(containerName, watchSource, m.inHostNamespace)
+ handler, accept, err := container.NewContainerHandler(containerName, watchSource, m.containerEnvMetadataWhiteList, m.inHostNamespace)
if err != nil {
return err
}
@@ -928,13 +936,7 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
return err
}
- if cgroups.IsCgroup2UnifiedMode() {
- perfCgroupPath := path.Join(fs2.UnifiedMountpoint, containerName)
- cont.perfCollector, err = m.perfManager.GetCollector(perfCgroupPath)
- if err != nil {
- klog.Errorf("Perf event metrics will not be available for container %q: %v", containerName, err)
- }
- } else {
+ if !cgroups.IsCgroup2UnifiedMode() {
devicesCgroupPath, err := handler.GetCgroupPath("devices")
if err != nil {
klog.Warningf("Error getting devices cgroup path: %v", err)
@@ -944,6 +946,8 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
klog.V(4).Infof("GPU metrics may be unavailable/incomplete for container %s: %s", cont.info.Name, err)
}
}
+ }
+ if m.includedMetrics.Has(container.PerfMetrics) {
perfCgroupPath, err := handler.GetCgroupPath("perf_event")
if err != nil {
klog.Warningf("Error getting perf_event cgroup path: %q", err)
@@ -956,14 +960,11 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
}
if m.includedMetrics.Has(container.ResctrlMetrics) {
- resctrlPath, err := intelrdt.GetIntelRdtPath(containerName)
+ cont.resctrlCollector, err = m.resctrlManager.GetCollector(containerName, func() ([]string, error) {
+ return cont.getContainerPids(m.inHostNamespace)
+ }, len(m.machineInfo.Topology))
if err != nil {
- klog.V(4).Infof("Error getting resctrl path: %q", err)
- } else {
- cont.resctrlCollector, err = m.resctrlManager.GetCollector(resctrlPath)
- if err != nil {
- klog.V(4).Infof("resctrl metrics will not be available for container %s: %s", cont.info.Name, err)
- }
+ klog.V(4).Infof("resctrl metrics will not be available for container %s: %s", cont.info.Name, err)
}
}
@@ -1005,7 +1006,6 @@ func (m *manager) createContainerLocked(containerName string, watchSource watche
if err != nil {
return err
}
-
// Start the container's housekeeping.
return cont.Start()
}
@@ -1237,6 +1237,24 @@ func (m *manager) watchForNewOoms() error {
if err != nil {
klog.Errorf("failed to add OOM kill event for %q: %v", oomInstance.ContainerName, err)
}
+
+ // Count OOM events for later collection by prometheus
+ request := v2.RequestOptions{
+ IdType: v2.TypeName,
+ Count: 1,
+ }
+ conts, err := m.getRequestedContainers(oomInstance.ContainerName, request)
+ if err != nil {
+ klog.V(2).Infof("failed getting container info for %q: %v", oomInstance.ContainerName, err)
+ continue
+ }
+ if len(conts) != 1 {
+ klog.V(2).Info("Expected the request to match only one container")
+ continue
+ }
+ for _, cont := range conts {
+ atomic.AddUint64(&cont.oomEvents, 1)
+ }
}
}()
return nil
@@ -1304,14 +1322,6 @@ func parseEventsStoragePolicy() events.StoragePolicy {
return policy
}
-func (m *manager) DockerImages() ([]info.DockerImage, error) {
- return docker.Images()
-}
-
-func (m *manager) DockerInfo() (info.DockerStatus, error) {
- return docker.Status()
-}
-
func (m *manager) DebugInfo() map[string][]string {
debugInfo := container.DebugInfo()
@@ -1368,20 +1378,10 @@ func getVersionInfo() (*info.VersionInfo, error) {
kernelVersion := machine.KernelVersion()
osVersion := machine.ContainerOsVersion()
- dockerVersion, err := docker.VersionString()
- if err != nil {
- return nil, err
- }
- dockerAPIVersion, err := docker.APIVersionString()
- if err != nil {
- return nil, err
- }
return &info.VersionInfo{
KernelVersion: kernelVersion,
ContainerOsVersion: osVersion,
- DockerVersion: dockerVersion,
- DockerAPIVersion: dockerAPIVersion,
CadvisorVersion: version.Info["version"],
CadvisorRevision: version.Info["revision"],
}, nil
diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus.go b/vendor/github.com/google/cadvisor/metrics/prometheus.go
index 7d3f24a99da..04c8d27e8f7 100644
--- a/vendor/github.com/google/cadvisor/metrics/prometheus.go
+++ b/vendor/github.com/google/cadvisor/metrics/prometheus.go
@@ -1757,6 +1757,17 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc, includedMetri
},
}...)
}
+ if includedMetrics.Has(container.OOMMetrics) {
+ c.containerMetrics = append(c.containerMetrics, containerMetric{
+ name: "container_oom_events_total",
+ help: "Count of out of memory events observed for the container",
+ valueType: prometheus.CounterValue,
+ getValues: func(s *info.ContainerStats) metricValues {
+ return metricValues{{value: float64(s.OOMEvents), timestamp: s.Timestamp}}
+ },
+ })
+ }
+
return c
}
@@ -1825,7 +1836,7 @@ func DefaultContainerLabels(container *info.ContainerInfo) map[string]string {
}
// BaseContainerLabels returns a ContainerLabelsFunc that exports the container
-// name, first alias, image name as well as white listed label values.
+// name, first alias, image name as well as all its white listed env and label values.
func BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo) map[string]string {
whiteListMap := make(map[string]struct{}, len(whiteList))
for _, k := range whiteList {
@@ -1845,6 +1856,9 @@ func BaseContainerLabels(whiteList []string) func(container *info.ContainerInfo)
set[ContainerLabelPrefix+k] = v
}
}
+ for k, v := range container.Spec.Envs {
+ set[ContainerEnvPrefix+k] = v
+ }
return set
}
}
diff --git a/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go b/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
index 6a9c55ab173..f60cdc2883c 100644
--- a/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
+++ b/vendor/github.com/google/cadvisor/metrics/prometheus_machine.go
@@ -17,9 +17,10 @@ package metrics
import (
"strconv"
+ "github.com/prometheus/client_golang/prometheus"
+
"github.com/google/cadvisor/container"
info "github.com/google/cadvisor/info/v1"
- "github.com/prometheus/client_golang/prometheus"
"k8s.io/klog/v2"
)
@@ -334,6 +335,14 @@ func getCaches(machineInfo *info.MachineInfo) metricValues {
timestamp: machineInfo.Timestamp,
})
}
+ for _, cache := range core.UncoreCaches {
+ mValues = append(mValues,
+ metricValue{
+ value: float64(cache.Size),
+ labels: []string{nodeID, coreID, cache.Type, strconv.Itoa(cache.Level)},
+ timestamp: machineInfo.Timestamp,
+ })
+ }
}
for _, cache := range node.Caches {
diff --git a/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go b/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
index 9ee57fae246..0332a2c5994 100644
--- a/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
+++ b/vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go
@@ -1,3 +1,4 @@
+//go:build libipmctl && cgo
// +build libipmctl,cgo
// Copyright 2020 Google Inc. All Rights Reserved.
@@ -21,9 +22,10 @@ package nvm
import "C"
import (
"fmt"
- info "github.com/google/cadvisor/info/v1"
"sync"
+ info "github.com/google/cadvisor/info/v1"
+
"k8s.io/klog/v2"
)
diff --git a/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go b/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go
index 21311f8a7f7..886dd1bf44d 100644
--- a/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go
+++ b/vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go
@@ -1,3 +1,4 @@
+//go:build !libipmctl || !cgo
// +build !libipmctl !cgo
// Copyright 2020 Google Inc. All Rights Reserved.
@@ -17,8 +18,9 @@
package nvm
import (
- info "github.com/google/cadvisor/info/v1"
"k8s.io/klog/v2"
+
+ info "github.com/google/cadvisor/info/v1"
)
// GetInfo returns information specific for non-volatile memory modules.
diff --git a/vendor/github.com/google/cadvisor/perf/collector_libpfm.go b/vendor/github.com/google/cadvisor/perf/collector_libpfm.go
index cbc646ba108..cd7bc632f2d 100644
--- a/vendor/github.com/google/cadvisor/perf/collector_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/collector_libpfm.go
@@ -1,3 +1,4 @@
+//go:build libpfm && cgo
// +build libpfm,cgo
// Copyright 2020 Google Inc. All Rights Reserved.
@@ -47,6 +48,10 @@ type collector struct {
onlineCPUs []int
eventToCustomEvent map[Event]*CustomEvent
uncore stats.Collector
+
+ // Handle for mocking purposes.
+ perfEventOpen func(attr *unix.PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
+ ioctlSetInt func(fd int, req uint, value int) error
}
type group struct {
@@ -76,7 +81,7 @@ func init() {
}
func newCollector(cgroupPath string, events PerfEvents, onlineCPUs []int, cpuToSocket map[int]int) *collector {
- collector := &collector{cgroupPath: cgroupPath, events: events, onlineCPUs: onlineCPUs, cpuFiles: map[int]group{}, uncore: NewUncoreCollector(cgroupPath, events, cpuToSocket)}
+ collector := &collector{cgroupPath: cgroupPath, events: events, onlineCPUs: onlineCPUs, cpuFiles: map[int]group{}, uncore: NewUncoreCollector(cgroupPath, events, cpuToSocket), perfEventOpen: unix.PerfEventOpen, ioctlSetInt: unix.IoctlSetInt}
mapEventsToCustomEvents(collector)
return collector
}
@@ -185,44 +190,30 @@ func (c *collector) setup() error {
c.cpuFilesLock.Lock()
defer c.cpuFilesLock.Unlock()
cgroupFd := int(cgroup.Fd())
- for i, group := range c.events.Core.Events {
+ groupIndex := 0
+ for _, group := range c.events.Core.Events {
// CPUs file descriptors of group leader needed for perf_event_open.
leaderFileDescriptors := make(map[int]int, len(c.onlineCPUs))
for _, cpu := range c.onlineCPUs {
leaderFileDescriptors[cpu] = groupLeaderFileDescriptor
}
- for j, event := range group.events {
- // First element is group leader.
- isGroupLeader := j == 0
- customEvent, ok := c.eventToCustomEvent[event]
- if ok {
- config := c.createConfigFromRawEvent(customEvent)
- leaderFileDescriptors, err = c.registerEvent(eventInfo{string(customEvent.Name), config, cgroupFd, i, isGroupLeader}, leaderFileDescriptors)
- if err != nil {
- return err
- }
- } else {
- config, err := c.createConfigFromEvent(event)
- if err != nil {
- return err
- }
- leaderFileDescriptors, err = c.registerEvent(eventInfo{string(event), config, cgroupFd, i, isGroupLeader}, leaderFileDescriptors)
- if err != nil {
- return err
- }
- // Clean memory allocated by C code.
- C.free(unsafe.Pointer(config))
- }
+ leaderFileDescriptors, err := c.createLeaderFileDescriptors(group.events, cgroupFd, groupIndex, leaderFileDescriptors)
+ if err != nil {
+ klog.Errorf("Cannot count perf event group %v: %v", group.events, err)
+ c.deleteGroup(groupIndex)
+ continue
+ } else {
+ groupIndex++
}
// Group is prepared so we should reset and enable counting.
for _, fd := range leaderFileDescriptors {
- err = unix.IoctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)
+ err = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_RESET, 0)
if err != nil {
return err
}
- err = unix.IoctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)
+ err = c.ioctlSetInt(fd, unix.PERF_EVENT_IOC_ENABLE, 0)
if err != nil {
return err
}
@@ -232,6 +223,35 @@ func (c *collector) setup() error {
return nil
}
+func (c *collector) createLeaderFileDescriptors(events []Event, cgroupFd int, groupIndex int, leaderFileDescriptors map[int]int) (map[int]int, error) {
+ for j, event := range events {
+ // First element is group leader.
+ isGroupLeader := j == 0
+ customEvent, ok := c.eventToCustomEvent[event]
+ var err error
+ if ok {
+ config := c.createConfigFromRawEvent(customEvent)
+ leaderFileDescriptors, err = c.registerEvent(eventInfo{string(customEvent.Name), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)
+ if err != nil {
+ return nil, fmt.Errorf("cannot register perf event: %v", err)
+ }
+ } else {
+ config, err := c.createConfigFromEvent(event)
+ if err != nil {
+ return nil, fmt.Errorf("cannot create config from perf event: %v", err)
+
+ }
+ leaderFileDescriptors, err = c.registerEvent(eventInfo{string(event), config, cgroupFd, groupIndex, isGroupLeader}, leaderFileDescriptors)
+ if err != nil {
+ return nil, fmt.Errorf("cannot register perf event: %v", err)
+ }
+ // Clean memory allocated by C code.
+ C.free(unsafe.Pointer(config))
+ }
+ }
+ return leaderFileDescriptors, nil
+}
+
func readPerfEventAttr(name string, pfmGetOsEventEncoding func(string, unsafe.Pointer) error) (*unix.PerfEventAttr, error) {
perfEventAttrMemory := C.malloc(C.ulong(unsafe.Sizeof(unix.PerfEventAttr{})))
// Fill memory with 0 values.
@@ -279,13 +299,13 @@ func (c *collector) registerEvent(event eventInfo, leaderFileDescriptors map[int
setAttributes(event.config, event.isGroupLeader)
for _, cpu := range c.onlineCPUs {
- fd, err := unix.PerfEventOpen(event.config, pid, cpu, leaderFileDescriptors[cpu], flags)
+ fd, err := c.perfEventOpen(event.config, pid, cpu, leaderFileDescriptors[cpu], flags)
if err != nil {
- return nil, fmt.Errorf("setting up perf event %#v failed: %q", event.config, err)
+ return leaderFileDescriptors, fmt.Errorf("setting up perf event %#v failed: %q", event.config, err)
}
perfFile := os.NewFile(uintptr(fd), event.name)
if perfFile == nil {
- return nil, fmt.Errorf("unable to create os.File from file descriptor %#v", fd)
+ return leaderFileDescriptors, fmt.Errorf("unable to create os.File from file descriptor %#v", fd)
}
c.addEventFile(event.groupIndex, event.name, cpu, perfFile)
@@ -333,6 +353,19 @@ func (c *collector) addEventFile(index int, name string, cpu int, perfFile *os.F
}
}
+func (c *collector) deleteGroup(index int) {
+ for name, files := range c.cpuFiles[index].cpuFiles {
+ for cpu, file := range files {
+ klog.V(5).Infof("Closing perf event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
+ err := file.Close()
+ if err != nil {
+ klog.Warningf("Unable to close perf event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
+ }
+ }
+ }
+ delete(c.cpuFiles, index)
+}
+
func createPerfEventAttr(event CustomEvent) *unix.PerfEventAttr {
length := len(event.Config)
@@ -369,17 +402,8 @@ func (c *collector) Destroy() {
c.cpuFilesLock.Lock()
defer c.cpuFilesLock.Unlock()
- for _, group := range c.cpuFiles {
- for name, files := range group.cpuFiles {
- for cpu, file := range files {
- klog.V(5).Infof("Closing perf_event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
- err := file.Close()
- if err != nil {
- klog.Warningf("Unable to close perf_event file descriptor for cgroup %q, event %q and CPU %d", c.cgroupPath, name, cpu)
- }
- }
- delete(group.cpuFiles, name)
- }
+ for i := range c.cpuFiles {
+ c.deleteGroup(i)
}
}
diff --git a/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go b/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go
index 18a69d537b4..57c1a20595c 100644
--- a/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go
@@ -1,3 +1,4 @@
+//go:build !libpfm || !cgo
// +build !libpfm !cgo
// Copyright 2020 Google Inc. All Rights Reserved.
diff --git a/vendor/github.com/google/cadvisor/perf/manager_libpfm.go b/vendor/github.com/google/cadvisor/perf/manager_libpfm.go
index d4126d659b1..9be47e372c8 100644
--- a/vendor/github.com/google/cadvisor/perf/manager_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/manager_libpfm.go
@@ -1,3 +1,4 @@
+//go:build libpfm && cgo
// +build libpfm,cgo
// Copyright 2020 Google Inc. All Rights Reserved.
@@ -48,6 +49,10 @@ func NewManager(configFile string, topology []info.Node) (stats.Manager, error)
return nil, fmt.Errorf("unable to parse configuration file %q: %w", configFile, err)
}
+ if len(config.Core.Events) == 0 && len(config.Uncore.Events) == 0 {
+ return nil, fmt.Errorf("there is no events in config file %q", configFile)
+ }
+
onlineCPUs := sysinfo.GetOnlineCPUs(topology)
cpuToSocket := make(map[int]int)
diff --git a/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go b/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go
index d0fc4e78a12..135d778eea3 100644
--- a/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go
@@ -1,3 +1,4 @@
+//go:build !libpfm || !cgo
// +build !libpfm !cgo
// Copyright 2020 Google Inc. All Rights Reserved.
diff --git a/vendor/github.com/google/cadvisor/perf/types_libpfm.go b/vendor/github.com/google/cadvisor/perf/types_libpfm.go
index 1ca2136137b..89cf7be10b8 100644
--- a/vendor/github.com/google/cadvisor/perf/types_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/types_libpfm.go
@@ -1,3 +1,4 @@
+//go:build libpfm && cgo
// +build libpfm,cgo
// Copyright 2020 Google Inc. All Rights Reserved.
diff --git a/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go b/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
index fdd35a34b6a..0ef6248c79f 100644
--- a/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
+++ b/vendor/github.com/google/cadvisor/perf/uncore_libpfm.go
@@ -1,3 +1,4 @@
+//go:build libpfm && cgo
// +build libpfm,cgo
// Copyright 2020 Google Inc. All Rights Reserved.
@@ -158,6 +159,28 @@ func NewUncoreCollector(cgroupPath string, events PerfEvents, cpuToSocket map[in
return collector
}
+func (c *uncoreCollector) createLeaderFileDescriptors(events []Event, groupIndex int, groupPMUs map[Event]uncorePMUs,
+ leaderFileDescriptors map[string]map[uint32]int) (map[string]map[uint32]int, error) {
+ var err error
+ for _, event := range events {
+ eventName, _ := parseEventName(string(event))
+ customEvent, ok := c.eventToCustomEvent[event]
+ if ok {
+ err = c.setupRawEvent(customEvent, groupPMUs[event], groupIndex, leaderFileDescriptors)
+ } else {
+ err = c.setupEvent(eventName, groupPMUs[event], groupIndex, leaderFileDescriptors)
+ }
+ if err != nil {
+ break
+ }
+ }
+ if err != nil {
+ c.deleteGroup(groupIndex)
+ return nil, fmt.Errorf("cannot create config from perf event: %v", err)
+ }
+ return leaderFileDescriptors, nil
+}
+
func (c *uncoreCollector) setup(events PerfEvents, devicesPath string) error {
readUncorePMUs, err := getUncorePMUs(devicesPath)
if err != nil {
@@ -190,21 +213,11 @@ func (c *uncoreCollector) setup(events PerfEvents, devicesPath string) error {
leaderFileDescriptors[pmu.name][cpu] = groupLeaderFileDescriptor
}
}
-
- for _, event := range group.events {
- eventName, _ := parseEventName(string(event))
- customEvent, ok := c.eventToCustomEvent[event]
- if ok {
- err = c.setupRawEvent(customEvent, groupPMUs[event], i, leaderFileDescriptors)
- } else {
- err = c.setupEvent(eventName, groupPMUs[event], i, leaderFileDescriptors)
- }
-
- if err != nil {
- return err
- }
+ leaderFileDescriptors, err = c.createLeaderFileDescriptors(group.events, i, groupPMUs, leaderFileDescriptors)
+ if err != nil {
+ klog.Error(err)
+ continue
}
-
// Group is prepared so we should reset and enable counting.
for _, pmuCPUs := range leaderFileDescriptors {
for _, fd := range pmuCPUs {
@@ -320,20 +333,8 @@ func (c *uncoreCollector) Destroy() {
c.cpuFilesLock.Lock()
defer c.cpuFilesLock.Unlock()
- for groupIndex, groupPMUs := range c.cpuFiles {
- for pmu, group := range groupPMUs {
- for name, cpus := range group.cpuFiles {
- for cpu, file := range cpus {
- klog.V(5).Infof("Closing uncore perf_event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
- err := file.Close()
- if err != nil {
- klog.Warningf("Unable to close perf_event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
- }
- }
- delete(group.cpuFiles, name)
- }
- delete(groupPMUs, pmu)
- }
+ for groupIndex := range c.cpuFiles {
+ c.deleteGroup(groupIndex)
delete(c.cpuFiles, groupIndex)
}
}
@@ -475,6 +476,24 @@ func (c *uncoreCollector) setupRawEvent(event *CustomEvent, pmus uncorePMUs, gro
return nil
}
+func (c *uncoreCollector) deleteGroup(groupIndex int) {
+ groupPMUs := c.cpuFiles[groupIndex]
+ for pmu, group := range groupPMUs {
+ for name, cpus := range group.cpuFiles {
+ for cpu, file := range cpus {
+ klog.V(5).Infof("Closing uncore perf event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
+ err := file.Close()
+ if err != nil {
+ klog.Warningf("Unable to close perf event file descriptor for event %q, PMU %s and CPU %d", name, pmu, cpu)
+ }
+ }
+ delete(group.cpuFiles, name)
+ }
+ delete(groupPMUs, pmu)
+ }
+ delete(c.cpuFiles, groupIndex)
+}
+
func readPerfUncoreStat(file readerCloser, group group, cpu int, pmu string, cpuToSocket map[int]int) ([]info.PerfUncoreStat, error) {
values, err := getPerfValues(file, group)
if err != nil {
diff --git a/vendor/github.com/google/cadvisor/resctrl/collector.go b/vendor/github.com/google/cadvisor/resctrl/collector.go
index f677b8d0441..e5e71a7e48c 100644
--- a/vendor/github.com/google/cadvisor/resctrl/collector.go
+++ b/vendor/github.com/google/cadvisor/resctrl/collector.go
@@ -1,6 +1,7 @@
+//go:build linux
// +build linux
-// Copyright 2020 Google Inc. All Rights Reserved.
+// Copyright 2021 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,57 +19,153 @@
package resctrl
import (
- info "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/stats"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/intelrdt"
+ "k8s.io/klog/v2"
+
+ info "github.com/google/cadvisor/info/v1"
)
+const noInterval = 0
+
type collector struct {
- resctrl intelrdt.Manager
- stats.NoopDestroy
+ id string
+ interval time.Duration
+ getContainerPids func() ([]string, error)
+ resctrlPath string
+ running bool
+ destroyed bool
+ numberOfNUMANodes int
+ vendorID string
+ mu sync.Mutex
+ inHostNamespace bool
}
-func newCollector(id string, resctrlPath string) *collector {
- collector := &collector{
- resctrl: intelrdt.NewManager(
- &configs.Config{
- IntelRdt: &configs.IntelRdt{},
- },
- id,
- resctrlPath,
- ),
- }
-
- return collector
+func newCollector(id string, getContainerPids func() ([]string, error), interval time.Duration, numberOfNUMANodes int, vendorID string, inHostNamespace bool) *collector {
+ return &collector{id: id, interval: interval, getContainerPids: getContainerPids, numberOfNUMANodes: numberOfNUMANodes,
+ vendorID: vendorID, mu: sync.Mutex{}, inHostNamespace: inHostNamespace}
}
-func (c *collector) UpdateStats(stats *info.ContainerStats) error {
- stats.Resctrl = info.ResctrlStats{}
+func (c *collector) setup() error {
+ var err error
+ c.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
- resctrlStats, err := c.resctrl.GetStats()
- if err != nil {
- return err
- }
-
- numberOfNUMANodes := len(*resctrlStats.MBMStats)
-
- stats.Resctrl.MemoryBandwidth = make([]info.MemoryBandwidthStats, 0, numberOfNUMANodes)
- stats.Resctrl.Cache = make([]info.CacheStats, 0, numberOfNUMANodes)
-
- for _, numaNodeStats := range *resctrlStats.MBMStats {
- stats.Resctrl.MemoryBandwidth = append(stats.Resctrl.MemoryBandwidth,
- info.MemoryBandwidthStats{
- TotalBytes: numaNodeStats.MBMTotalBytes,
- LocalBytes: numaNodeStats.MBMLocalBytes,
- })
- }
-
- for _, numaNodeStats := range *resctrlStats.CMTStats {
- stats.Resctrl.Cache = append(stats.Resctrl.Cache,
- info.CacheStats{LLCOccupancy: numaNodeStats.LLCOccupancy})
+ if c.interval != noInterval {
+ if err != nil {
+ klog.Errorf("Failed to setup container %q resctrl collector: %s \n Trying again in next intervals.", c.id, err)
+ } else {
+ c.running = true
+ }
+ go func() {
+ for {
+ time.Sleep(c.interval)
+ c.mu.Lock()
+ if c.destroyed {
+ break
+ }
+ klog.V(5).Infof("Trying to check %q containers control group.", c.id)
+ if c.running {
+ err = c.checkMonitoringGroup()
+ if err != nil {
+ c.running = false
+ klog.Errorf("Failed to check %q resctrl collector control group: %s \n Trying again in next intervals.", c.id, err)
+ }
+ } else {
+ c.resctrlPath, err = prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
+ if err != nil {
+ c.running = false
+ klog.Errorf("Failed to setup container %q resctrl collector: %s \n Trying again in next intervals.", c.id, err)
+ }
+ }
+ c.mu.Unlock()
+ }
+ }()
+ } else {
+ // There is no interval set, if setup fail, stop.
+ if err != nil {
+ return fmt.Errorf("failed to setup container %q resctrl collector: %w", c.id, err)
+ }
+ c.running = true
}
return nil
}
+
+func (c *collector) checkMonitoringGroup() error {
+ newPath, err := prepareMonitoringGroup(c.id, c.getContainerPids, c.inHostNamespace)
+ if err != nil {
+ return fmt.Errorf("couldn't obtain mon_group path: %v", err)
+ }
+
+ // Check if container moved between control groups.
+ if newPath != c.resctrlPath {
+ err = c.clear()
+ if err != nil {
+ return fmt.Errorf("couldn't clear previous monitoring group: %w", err)
+ }
+ c.resctrlPath = newPath
+ }
+
+ return nil
+}
+
+func (c *collector) UpdateStats(stats *info.ContainerStats) error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.running {
+ stats.Resctrl = info.ResctrlStats{}
+
+ resctrlStats, err := getIntelRDTStatsFrom(c.resctrlPath, c.vendorID)
+ if err != nil {
+ return err
+ }
+
+ stats.Resctrl.MemoryBandwidth = make([]info.MemoryBandwidthStats, 0, c.numberOfNUMANodes)
+ stats.Resctrl.Cache = make([]info.CacheStats, 0, c.numberOfNUMANodes)
+
+ for _, numaNodeStats := range *resctrlStats.MBMStats {
+ stats.Resctrl.MemoryBandwidth = append(stats.Resctrl.MemoryBandwidth,
+ info.MemoryBandwidthStats{
+ TotalBytes: numaNodeStats.MBMTotalBytes,
+ LocalBytes: numaNodeStats.MBMLocalBytes,
+ })
+ }
+
+ for _, numaNodeStats := range *resctrlStats.CMTStats {
+ stats.Resctrl.Cache = append(stats.Resctrl.Cache,
+ info.CacheStats{LLCOccupancy: numaNodeStats.LLCOccupancy})
+ }
+ }
+
+ return nil
+}
+
+func (c *collector) Destroy() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.running = false
+ err := c.clear()
+ if err != nil {
+ klog.Errorf("trying to destroy %q resctrl collector but: %v", c.id, err)
+ }
+ c.destroyed = true
+}
+
+func (c *collector) clear() error {
+ // Not allowed to remove root or undefined resctrl directory.
+ if c.id != rootContainer && c.resctrlPath != "" {
+ // Remove only own prepared mon group.
+ if strings.HasPrefix(filepath.Base(c.resctrlPath), monGroupPrefix) {
+ err := os.RemoveAll(c.resctrlPath)
+ if err != nil {
+ return fmt.Errorf("couldn't clear mon_group: %v", err)
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/google/cadvisor/resctrl/manager.go b/vendor/github.com/google/cadvisor/resctrl/manager.go
index cceb28e6b6e..672e0c74e07 100644
--- a/vendor/github.com/google/cadvisor/resctrl/manager.go
+++ b/vendor/github.com/google/cadvisor/resctrl/manager.go
@@ -1,6 +1,7 @@
+//go:build linux
// +build linux
-// Copyright 2020 Google Inc. All Rights Reserved.
+// Copyright 2021 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,31 +19,61 @@
package resctrl
import (
- "os"
+ "errors"
+ "time"
+ "k8s.io/klog/v2"
+
+ "github.com/google/cadvisor/container/raw"
"github.com/google/cadvisor/stats"
-
- "github.com/opencontainers/runc/libcontainer/intelrdt"
)
-type manager struct {
- id string
- stats.NoopDestroy
+type Manager interface {
+ Destroy()
+ GetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error)
}
-func (m manager) GetCollector(resctrlPath string) (stats.Collector, error) {
- if _, err := os.Stat(resctrlPath); err != nil {
+type manager struct {
+ stats.NoopDestroy
+ interval time.Duration
+ vendorID string
+ inHostNamespace bool
+}
+
+func (m *manager) GetCollector(containerName string, getContainerPids func() ([]string, error), numberOfNUMANodes int) (stats.Collector, error) {
+ collector := newCollector(containerName, getContainerPids, m.interval, numberOfNUMANodes, m.vendorID, m.inHostNamespace)
+ err := collector.setup()
+ if err != nil {
return &stats.NoopCollector{}, err
}
- collector := newCollector(m.id, resctrlPath)
+
return collector, nil
}
-func NewManager(id string) (stats.Manager, error) {
-
- if intelrdt.IsMBMEnabled() || intelrdt.IsCMTEnabled() {
- return &manager{id: id}, nil
+func NewManager(interval time.Duration, setup func() error, vendorID string, inHostNamespace bool) (Manager, error) {
+ err := setup()
+ if err != nil {
+ return &NoopManager{}, err
}
- return &stats.NoopManager{}, nil
+ if !isResctrlInitialized {
+ return &NoopManager{}, errors.New("the resctrl isn't initialized")
+ }
+ if !(enabledCMT || enabledMBM) {
+ return &NoopManager{}, errors.New("there are no monitoring features available")
+ }
+
+ if !*raw.DockerOnly {
+ klog.Warning("--docker_only should be set when collecting Resctrl metrics! See the runtime docs.")
+ }
+
+ return &manager{interval: interval, vendorID: vendorID, inHostNamespace: inHostNamespace}, nil
+}
+
+type NoopManager struct {
+ stats.NoopDestroy
+}
+
+func (np *NoopManager) GetCollector(_ string, _ func() ([]string, error), _ int) (stats.Collector, error) {
+ return &stats.NoopCollector{}, nil
}
diff --git a/vendor/github.com/google/cadvisor/resctrl/utils.go b/vendor/github.com/google/cadvisor/resctrl/utils.go
new file mode 100644
index 00000000000..f7931d22ebf
--- /dev/null
+++ b/vendor/github.com/google/cadvisor/resctrl/utils.go
@@ -0,0 +1,366 @@
+//go:build linux
+// +build linux
+
+// Copyright 2021 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Utilities.
+package resctrl
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "github.com/opencontainers/runc/libcontainer/cgroups"
+ "github.com/opencontainers/runc/libcontainer/cgroups/fs2"
+ "github.com/opencontainers/runc/libcontainer/intelrdt"
+)
+
+const (
+ cpuCgroup = "cpu"
+ rootContainer = "/"
+ monitoringGroupDir = "mon_groups"
+ processTask = "task"
+ cpusFileName = "cpus"
+ cpusListFileName = "cpus_list"
+ schemataFileName = "schemata"
+ tasksFileName = "tasks"
+ infoDirName = "info"
+ monDataDirName = "mon_data"
+ monGroupsDirName = "mon_groups"
+ noPidsPassedError = "there are no pids passed"
+ noContainerNameError = "there are no container name passed"
+ noControlGroupFoundError = "couldn't find control group matching container"
+ llcOccupancyFileName = "llc_occupancy"
+ mbmLocalBytesFileName = "mbm_local_bytes"
+ mbmTotalBytesFileName = "mbm_total_bytes"
+ containerPrefix = '/'
+ minContainerNameLen = 2 // "/" e.g. "/a"
+ unavailable = "Unavailable"
+ monGroupPrefix = "cadvisor"
+)
+
+var (
+ rootResctrl = ""
+ pidsPath = ""
+ processPath = "/proc"
+ enabledMBM = false
+ enabledCMT = false
+ isResctrlInitialized = false
+ groupDirectories = map[string]struct{}{
+ cpusFileName: {},
+ cpusListFileName: {},
+ infoDirName: {},
+ monDataDirName: {},
+ monGroupsDirName: {},
+ schemataFileName: {},
+ tasksFileName: {},
+ }
+)
+
+func Setup() error {
+ var err error
+ rootResctrl, err = intelrdt.GetIntelRdtPath(rootContainer)
+ if err != nil {
+ return fmt.Errorf("unable to initialize resctrl: %v", err)
+ }
+
+ if cgroups.IsCgroup2UnifiedMode() {
+ pidsPath = fs2.UnifiedMountpoint
+ } else {
+ pidsPath = filepath.Join(fs2.UnifiedMountpoint, cpuCgroup)
+ }
+
+ enabledMBM = intelrdt.IsMBMEnabled()
+ enabledCMT = intelrdt.IsCMTEnabled()
+
+ isResctrlInitialized = true
+
+ return nil
+}
+
+func prepareMonitoringGroup(containerName string, getContainerPids func() ([]string, error), inHostNamespace bool) (string, error) {
+ if containerName == rootContainer {
+ return rootResctrl, nil
+ }
+
+ pids, err := getContainerPids()
+ if err != nil {
+ return "", err
+ }
+
+ if len(pids) == 0 {
+ return "", fmt.Errorf("couldn't obtain %q container pids: there is no pids in cgroup", containerName)
+ }
+
+ // Firstly, find the control group to which the container belongs.
+ // Consider the root group.
+ controlGroupPath, err := findGroup(rootResctrl, pids, true, false)
+ if err != nil {
+ return "", fmt.Errorf("%q %q: %q", noControlGroupFoundError, containerName, err)
+ }
+ if controlGroupPath == "" {
+ return "", fmt.Errorf("%q %q", noControlGroupFoundError, containerName)
+ }
+
+ // Check if there is any monitoring group.
+ monGroupPath, err := findGroup(filepath.Join(controlGroupPath, monGroupsDirName), pids, false, true)
+ if err != nil {
+ return "", fmt.Errorf("couldn't find monitoring group matching %q container: %v", containerName, err)
+ }
+
+ // Prepare new one if not exists.
+ if monGroupPath == "" {
+ // Remove leading prefix.
+ // e.g. /my/container -> my/container
+ if len(containerName) >= minContainerNameLen && containerName[0] == containerPrefix {
+ containerName = containerName[1:]
+ }
+
+ // Add own prefix and use `-` instead `/`.
+ // e.g. my/container -> cadvisor-my-container
+ properContainerName := fmt.Sprintf("%s-%s", monGroupPrefix, strings.Replace(containerName, "/", "-", -1))
+ monGroupPath = filepath.Join(controlGroupPath, monitoringGroupDir, properContainerName)
+
+ err = os.MkdirAll(monGroupPath, os.ModePerm)
+ if err != nil {
+ return "", fmt.Errorf("couldn't create monitoring group directory for %q container: %w", containerName, err)
+ }
+
+ if !inHostNamespace {
+ processPath = "/rootfs/proc"
+ }
+
+ for _, pid := range pids {
+ processThreads, err := getAllProcessThreads(filepath.Join(processPath, pid, processTask))
+ if err != nil {
+ return "", err
+ }
+ for _, thread := range processThreads {
+ err = intelrdt.WriteIntelRdtTasks(monGroupPath, thread)
+ if err != nil {
+ secondError := os.Remove(monGroupPath)
+ if secondError != nil {
+ return "", fmt.Errorf(
+ "coudn't assign pids to %q container monitoring group: %w \n couldn't clear %q monitoring group: %v",
+ containerName, err, containerName, secondError)
+ }
+ return "", fmt.Errorf("coudn't assign pids to %q container monitoring group: %w", containerName, err)
+ }
+ }
+ }
+ }
+
+ return monGroupPath, nil
+}
+
+func getPids(containerName string) ([]int, error) {
+ if len(containerName) == 0 {
+ // No container name passed.
+ return nil, fmt.Errorf(noContainerNameError)
+ }
+ pids, err := cgroups.GetAllPids(filepath.Join(pidsPath, containerName))
+ if err != nil {
+ return nil, fmt.Errorf("couldn't obtain pids for %q container: %v", containerName, err)
+ }
+ return pids, nil
+}
+
+// getAllProcessThreads obtains all available processes from directory.
+// e.g. ls /proc/4215/task/ -> 4215, 4216, 4217, 4218
+// func will return [4215, 4216, 4217, 4218].
+func getAllProcessThreads(path string) ([]int, error) {
+ processThreads := make([]int, 0)
+
+ threadDirs, err := ioutil.ReadDir(path)
+ if err != nil {
+ return processThreads, err
+ }
+
+ for _, dir := range threadDirs {
+ pid, err := strconv.Atoi(dir.Name())
+ if err != nil {
+ return nil, fmt.Errorf("couldn't parse %q dir: %v", dir.Name(), err)
+ }
+ processThreads = append(processThreads, pid)
+ }
+
+ return processThreads, nil
+}
+
+// findGroup returns the path of a control/monitoring group in which the pids are.
+func findGroup(group string, pids []string, includeGroup bool, exclusive bool) (string, error) {
+ if len(pids) == 0 {
+ return "", fmt.Errorf(noPidsPassedError)
+ }
+
+ availablePaths := make([]string, 0)
+ if includeGroup {
+ availablePaths = append(availablePaths, group)
+ }
+
+ files, err := ioutil.ReadDir(group)
+ for _, file := range files {
+ if _, ok := groupDirectories[file.Name()]; !ok {
+ availablePaths = append(availablePaths, filepath.Join(group, file.Name()))
+ }
+ }
+ if err != nil {
+ return "", fmt.Errorf("couldn't obtain groups paths: %w", err)
+ }
+
+ for _, path := range availablePaths {
+ groupFound, err := arePIDsInGroup(path, pids, exclusive)
+ if err != nil {
+ return "", err
+ }
+ if groupFound {
+ return path, nil
+ }
+ }
+
+ return "", nil
+}
+
+// arePIDsInGroup returns true if all of the pids are within control group.
+func arePIDsInGroup(path string, pids []string, exclusive bool) (bool, error) {
+ if len(pids) == 0 {
+ return false, fmt.Errorf("couldn't obtain pids from %q path: %v", path, noPidsPassedError)
+ }
+
+ tasks, err := readTasksFile(filepath.Join(path, tasksFileName))
+ if err != nil {
+ return false, err
+ }
+
+ any := false
+ for _, pid := range pids {
+ _, ok := tasks[pid]
+ if !ok {
+ // There are missing pids within group.
+ if any {
+ return false, fmt.Errorf("there should be all pids in group")
+ }
+ return false, nil
+ }
+ any = true
+ }
+
+ // Check if there should be only passed pids in group.
+ if exclusive {
+ if len(tasks) != len(pids) {
+ return false, fmt.Errorf("group should have container pids only")
+ }
+ }
+
+ return true, nil
+}
+
+// readTasksFile returns pids map from given tasks path.
+func readTasksFile(tasksPath string) (map[string]struct{}, error) {
+ tasks := make(map[string]struct{})
+
+ tasksFile, err := os.Open(tasksPath)
+ if err != nil {
+ return tasks, fmt.Errorf("couldn't read tasks file from %q path: %w", tasksPath, err)
+ }
+ defer tasksFile.Close()
+
+ scanner := bufio.NewScanner(tasksFile)
+ for scanner.Scan() {
+ tasks[scanner.Text()] = struct{}{}
+ }
+
+ if err := scanner.Err(); err != nil {
+ return tasks, fmt.Errorf("couldn't obtain pids from %q path: %w", tasksPath, err)
+ }
+
+ return tasks, nil
+}
+
+func readStatFrom(path string, vendorID string) (uint64, error) {
+ context, err := ioutil.ReadFile(path)
+ if err != nil {
+ return 0, err
+ }
+
+ contextString := string(bytes.TrimSpace(context))
+
+ if contextString == unavailable {
+ err := fmt.Errorf("\"Unavailable\" value from file %q", path)
+ if vendorID == "AuthenticAMD" {
+ kernelBugzillaLink := "https://bugzilla.kernel.org/show_bug.cgi?id=213311"
+ err = fmt.Errorf("%v, possible bug: %q", err, kernelBugzillaLink)
+ }
+ return 0, err
+ }
+
+ stat, err := strconv.ParseUint(contextString, 10, 64)
+ if err != nil {
+ return stat, fmt.Errorf("unable to parse %q as a uint from file %q", string(context), path)
+ }
+
+ return stat, nil
+}
+
+func getIntelRDTStatsFrom(path string, vendorID string) (intelrdt.Stats, error) {
+ stats := intelrdt.Stats{}
+
+ statsDirectories, err := filepath.Glob(filepath.Join(path, monDataDirName, "*"))
+ if err != nil {
+ return stats, err
+ }
+
+ if len(statsDirectories) == 0 {
+ return stats, fmt.Errorf("there is no mon_data stats directories: %q", path)
+ }
+
+ var cmtStats []intelrdt.CMTNumaNodeStats
+ var mbmStats []intelrdt.MBMNumaNodeStats
+
+ for _, dir := range statsDirectories {
+ if enabledCMT {
+ llcOccupancy, err := readStatFrom(filepath.Join(dir, llcOccupancyFileName), vendorID)
+ if err != nil {
+ return stats, err
+ }
+ cmtStats = append(cmtStats, intelrdt.CMTNumaNodeStats{LLCOccupancy: llcOccupancy})
+ }
+ if enabledMBM {
+ mbmTotalBytes, err := readStatFrom(filepath.Join(dir, mbmTotalBytesFileName), vendorID)
+ if err != nil {
+ return stats, err
+ }
+ mbmLocalBytes, err := readStatFrom(filepath.Join(dir, mbmLocalBytesFileName), vendorID)
+ if err != nil {
+ return stats, err
+ }
+ mbmStats = append(mbmStats, intelrdt.MBMNumaNodeStats{
+ MBMTotalBytes: mbmTotalBytes,
+ MBMLocalBytes: mbmLocalBytes,
+ })
+ }
+ }
+
+ stats.CMTStats = &cmtStats
+ stats.MBMStats = &mbmStats
+
+ return stats, nil
+}
diff --git a/vendor/github.com/google/cadvisor/stats/noop.go b/vendor/github.com/google/cadvisor/stats/noop.go
index db129353495..eda7c9f0611 100644
--- a/vendor/github.com/google/cadvisor/stats/noop.go
+++ b/vendor/github.com/google/cadvisor/stats/noop.go
@@ -16,8 +16,9 @@
package stats
import (
- v1 "github.com/google/cadvisor/info/v1"
"k8s.io/klog/v2"
+
+ v1 "github.com/google/cadvisor/info/v1"
)
type NoopManager struct {
diff --git a/vendor/github.com/google/cadvisor/summary/summary.go b/vendor/github.com/google/cadvisor/summary/summary.go
index 089396b74f8..de12f43b3d9 100644
--- a/vendor/github.com/google/cadvisor/summary/summary.go
+++ b/vendor/github.com/google/cadvisor/summary/summary.go
@@ -25,7 +25,7 @@ import (
"sync"
"time"
- "github.com/google/cadvisor/info/v1"
+ v1 "github.com/google/cadvisor/info/v1"
info "github.com/google/cadvisor/info/v2"
)
diff --git a/vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go b/vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
index 3546a80c566..bcb111e571e 100644
--- a/vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
+++ b/vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go
@@ -17,8 +17,9 @@
package cloudinfo
import (
- info "github.com/google/cadvisor/info/v1"
"k8s.io/klog/v2"
+
+ info "github.com/google/cadvisor/info/v1"
)
type CloudInfo interface {
diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go
index 64a044e219a..926c67034a7 100644
--- a/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go
+++ b/vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go
@@ -19,8 +19,9 @@ import (
info "github.com/google/cadvisor/info/v1"
- "github.com/google/cadvisor/utils/cpuload/netlink"
"k8s.io/klog/v2"
+
+ "github.com/google/cadvisor/utils/cpuload/netlink"
)
type CpuLoadReader interface {
diff --git a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go
index 0a73230d5ac..31804768d54 100644
--- a/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go
+++ b/vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go
@@ -21,8 +21,9 @@ import (
"os"
"syscall"
- info "github.com/google/cadvisor/info/v1"
"golang.org/x/sys/unix"
+
+ info "github.com/google/cadvisor/info/v1"
)
var (
diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
index 1be228a0e5f..580ef91eb91 100644
--- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
+++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go
@@ -64,6 +64,8 @@ var (
)
type CacheInfo struct {
+ // cache id
+ Id int
// size in bytes
Size uint64
// cache type - instruction, data, unified
@@ -292,14 +294,24 @@ func getCPUCount(cache string) (count int, err error) {
return
}
-func (fs *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) {
- cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, id, name)
- out, err := ioutil.ReadFile(path.Join(cachePath, "/size"))
+func (fs *realSysFs) GetCacheInfo(cpu int, name string) (CacheInfo, error) {
+ cachePath := fmt.Sprintf("%s%d/cache/%s", cacheDir, cpu, name)
+ out, err := ioutil.ReadFile(path.Join(cachePath, "/id"))
+ if err != nil {
+ return CacheInfo{}, err
+ }
+ var id int
+ n, err := fmt.Sscanf(string(out), "%d", &id)
+ if err != nil || n != 1 {
+ return CacheInfo{}, err
+ }
+
+ out, err = ioutil.ReadFile(path.Join(cachePath, "/size"))
if err != nil {
return CacheInfo{}, err
}
var size uint64
- n, err := fmt.Sscanf(string(out), "%dK", &size)
+ n, err = fmt.Sscanf(string(out), "%dK", &size)
if err != nil || n != 1 {
return CacheInfo{}, err
}
@@ -325,6 +337,7 @@ func (fs *realSysFs) GetCacheInfo(id int, name string) (CacheInfo, error) {
return CacheInfo{}, err
}
return CacheInfo{
+ Id: id,
Size: size,
Level: level,
Type: cacheType,
diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go
index 86b8d02467e..e22dc20c3e4 100644
--- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go
+++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go
@@ -1,3 +1,4 @@
+//go:build !x86
// +build !x86
// Copyright 2021 Google Inc. All Rights Reserved.
diff --git a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go
index fd6ff358f6f..f0c7b1ae1d1 100644
--- a/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go
+++ b/vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go
@@ -1,3 +1,4 @@
+//go:build x86
// +build x86
// Copyright 2021 Google Inc. All Rights Reserved.
diff --git a/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go b/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
index 980af9cc142..47fea630cbd 100644
--- a/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
+++ b/vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go
@@ -332,20 +332,34 @@ func addCacheInfo(sysFs sysfs.SysFs, node *info.Node) error {
for _, cache := range caches {
c := info.Cache{
+ Id: cache.Id,
Size: cache.Size,
Level: cache.Level,
Type: cache.Type,
}
- if cache.Cpus == numThreadsPerNode && cache.Level > cacheLevel2 {
- // Add a node-level cache.
- cacheFound := false
- for _, nodeCache := range node.Caches {
- if nodeCache == c {
- cacheFound = true
+ if cache.Level > cacheLevel2 {
+ if cache.Cpus == numThreadsPerNode {
+ // Add a node level cache.
+ cacheFound := false
+ for _, nodeCache := range node.Caches {
+ if nodeCache == c {
+ cacheFound = true
+ }
+ }
+ if !cacheFound {
+ node.Caches = append(node.Caches, c)
+ }
+ } else {
+ // Add uncore cache, for architecture in which l3 cache only shared among some cores.
+ uncoreCacheFound := false
+ for _, uncoreCache := range node.Cores[coreID].UncoreCaches {
+ if uncoreCache == c {
+ uncoreCacheFound = true
+ }
+ }
+ if !uncoreCacheFound {
+ node.Cores[coreID].UncoreCaches = append(node.Cores[coreID].UncoreCaches, c)
}
- }
- if !cacheFound {
- node.Caches = append(node.Caches, c)
}
} else if cache.Cpus == numThreadsPerCore {
// Add core level cache
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 94c701f9ce6..84dd0b18b2e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -179,18 +179,14 @@ github.com/container-storage-interface/spec/lib/go/csi
github.com/containerd/cgroups/stats/v1
# github.com/containerd/console v1.0.2 => github.com/containerd/console v1.0.2
github.com/containerd/console
-# github.com/containerd/containerd v1.4.9 => github.com/containerd/containerd v1.4.9
+# github.com/containerd/containerd v1.4.11 => github.com/containerd/containerd v1.4.11
github.com/containerd/containerd/api/services/containers/v1
github.com/containerd/containerd/api/services/tasks/v1
github.com/containerd/containerd/api/services/version/v1
github.com/containerd/containerd/api/types
github.com/containerd/containerd/api/types/task
-github.com/containerd/containerd/containers
github.com/containerd/containerd/errdefs
-github.com/containerd/containerd/identifiers
github.com/containerd/containerd/log
-github.com/containerd/containerd/namespaces
-github.com/containerd/containerd/pkg/dialer
github.com/containerd/containerd/platforms
# github.com/containerd/ttrpc v1.0.2 => github.com/containerd/ttrpc v1.0.2
github.com/containerd/ttrpc
@@ -236,7 +232,7 @@ github.com/daviddengcn/go-colortext
github.com/docker/distribution/digestset
github.com/docker/distribution/reference
github.com/docker/distribution/registry/api/errcode
-# github.com/docker/docker v20.10.2+incompatible => github.com/docker/docker v20.10.2+incompatible
+# github.com/docker/docker v20.10.7+incompatible => github.com/docker/docker v20.10.7+incompatible
## explicit
github.com/docker/docker/api
github.com/docker/docker/api/types
@@ -362,7 +358,7 @@ github.com/golang/protobuf/ptypes/timestamp
github.com/golang/protobuf/ptypes/wrappers
# github.com/google/btree v1.0.1 => github.com/google/btree v1.0.1
github.com/google/btree
-# github.com/google/cadvisor v0.39.2 => github.com/google/cadvisor v0.39.2
+# github.com/google/cadvisor v0.43.0 => github.com/google/cadvisor v0.43.0
## explicit
github.com/google/cadvisor/accelerators
github.com/google/cadvisor/cache/memory
@@ -371,7 +367,12 @@ github.com/google/cadvisor/collector
github.com/google/cadvisor/container
github.com/google/cadvisor/container/common
github.com/google/cadvisor/container/containerd
+github.com/google/cadvisor/container/containerd/containers
+github.com/google/cadvisor/container/containerd/errdefs
+github.com/google/cadvisor/container/containerd/identifiers
github.com/google/cadvisor/container/containerd/install
+github.com/google/cadvisor/container/containerd/namespaces
+github.com/google/cadvisor/container/containerd/pkg/dialer
github.com/google/cadvisor/container/crio
github.com/google/cadvisor/container/crio/install
github.com/google/cadvisor/container/docker
@@ -733,6 +734,7 @@ github.com/tmc/grpc-websocket-proxy/wsproxy
github.com/vishvananda/netlink
github.com/vishvananda/netlink/nl
# github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae => github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
+## explicit
github.com/vishvananda/netns
# github.com/vmware/govmomi v0.20.3 => github.com/vmware/govmomi v0.20.3
## explicit
@@ -2474,7 +2476,7 @@ sigs.k8s.io/yaml
# github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.5.0
# github.com/containerd/cgroups => github.com/containerd/cgroups v1.0.1
# github.com/containerd/console => github.com/containerd/console v1.0.2
-# github.com/containerd/containerd => github.com/containerd/containerd v1.4.9
+# github.com/containerd/containerd => github.com/containerd/containerd v1.4.11
# github.com/containerd/continuity => github.com/containerd/continuity v0.1.0
# github.com/containerd/fifo => github.com/containerd/fifo v1.0.0
# github.com/containerd/go-runc => github.com/containerd/go-runc v1.0.0
@@ -2493,7 +2495,7 @@ sigs.k8s.io/yaml
# github.com/daviddengcn/go-colortext => github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd
# github.com/dnaeon/go-vcr => github.com/dnaeon/go-vcr v1.0.1
# github.com/docker/distribution => github.com/docker/distribution v2.7.1+incompatible
-# github.com/docker/docker => github.com/docker/docker v20.10.2+incompatible
+# github.com/docker/docker => github.com/docker/docker v20.10.7+incompatible
# github.com/docker/go-connections => github.com/docker/go-connections v0.4.0
# github.com/docker/go-units => github.com/docker/go-units v0.4.0
# github.com/docopt/docopt-go => github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
@@ -2538,7 +2540,7 @@ sigs.k8s.io/yaml
# github.com/golang/protobuf => github.com/golang/protobuf v1.5.2
# github.com/golangplus/testing => github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e
# github.com/google/btree => github.com/google/btree v1.0.1
-# github.com/google/cadvisor => github.com/google/cadvisor v0.39.2
+# github.com/google/cadvisor => github.com/google/cadvisor v0.43.0
# github.com/google/go-cmp => github.com/google/go-cmp v0.5.5
# github.com/google/gofuzz => github.com/google/gofuzz v1.1.0
# github.com/google/martian/v3 => github.com/google/martian/v3 v3.1.0