mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-27 15:57:09 +00:00
virtcontainers: add StatsSandbox to vc API
StatsSandbox is used to gather metrics for the sandbox (host cgroup) as well as from the individual containers (from the guest cgroups). This is intended to be used for easily calculating Kata sandbox overheads. Fixes: #2096 Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com> Signed-off-by: Eric Ernst <eric.ernst@intel.com>
This commit is contained in:
parent
569bd780f1
commit
1bbc1d58bd
@ -758,6 +758,46 @@ func StatsContainer(ctx context.Context, sandboxID, containerID string) (Contain
|
|||||||
return s.StatsContainer(containerID)
|
return s.StatsContainer(containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatsSandbox is the virtcontainers sandbox stats entry point.
|
||||||
|
// StatsSandbox returns a detailed sandbox stats.
|
||||||
|
func StatsSandbox(ctx context.Context, sandboxID string) (SandboxStats, []ContainerStats, error) {
|
||||||
|
span, ctx := trace(ctx, "StatsSandbox")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
if sandboxID == "" {
|
||||||
|
return SandboxStats{}, []ContainerStats{}, vcTypes.ErrNeedSandboxID
|
||||||
|
}
|
||||||
|
|
||||||
|
lockFile, err := rLockSandbox(ctx, sandboxID)
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, []ContainerStats{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer unlockSandbox(ctx, sandboxID, lockFile)
|
||||||
|
|
||||||
|
s, err := fetchSandbox(ctx, sandboxID)
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, []ContainerStats{}, err
|
||||||
|
}
|
||||||
|
defer s.releaseStatelessSandbox()
|
||||||
|
|
||||||
|
sandboxStats, err := s.Stats()
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, []ContainerStats{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
containerStats := []ContainerStats{}
|
||||||
|
for _, c := range s.containers {
|
||||||
|
cstats, err := s.StatsContainer(c.id)
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, []ContainerStats{}, err
|
||||||
|
}
|
||||||
|
containerStats = append(containerStats, cstats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sandboxStats, containerStats, nil
|
||||||
|
}
|
||||||
|
|
||||||
func togglePauseContainer(ctx context.Context, sandboxID, containerID string, pause bool) error {
|
func togglePauseContainer(ctx context.Context, sandboxID, containerID string, pause bool) error {
|
||||||
if sandboxID == "" {
|
if sandboxID == "" {
|
||||||
return vcTypes.ErrNeedSandboxID
|
return vcTypes.ErrNeedSandboxID
|
||||||
|
@ -122,6 +122,11 @@ func (impl *VCImpl) StatsContainer(ctx context.Context, sandboxID, containerID s
|
|||||||
return StatsContainer(ctx, sandboxID, containerID)
|
return StatsContainer(ctx, sandboxID, containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatsSandbox implements the VC function of the same name.
|
||||||
|
func (impl *VCImpl) StatsSandbox(ctx context.Context, sandboxID string) (SandboxStats, []ContainerStats, error) {
|
||||||
|
return StatsSandbox(ctx, sandboxID)
|
||||||
|
}
|
||||||
|
|
||||||
// KillContainer implements the VC function of the same name.
|
// KillContainer implements the VC function of the same name.
|
||||||
func (impl *VCImpl) KillContainer(ctx context.Context, sandboxID, containerID string, signal syscall.Signal, all bool) error {
|
func (impl *VCImpl) KillContainer(ctx context.Context, sandboxID, containerID string, signal syscall.Signal, all bool) error {
|
||||||
return KillContainer(ctx, sandboxID, containerID, signal, all)
|
return KillContainer(ctx, sandboxID, containerID, signal, all)
|
||||||
|
@ -41,6 +41,7 @@ type VC interface {
|
|||||||
StartContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
StartContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
||||||
StatusContainer(ctx context.Context, sandboxID, containerID string) (ContainerStatus, error)
|
StatusContainer(ctx context.Context, sandboxID, containerID string) (ContainerStatus, error)
|
||||||
StatsContainer(ctx context.Context, sandboxID, containerID string) (ContainerStats, error)
|
StatsContainer(ctx context.Context, sandboxID, containerID string) (ContainerStats, error)
|
||||||
|
StatsSandbox(ctx context.Context, sandboxID string) (SandboxStats, []ContainerStats, error)
|
||||||
StopContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
StopContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
||||||
ProcessListContainer(ctx context.Context, sandboxID, containerID string, options ProcessListOptions) (ProcessList, error)
|
ProcessListContainer(ctx context.Context, sandboxID, containerID string, options ProcessListOptions) (ProcessList, error)
|
||||||
UpdateContainer(ctx context.Context, sandboxID, containerID string, resources specs.LinuxResources) error
|
UpdateContainer(ctx context.Context, sandboxID, containerID string, resources specs.LinuxResources) error
|
||||||
|
@ -200,6 +200,15 @@ func (m *VCMock) StatsContainer(ctx context.Context, sandboxID, containerID stri
|
|||||||
return vc.ContainerStats{}, fmt.Errorf("%s: %s (%+v): sandboxID: %v, containerID: %v", mockErrorPrefix, getSelf(), m, sandboxID, containerID)
|
return vc.ContainerStats{}, fmt.Errorf("%s: %s (%+v): sandboxID: %v, containerID: %v", mockErrorPrefix, getSelf(), m, sandboxID, containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StatsSandbox implements the VC function of the same name.
|
||||||
|
func (m *VCMock) StatsSandbox(ctx context.Context, sandboxID string) (vc.SandboxStats, []vc.ContainerStats, error) {
|
||||||
|
if m.StatsContainerFunc != nil {
|
||||||
|
return m.StatsSandboxFunc(ctx, sandboxID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return vc.SandboxStats{}, []vc.ContainerStats{}, fmt.Errorf("%s: %s (%+v): sandboxID: %v", mockErrorPrefix, getSelf(), m, sandboxID)
|
||||||
|
}
|
||||||
|
|
||||||
// KillContainer implements the VC function of the same name.
|
// KillContainer implements the VC function of the same name.
|
||||||
func (m *VCMock) KillContainer(ctx context.Context, sandboxID, containerID string, signal syscall.Signal, all bool) error {
|
func (m *VCMock) KillContainer(ctx context.Context, sandboxID, containerID string, signal syscall.Signal, all bool) error {
|
||||||
if m.KillContainerFunc != nil {
|
if m.KillContainerFunc != nil {
|
||||||
|
@ -54,6 +54,7 @@ type VCMock struct {
|
|||||||
StartSandboxFunc func(ctx context.Context, sandboxID string) (vc.VCSandbox, error)
|
StartSandboxFunc func(ctx context.Context, sandboxID string) (vc.VCSandbox, error)
|
||||||
StatusSandboxFunc func(ctx context.Context, sandboxID string) (vc.SandboxStatus, error)
|
StatusSandboxFunc func(ctx context.Context, sandboxID string) (vc.SandboxStatus, error)
|
||||||
StatsContainerFunc func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStats, error)
|
StatsContainerFunc func(ctx context.Context, sandboxID, containerID string) (vc.ContainerStats, error)
|
||||||
|
StatsSandboxFunc func(ctx context.Context, sandboxID string) (vc.SandboxStats, []vc.ContainerStats, error)
|
||||||
StopSandboxFunc func(ctx context.Context, sandboxID string, force bool) (vc.VCSandbox, error)
|
StopSandboxFunc func(ctx context.Context, sandboxID string, force bool) (vc.VCSandbox, error)
|
||||||
|
|
||||||
CreateContainerFunc func(ctx context.Context, sandboxID string, containerConfig vc.ContainerConfig) (vc.VCSandbox, vc.VCContainer, error)
|
CreateContainerFunc func(ctx context.Context, sandboxID string, containerConfig vc.ContainerConfig) (vc.VCSandbox, vc.VCContainer, error)
|
||||||
|
@ -63,6 +63,12 @@ type SandboxStatus struct {
|
|||||||
Annotations map[string]string
|
Annotations map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SandboxStats describes a sandbox's stats
|
||||||
|
type SandboxStats struct {
|
||||||
|
CgroupStats CgroupStats
|
||||||
|
Cpus int
|
||||||
|
}
|
||||||
|
|
||||||
// SandboxConfig is a Sandbox configuration.
|
// SandboxConfig is a Sandbox configuration.
|
||||||
type SandboxConfig struct {
|
type SandboxConfig struct {
|
||||||
ID string
|
ID string
|
||||||
@ -1367,6 +1373,46 @@ func (s *Sandbox) StatsContainer(containerID string) (ContainerStats, error) {
|
|||||||
return *stats, nil
|
return *stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats returns the stats of a running sandbox
|
||||||
|
func (s *Sandbox) Stats() (SandboxStats, error) {
|
||||||
|
if s.state.CgroupPath == "" {
|
||||||
|
return SandboxStats{}, fmt.Errorf("sandbox cgroup path is emtpy")
|
||||||
|
}
|
||||||
|
|
||||||
|
var path string
|
||||||
|
var cgroupSubsystems cgroups.Hierarchy
|
||||||
|
|
||||||
|
if s.config.SandboxCgroupOnly {
|
||||||
|
cgroupSubsystems = cgroups.V1
|
||||||
|
path = s.state.CgroupPath
|
||||||
|
} else {
|
||||||
|
cgroupSubsystems = V1NoConstraints
|
||||||
|
path = cgroupNoConstraintsPath(s.state.CgroupPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
cgroup, err := cgroupsLoadFunc(cgroupSubsystems, cgroups.StaticPath(path))
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, fmt.Errorf("Could not load sandbox cgroup in %v: %v", s.state.CgroupPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
metrics, err := cgroup.Stat(cgroups.ErrorHandler(cgroups.IgnoreNotExist))
|
||||||
|
if err != nil {
|
||||||
|
return SandboxStats{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stats := SandboxStats{}
|
||||||
|
|
||||||
|
stats.CgroupStats.CPUStats.CPUUsage.TotalUsage = metrics.CPU.Usage.Total
|
||||||
|
stats.CgroupStats.MemoryStats.Usage.Usage = metrics.Memory.Usage.Usage
|
||||||
|
tids, err := s.hypervisor.getThreadIDs()
|
||||||
|
if err != nil {
|
||||||
|
return stats, err
|
||||||
|
}
|
||||||
|
stats.Cpus = len(tids.vcpus)
|
||||||
|
|
||||||
|
return stats, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PauseContainer pauses a running container.
|
// PauseContainer pauses a running container.
|
||||||
func (s *Sandbox) PauseContainer(containerID string) error {
|
func (s *Sandbox) PauseContainer(containerID string) error {
|
||||||
// Fetch the container.
|
// Fetch the container.
|
||||||
@ -2125,7 +2171,6 @@ func (s *Sandbox) setupSandboxCgroup() error {
|
|||||||
if err := cgroup.Add(cgroups.Process{Pid: runtimePid}); err != nil {
|
if err := cgroup.Add(cgroups.Process{Pid: runtimePid}); err != nil {
|
||||||
return fmt.Errorf("Could not add runtime PID %d to sandbox cgroup: %v", runtimePid, err)
|
return fmt.Errorf("Could not add runtime PID %d to sandbox cgroup: %v", runtimePid, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user