From dcef12f062575bfad927f201a1cc616dcfd94d2b Mon Sep 17 00:00:00 2001 From: Dillon Giacoppo Date: Sun, 29 Jun 2025 11:44:16 +1000 Subject: [PATCH] fix(3643) add containerd-snapshotter support --- container/docker/factory.go | 24 ++++++++++++++++------- container/docker/handler.go | 38 ++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/container/docker/factory.go b/container/docker/factory.go index 1c68b8625f..7e6a5cdbcc 100644 --- a/container/docker/factory.go +++ b/container/docker/factory.go @@ -25,6 +25,7 @@ import ( "github.com/blang/semver/v4" dockersystem "github.com/docker/docker/api/types/system" + "github.com/google/cadvisor/container/containerd" "github.com/google/cadvisor/container" dockerutil "github.com/google/cadvisor/container/docker/utils" @@ -94,12 +95,13 @@ func RootDir() string { type StorageDriver string const ( - DevicemapperStorageDriver StorageDriver = "devicemapper" - AufsStorageDriver StorageDriver = "aufs" - OverlayStorageDriver StorageDriver = "overlay" - Overlay2StorageDriver StorageDriver = "overlay2" - ZfsStorageDriver StorageDriver = "zfs" - VfsStorageDriver StorageDriver = "vfs" + DevicemapperStorageDriver StorageDriver = "devicemapper" + AufsStorageDriver StorageDriver = "aufs" + OverlayStorageDriver StorageDriver = "overlay" + Overlay2StorageDriver StorageDriver = "overlay2" + ContainerdSnapshotterStorageDriver StorageDriver = "overlayfs" + ZfsStorageDriver StorageDriver = "zfs" + VfsStorageDriver StorageDriver = "vfs" ) type dockerFactory struct { @@ -108,7 +110,8 @@ type dockerFactory struct { storageDriver StorageDriver storageDir string - client *docker.Client + client *docker.Client + containerdClient containerd.ContainerdClient // Information about the mounted cgroup subsystems. cgroupSubsystems map[string]string @@ -147,6 +150,7 @@ func (f *dockerFactory) NewContainerHandler(name string, metadataEnvAllowList [] handler, err = newDockerContainerHandler( client, + f.containerdClient, name, f.machineInfoFactory, f.fsInfo, @@ -349,10 +353,16 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics } } + containerdClient, err := containerd.Client(*containerd.ArgContainerdEndpoint, "moby") + if err != nil { + return fmt.Errorf("unable to create containerd client: %v", err) + } + klog.V(1).Infof("Registering Docker factory") f := &dockerFactory{ cgroupSubsystems: cgroupSubsystems, client: client, + containerdClient: containerdClient, dockerVersion: dockerVersion, dockerAPIVersion: dockerAPIVersion, fsInfo: fsInfo, diff --git a/container/docker/handler.go b/container/docker/handler.go index 86ec729047..3f5593d2fc 100644 --- a/container/docker/handler.go +++ b/container/docker/handler.go @@ -16,6 +16,7 @@ package docker import ( + "encoding/json" "fmt" "os" "path" @@ -25,6 +26,8 @@ import ( "github.com/google/cadvisor/container" "github.com/google/cadvisor/container/common" + "github.com/google/cadvisor/container/containerd" + "github.com/google/cadvisor/container/containerd/namespaces" dockerutil "github.com/google/cadvisor/container/docker/utils" containerlibcontainer "github.com/google/cadvisor/container/libcontainer" "github.com/google/cadvisor/devicemapper" @@ -32,6 +35,7 @@ import ( info "github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/zfs" "github.com/opencontainers/cgroups" + "github.com/opencontainers/runtime-spec/specs-go" docker "github.com/docker/docker/client" "golang.org/x/net/context" @@ -112,6 +116,7 @@ func getRwLayerID(containerID, storageDir string, sd StorageDriver, dockerVersio // newDockerContainerHandler returns a new container.ContainerHandler func newDockerContainerHandler( client *docker.Client, + containerdClient containerd.ContainerdClient, name string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, @@ -147,16 +152,31 @@ func newDockerContainerHandler( // FIXME: Give `otherStorageDir` a more descriptive name. otherStorageDir := path.Join(storageDir, pathToContainersDir, id) - rwLayerID, err := getRwLayerID(id, storageDir, storageDriver, dockerVersion) - if err != nil { - return nil, err - } + var rootfsStorageDir, zfsFilesystem, zfsParent string + if storageDriver == ContainerdSnapshotterStorageDriver { + ctx := namespaces.WithNamespace(context.Background(), "moby") + cntr, err := containerdClient.LoadContainer(ctx, id) + if err != nil { + return nil, err + } - // Determine the rootfs storage dir OR the pool name to determine the device. - // For devicemapper, we only need the thin pool name, and that is passed in to this call - rootfsStorageDir, zfsFilesystem, zfsParent, err := DetermineDeviceStorage(storageDriver, storageDir, rwLayerID) - if err != nil { - return nil, fmt.Errorf("unable to determine device storage: %v", err) + var spec specs.Spec + if err := json.Unmarshal(cntr.Spec.Value, &spec); err != nil { + return nil, err + } + rootfsStorageDir = spec.Root.Path + } else { + rwLayerID, err := getRwLayerID(id, storageDir, storageDriver, dockerVersion) + if err != nil { + return nil, err + } + + // Determine the rootfs storage dir OR the pool name to determine the device. + // For devicemapper, we only need the thin pool name, and that is passed in to this call + rootfsStorageDir, zfsFilesystem, zfsParent, err = DetermineDeviceStorage(storageDriver, storageDir, rwLayerID) + if err != nil { + return nil, fmt.Errorf("unable to determine device storage: %v", err) + } } // We assume that if Inspect fails then the container is not known to docker.