-
Notifications
You must be signed in to change notification settings - Fork 944
feature: stats of cri manager #1431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,15 @@ const ( | |
|
|
||
| // resolvConfPath is the abs path of resolv.conf on host or container. | ||
| resolvConfPath = "/etc/resolv.conf" | ||
|
|
||
| // statsCollectPeriod is the time duration (in time.Second) we sync stats from containerd. | ||
| statsCollectPeriod = 10 | ||
|
|
||
| // defaultSnapshotterName is the default Snapshotter name. | ||
| defaultSnapshotterName = "overlayfs" | ||
|
|
||
| // snapshotPlugin implements a snapshotter. | ||
| snapshotPlugin = "io.containerd.snapshotter.v1" | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -96,6 +105,12 @@ type CriManager struct { | |
| SandboxImage string | ||
| // SandboxStore stores the configuration of sandboxes. | ||
| SandboxStore *meta.Store | ||
|
|
||
| // SnapshotStore stores information of all snapshots. | ||
| SnapshotStore *mgr.SnapshotStore | ||
|
|
||
| // ImageFSUUID is the device uuid of image filesystem. | ||
| ImageFSUUID string | ||
| } | ||
|
|
||
| // NewCriManager creates a brand new cri manager. | ||
|
|
@@ -112,6 +127,7 @@ func NewCriManager(config *config.Config, ctrMgr mgr.ContainerMgr, imgMgr mgr.Im | |
| StreamServer: streamServer, | ||
| SandboxBaseDir: path.Join(config.HomeDir, "sandboxes"), | ||
| SandboxImage: config.CriConfig.SandboxImage, | ||
| SnapshotStore: mgr.NewSnapshotStore(), | ||
| } | ||
|
|
||
| c.SandboxStore, err = meta.NewStore(meta.Config{ | ||
|
|
@@ -128,6 +144,18 @@ func NewCriManager(config *config.Config, ctrMgr mgr.ContainerMgr, imgMgr mgr.Im | |
| return nil, fmt.Errorf("failed to create sandbox meta store: %v", err) | ||
| } | ||
|
|
||
| imageFSPath := imageFSPath(path.Join(config.HomeDir, "containerd/root"), defaultSnapshotterName) | ||
| c.ImageFSUUID, err = getDeviceUUID(imageFSPath) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to get imagefs uuid of %q: %v", imageFSPath, err) | ||
| } | ||
|
|
||
| snapshotsSyncer := ctrMgr.NewSnapshotsSyncer( | ||
| c.SnapshotStore, | ||
| time.Duration(statsCollectPeriod)*time.Second, | ||
| ) | ||
| snapshotsSyncer.Start() | ||
|
|
||
| return NewCriWrapper(c), nil | ||
| } | ||
|
|
||
|
|
@@ -709,12 +737,46 @@ func (c *CriManager) ContainerStatus(ctx context.Context, r *runtime.ContainerSt | |
| // ContainerStats returns stats of the container. If the container does not | ||
| // exist, the call returns an error. | ||
| func (c *CriManager) ContainerStats(ctx context.Context, r *runtime.ContainerStatsRequest) (*runtime.ContainerStatsResponse, error) { | ||
| return nil, fmt.Errorf("ContainerStats Not Implemented Yet") | ||
| containerID := r.GetContainerId() | ||
|
|
||
| container, err := c.ContainerMgr.Get(ctx, containerID) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we use a function to get the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it is not necessary to do that, the function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. The function like Or use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to admit it's more elegant. Thank you. |
||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to get container %q with error: %v", containerID, err) | ||
| } | ||
|
|
||
| cs, err := c.getContainerMetrics(ctx, container) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to decode container metrics: %v", err) | ||
| } | ||
|
|
||
| return &runtime.ContainerStatsResponse{Stats: cs}, nil | ||
| } | ||
|
|
||
| // ListContainerStats returns stats of all running containers. | ||
| func (c *CriManager) ListContainerStats(ctx context.Context, r *runtime.ListContainerStatsRequest) (*runtime.ListContainerStatsResponse, error) { | ||
| return nil, fmt.Errorf("ListContainerStats Not Implemented Yet") | ||
| opts := &mgr.ContainerListOption{All: true} | ||
| filter := func(c *mgr.Container) bool { | ||
| return true | ||
| } | ||
| opts.FilterFunc = filter | ||
|
|
||
| containers, err := c.ContainerMgr.List(ctx, opts) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to list containers: %v", err) | ||
| } | ||
|
|
||
| result := &runtime.ListContainerStatsResponse{} | ||
| for _, container := range containers { | ||
| cs, err := c.getContainerMetrics(ctx, container) | ||
| if err != nil { | ||
| logrus.Errorf("failed to decode metrics of container %q: %v", container.ID, err) | ||
| continue | ||
| } | ||
|
|
||
| result.Stats = append(result.Stats, cs) | ||
| } | ||
|
|
||
| return result, nil | ||
| } | ||
|
|
||
| // UpdateContainerResources updates ContainerConfig of the container. | ||
|
|
@@ -962,5 +1024,25 @@ func (c *CriManager) RemoveImage(ctx context.Context, r *runtime.RemoveImageRequ | |
|
|
||
| // ImageFsInfo returns information of the filesystem that is used to store images. | ||
| func (c *CriManager) ImageFsInfo(ctx context.Context, r *runtime.ImageFsInfoRequest) (*runtime.ImageFsInfoResponse, error) { | ||
| return nil, fmt.Errorf("ImageFsInfo Not Implemented Yet") | ||
| snapshots := c.SnapshotStore.List() | ||
| timestamp := time.Now().UnixNano() | ||
| var usedBytes, inodesUsed uint64 | ||
| for _, sn := range snapshots { | ||
| // Use the oldest timestamp as the timestamp of imagefs info. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add more information about this logic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Timestamp is latest time which the information were collected, we hava to be consistent. So I choose the oldest timestamp as the timestamp of imagefs info here. |
||
| if sn.Timestamp < timestamp { | ||
| timestamp = sn.Timestamp | ||
| } | ||
| usedBytes += sn.Size | ||
| inodesUsed += sn.Inodes | ||
| } | ||
| return &runtime.ImageFsInfoResponse{ | ||
| ImageFilesystems: []*runtime.FilesystemUsage{ | ||
| { | ||
| Timestamp: timestamp, | ||
| StorageId: &runtime.StorageIdentifier{Uuid: c.ImageFSUUID}, | ||
| UsedBytes: &runtime.UInt64Value{Value: usedBytes}, | ||
| InodesUsed: &runtime.UInt64Value{Value: inodesUsed}, | ||
| }, | ||
| }, | ||
| }, nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should add utils' function to retrieve the root folder in the project next step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A separate PR will be submitted to deal with similar things.