cgroup2: implement containerd.events.TaskOOM event

How to test (from https://github.com/opencontainers/runc/pull/2352#issuecomment-620834524):
  (host)$ sudo swapoff -a
  (host)$ sudo ctr run -t --rm --memory-limit $((1024*1024*32)) docker.io/library/alpine:latest foo
  (container)$ sh -c 'VAR=$(seq 1 100000000)'

An event `/tasks/oom {"container_id":"foo"}` will be displayed in `ctr events`.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2020-05-20 13:51:12 +09:00
parent d9809bbbe0
commit 2f601013e6
17 changed files with 861 additions and 149 deletions

View File

@@ -35,6 +35,7 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/oom"
oomv1 "github.com/containerd/containerd/pkg/oom/v1"
"github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/runtime/v2/runc"
@@ -58,7 +59,7 @@ var (
// New returns a new shim service that can be used via GRPC
func New(ctx context.Context, id string, publisher shim.Publisher, shutdown func()) (shim.Shim, error) {
ep, err := oom.New(publisher)
ep, err := oomv1.New(publisher)
if err != nil {
return nil, err
}
@@ -90,7 +91,7 @@ type service struct {
events chan interface{}
platform stdio.Platform
ec chan runcC.Exit
ep *oom.Epoller
ep oom.Watcher
id string
container *runc.Container

View File

@@ -38,6 +38,8 @@ import (
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/oom"
oomv1 "github.com/containerd/containerd/pkg/oom/v1"
oomv2 "github.com/containerd/containerd/pkg/oom/v2"
"github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/runtime/v2/runc"
@@ -73,7 +75,15 @@ type spec struct {
// New returns a new shim service that can be used via GRPC
func New(ctx context.Context, id string, publisher shim.Publisher, shutdown func()) (shim.Shim, error) {
ep, err := oom.New(publisher)
var (
ep oom.Watcher
err error
)
if cgroups.Mode() == cgroups.Unified {
ep, err = oomv2.New(publisher)
} else {
ep, err = oomv1.New(publisher)
}
if err != nil {
return nil, err
}
@@ -106,7 +116,7 @@ type service struct {
events chan interface{}
platform stdio.Platform
ec chan runcC.Exit
ep *oom.Epoller
ep oom.Watcher
// id only used in cleanup case
id string
@@ -344,9 +354,9 @@ func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.
logrus.WithError(err).Errorf("failed to enable controllers (%v)", allControllers)
}
}
// OOM monitor is not implemented yet
logrus.WithError(errdefs.ErrNotImplemented).Warn("add cg to OOM monitor")
if err := s.ep.Add(container.ID, cg); err != nil {
logrus.WithError(err).Error("add cg to OOM monitor")
}
}
s.send(&eventstypes.TaskStart{