Skip to content

Commit 19c267b

Browse files
committed
fix fs_limit, fs_inode_total, fs_inode_free in containerd handler
1 parent 48d4ca3 commit 19c267b

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed

container/containerd/client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"time"
2323

2424
containersapi "github.com/containerd/containerd/api/services/containers/v1"
25+
snapshotapi "github.com/containerd/containerd/api/services/snapshots/v1"
2526
tasksapi "github.com/containerd/containerd/api/services/tasks/v1"
2627
versionapi "github.com/containerd/containerd/api/services/version/v1"
28+
types "github.com/containerd/containerd/api/types"
2729
"github.com/containerd/containerd/containers"
2830
"github.com/containerd/containerd/errdefs"
2931
"github.com/containerd/containerd/pkg/dialer"
@@ -37,13 +39,15 @@ type client struct {
3739
containerService containersapi.ContainersClient
3840
taskService tasksapi.TasksClient
3941
versionService versionapi.VersionClient
42+
snapshotService snapshotapi.SnapshotsClient
4043
criService criapi.RuntimeServiceClient
4144
}
4245

4346
type ContainerdClient interface {
4447
LoadContainer(ctx context.Context, id string) (*containers.Container, error)
4548
TaskPid(ctx context.Context, id string) (uint32, error)
4649
Version(ctx context.Context) (string, error)
50+
SnapshotMounts(ctx context.Context, snapshotter, key string) ([]*types.Mount, error)
4751
ContainerStatus(ctx context.Context, id string) (*criapi.ContainerStatus, error)
4852
ContainerStats(ctx context.Context, id string) (*criapi.ContainerStats, error)
4953
}
@@ -96,6 +100,7 @@ func Client(address, namespace string) (ContainerdClient, error) {
96100
containerService: containersapi.NewContainersClient(conn),
97101
taskService: tasksapi.NewTasksClient(conn),
98102
versionService: versionapi.NewVersionClient(conn),
103+
snapshotService: snapshotapi.NewSnapshotsClient(conn),
99104
criService: criapi.NewRuntimeServiceClient(conn),
100105
}
101106
})
@@ -130,6 +135,17 @@ func (c *client) Version(ctx context.Context) (string, error) {
130135
return response.Version, nil
131136
}
132137

138+
func (c *client) SnapshotMounts(ctx context.Context, snapshotter, key string) ([]*types.Mount, error) {
139+
response, err := c.snapshotService.Mounts(ctx, &snapshotapi.MountsRequest{
140+
Snapshotter: snapshotter,
141+
Key: key,
142+
})
143+
if err != nil {
144+
return nil, errdefs.FromGRPC(err)
145+
}
146+
return response.Mounts, nil
147+
}
148+
133149
func (c *client) ContainerStatus(ctx context.Context, id string) (*criapi.ContainerStatus, error) {
134150
response, err := c.criService.ContainerStatus(ctx, &criapi.ContainerStatusRequest{
135151
ContainerId: id,

container/containerd/client_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"context"
1919
"fmt"
2020

21+
types "github.com/containerd/containerd/api/types"
2122
"github.com/containerd/containerd/containers"
2223
criapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
2324
)
@@ -56,6 +57,10 @@ func (c *containerdClientMock) ContainerStats(ctx context.Context, id string) (*
5657
return c.stats, nil
5758
}
5859

60+
func (c *containerdClientMock) SnapshotMounts(ctx context.Context, snapshotter, key string) ([]*types.Mount, error) {
61+
return nil, nil
62+
}
63+
5964
func mockcontainerdClient(cntrs map[string]*containers.Container, status *criapi.ContainerStatus, stats *criapi.ContainerStats, returnErr error) ContainerdClient {
6065
return &containerdClientMock{
6166
cntrs: cntrs,

container/containerd/handler.go

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ type containerdContainerHandler struct {
4242
machineInfoFactory info.MachineInfoFactory
4343
// Absolute path to the cgroup hierarchies of this container.
4444
// (e.g.: "cpu" -> "/sys/fs/cgroup/cpu/test")
45-
cgroupPaths map[string]string
46-
fsInfo fs.FsInfo
47-
fsHandler common.FsHandler
45+
cgroupPaths map[string]string
46+
fsInfo fs.FsInfo
47+
fsHandler common.FsHandler
48+
fsLimit uint64
49+
fsTotalInodes uint64
50+
fsType string
51+
device string
52+
4853
// Metadata associated with the container.
4954
reference info.ContainerReference
5055
envs map[string]string
@@ -165,6 +170,52 @@ func newContainerdContainerHandler(
165170
handler.image = cntr.Image
166171

167172
if includedMetrics.Has(container.DiskUsageMetrics) && cntr.Labels["io.cri-containerd.kind"] != "sandbox" {
173+
mounts, err := client.SnapshotMounts(ctx, cntr.Snapshotter, cntr.SnapshotKey)
174+
if err != nil {
175+
return nil, err
176+
}
177+
178+
// Default to top directory if the specific upperdir snapshot is not found
179+
snapshotDir := "/var/lib/containerd"
180+
// Example: upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/5001/fs
181+
if len(mounts) > 0 {
182+
for _, option := range mounts[0].Options {
183+
if strings.Index(option, "upperdir=") == 0 {
184+
snapshotDir = option[len("upperdir="):]
185+
break
186+
}
187+
}
188+
}
189+
deviceInfo, err := fsInfo.GetDirFsDevice(snapshotDir)
190+
if err != nil {
191+
return nil, err
192+
}
193+
194+
mi, err := machineInfoFactory.GetMachineInfo()
195+
if err != nil {
196+
return nil, err
197+
}
198+
199+
var (
200+
fsLimit uint64
201+
fsType string
202+
fsTotalInodes uint64
203+
)
204+
// Containerd does not impose any filesystem limits for containers. So use capacity as limit.
205+
for _, fs := range mi.Filesystems {
206+
if fs.Device == deviceInfo.Device {
207+
fsLimit = fs.Capacity
208+
fsType = fs.Type
209+
fsTotalInodes = fs.Inodes
210+
break
211+
}
212+
}
213+
214+
handler.fsLimit = fsLimit
215+
handler.fsType = fsType
216+
handler.fsTotalInodes = fsTotalInodes
217+
handler.device = deviceInfo.Device
218+
168219
handler.fsHandler = common.NewFsHandler(common.DefaultPeriod, &fsUsageProvider{
169220
ctx: ctx,
170221
client: client,
@@ -232,12 +283,15 @@ func (h *containerdContainerHandler) getFsStats(stats *info.ContainerStats) erro
232283
return nil
233284
}
234285

235-
// Device 、fsType and fsLimits and other information are not supported yet
236286
fsStat := info.FsStats{}
237287
usage := h.fsHandler.Usage()
238288
fsStat.BaseUsage = usage.BaseUsageBytes
239289
fsStat.Usage = usage.TotalUsageBytes
240-
fsStat.Inodes = usage.InodeUsage
290+
fsStat.InodesFree = h.fsTotalInodes - usage.InodeUsage
291+
fsStat.Inodes = h.fsTotalInodes
292+
fsStat.Device = h.device
293+
fsStat.Limit = h.fsLimit
294+
fsStat.Type = h.fsType
241295

242296
stats.Filesystem = append(stats.Filesystem, fsStat)
243297

0 commit comments

Comments
 (0)