support cgroup2

* only shim v2 runc v2 ("io.containerd.runc.v2") is supported
* only PID metrics is implemented. Others should be implemented in separate PRs.
* lots of code duplication in v1 metrics and v2 metrics. Dedupe should be separate PR.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2019-11-05 13:31:48 +09:00
parent f01665aa02
commit 8f870c233f
69 changed files with 10619 additions and 160 deletions

View File

@@ -26,6 +26,7 @@ import (
"sync"
"github.com/containerd/cgroups"
cgroupsv2 "github.com/containerd/cgroups/v2"
"github.com/containerd/console"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
@@ -133,9 +134,22 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
}
pid := p.Pid()
if pid > 0 {
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
if err != nil {
logrus.WithError(err).Errorf("loading cgroup for %d", pid)
var cg interface{}
if cgroups.Mode() == cgroups.Unified {
g, err := cgroupsv2.PidGroupPath(pid)
if err != nil {
logrus.WithError(err).Errorf("loading cgroup2 for %d", pid)
return container, nil
}
cg, err = cgroupsv2.LoadManager("/sys/fs/cgroup", g)
if err != nil {
logrus.WithError(err).Errorf("loading cgroup2 for %d", pid)
}
} else {
cg, err = cgroups.Load(cgroups.V1, cgroups.PidPath(pid))
if err != nil {
logrus.WithError(err).Errorf("loading cgroup for %d", pid)
}
}
container.cgroup = cg
}
@@ -190,7 +204,8 @@ type Container struct {
// Bundle path
Bundle string
cgroup cgroups.Cgroup
// cgroup is either cgroups.Cgroup or *cgroupsv2.Manager
cgroup interface{}
process process.Process
processes map[string]process.Process
reservedProcess map[string]struct{}
@@ -228,14 +243,14 @@ func (c *Container) Pid() int {
}
// Cgroup of the container
func (c *Container) Cgroup() cgroups.Cgroup {
func (c *Container) Cgroup() interface{} {
c.mu.Lock()
defer c.mu.Unlock()
return c.cgroup
}
// CgroupSet sets the cgroup to the container
func (c *Container) CgroupSet(cg cgroups.Cgroup) {
func (c *Container) CgroupSet(cg interface{}) {
c.mu.Lock()
c.cgroup = cg
c.mu.Unlock()
@@ -307,9 +322,21 @@ func (c *Container) Start(ctx context.Context, r *task.StartRequest) (process.Pr
return nil, err
}
if c.Cgroup() == nil && p.Pid() > 0 {
cg, err := cgroups.Load(cgroups.V1, cgroups.PidPath(p.Pid()))
if err != nil {
logrus.WithError(err).Errorf("loading cgroup for %d", p.Pid())
var cg interface{}
if cgroups.Mode() == cgroups.Unified {
g, err := cgroupsv2.PidGroupPath(p.Pid())
if err != nil {
logrus.WithError(err).Errorf("loading cgroup2 for %d", p.Pid())
}
cg, err = cgroupsv2.LoadManager("/sys/fs/cgroup", g)
if err != nil {
logrus.WithError(err).Errorf("loading cgroup2 for %d", p.Pid())
}
} else {
cg, err = cgroups.Load(cgroups.V1, cgroups.PidPath(p.Pid()))
if err != nil {
logrus.WithError(err).Errorf("loading cgroup for %d", p.Pid())
}
}
c.cgroup = cg
}