Add systemd cgroup support.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
		@@ -70,6 +70,8 @@ type Config struct {
 | 
			
		||||
	SandboxImage string `toml:"sandbox_image"`
 | 
			
		||||
	// StatsCollectPeriod is the period (in seconds) of snapshots stats collection.
 | 
			
		||||
	StatsCollectPeriod int `toml:"stats_collect_period"`
 | 
			
		||||
	// SystemdCgroup enables systemd cgroup support.
 | 
			
		||||
	SystemdCgroup bool `toml:"systemd_cgroup"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CRIContainerdOptions contains cri-containerd command line and toml options.
 | 
			
		||||
@@ -122,6 +124,8 @@ func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) {
 | 
			
		||||
		"gcr.io/google_containers/pause:3.0", "The image used by sandbox container.")
 | 
			
		||||
	fs.IntVar(&c.StatsCollectPeriod, "stats-collect-period",
 | 
			
		||||
		10, "The period (in seconds) of snapshots stats collection.")
 | 
			
		||||
	fs.BoolVar(&c.SystemdCgroup, "systemd-cgroup",
 | 
			
		||||
		false, "Enables systemd cgroup support.")
 | 
			
		||||
	fs.BoolVar(&c.PrintDefaultConfig, "default-config",
 | 
			
		||||
		false, "Print default toml config of cri-containerd and quit.")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import (
 | 
			
		||||
	"github.com/containerd/containerd"
 | 
			
		||||
	"github.com/containerd/containerd/contrib/apparmor"
 | 
			
		||||
	"github.com/containerd/containerd/contrib/seccomp"
 | 
			
		||||
	"github.com/containerd/containerd/linux/runcopts"
 | 
			
		||||
	"github.com/containerd/typeurl"
 | 
			
		||||
	"github.com/docker/docker/pkg/mount"
 | 
			
		||||
	"github.com/golang/glog"
 | 
			
		||||
@@ -221,7 +222,10 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
 | 
			
		||||
 | 
			
		||||
	opts = append(opts,
 | 
			
		||||
		containerd.WithSpec(spec, specOpts...),
 | 
			
		||||
		containerd.WithRuntime(defaultRuntime, nil),
 | 
			
		||||
		containerd.WithRuntime(
 | 
			
		||||
			defaultRuntime,
 | 
			
		||||
			&runcopts.RuncOptions{SystemdCgroup: c.config.SystemdCgroup},
 | 
			
		||||
		),
 | 
			
		||||
		containerd.WithContainerLabels(map[string]string{containerKindLabel: containerKindContainer}),
 | 
			
		||||
		containerd.WithContainerExtension(containerMetadataExtension, &meta))
 | 
			
		||||
	var cntr containerd.Container
 | 
			
		||||
@@ -344,7 +348,8 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
 | 
			
		||||
	setOCILinuxResource(&g, config.GetLinux().GetResources())
 | 
			
		||||
 | 
			
		||||
	if sandboxConfig.GetLinux().GetCgroupParent() != "" {
 | 
			
		||||
		cgroupsPath := getCgroupsPath(sandboxConfig.GetLinux().GetCgroupParent(), id)
 | 
			
		||||
		cgroupsPath := getCgroupsPath(sandboxConfig.GetLinux().GetCgroupParent(), id,
 | 
			
		||||
			c.config.SystemdCgroup)
 | 
			
		||||
		g.SetLinuxCgroupsPath(cgroupsPath)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,7 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
 | 
			
		||||
		assert.Equal(t, spec.Process.NoNewPrivileges, true)
 | 
			
		||||
 | 
			
		||||
		t.Logf("Check cgroup path")
 | 
			
		||||
		assert.Equal(t, getCgroupsPath("/test/cgroup/parent", id), spec.Linux.CgroupsPath)
 | 
			
		||||
		assert.Equal(t, getCgroupsPath("/test/cgroup/parent", id, false), spec.Linux.CgroupsPath)
 | 
			
		||||
 | 
			
		||||
		t.Logf("Check namespaces")
 | 
			
		||||
		assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -134,8 +135,13 @@ func makeContainerName(c *runtime.ContainerMetadata, s *runtime.PodSandboxMetada
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getCgroupsPath generates container cgroups path.
 | 
			
		||||
func getCgroupsPath(cgroupsParent string, id string) string {
 | 
			
		||||
	// TODO(random-liu): [P0] Handle systemd.
 | 
			
		||||
func getCgroupsPath(cgroupsParent, id string, systemdCgroup bool) string {
 | 
			
		||||
	if systemdCgroup {
 | 
			
		||||
		// Convert a.slice/b.slice/c.slice to c.slice.
 | 
			
		||||
		p := path.Base(cgroupsParent)
 | 
			
		||||
		// runc systemd cgroup path format is "slice:prefix:name".
 | 
			
		||||
		return strings.Join([]string{p, "cri-containerd", id}, ":")
 | 
			
		||||
	}
 | 
			
		||||
	return filepath.Join(cgroupsParent, id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -161,3 +161,27 @@ func TestGetRepoDigestAndTag(t *testing.T) {
 | 
			
		||||
		assert.Equal(t, test.expectedRepoTag, repoTag)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGetCgroupsPath(t *testing.T) {
 | 
			
		||||
	testID := "test-id"
 | 
			
		||||
	for desc, test := range map[string]struct {
 | 
			
		||||
		cgroupsParent string
 | 
			
		||||
		systemdCgroup bool
 | 
			
		||||
		expected      string
 | 
			
		||||
	}{
 | 
			
		||||
		"should support regular cgroup path": {
 | 
			
		||||
			cgroupsParent: "/a/b",
 | 
			
		||||
			systemdCgroup: false,
 | 
			
		||||
			expected:      "/a/b/test-id",
 | 
			
		||||
		},
 | 
			
		||||
		"should support systemd cgroup path": {
 | 
			
		||||
			cgroupsParent: "/a.slice/b.slice",
 | 
			
		||||
			systemdCgroup: true,
 | 
			
		||||
			expected:      "b.slice:cri-containerd:test-id",
 | 
			
		||||
		},
 | 
			
		||||
	} {
 | 
			
		||||
		t.Logf("TestCase %q", desc)
 | 
			
		||||
		got := getCgroupsPath(test.cgroupsParent, testID, test.systemdCgroup)
 | 
			
		||||
		assert.Equal(t, test.expected, got)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/containerd/containerd"
 | 
			
		||||
	"github.com/containerd/containerd/linux/runcopts"
 | 
			
		||||
	"github.com/containerd/typeurl"
 | 
			
		||||
	"github.com/cri-o/ocicni/pkg/ocicni"
 | 
			
		||||
	"github.com/golang/glog"
 | 
			
		||||
@@ -146,7 +147,11 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run
 | 
			
		||||
		containerd.WithSpec(spec, specOpts...),
 | 
			
		||||
		containerd.WithContainerLabels(map[string]string{containerKindLabel: containerKindSandbox}),
 | 
			
		||||
		containerd.WithContainerExtension(sandboxMetadataExtension, &sandbox.Metadata),
 | 
			
		||||
		containerd.WithRuntime(defaultRuntime, nil)}
 | 
			
		||||
		containerd.WithRuntime(
 | 
			
		||||
			defaultRuntime,
 | 
			
		||||
			&runcopts.RuncOptions{SystemdCgroup: c.config.SystemdCgroup},
 | 
			
		||||
		),
 | 
			
		||||
	}
 | 
			
		||||
	container, err := c.client.NewContainer(ctx, id, opts...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("failed to create containerd container: %v", err)
 | 
			
		||||
@@ -258,7 +263,8 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
 | 
			
		||||
 | 
			
		||||
	// Set cgroups parent.
 | 
			
		||||
	if config.GetLinux().GetCgroupParent() != "" {
 | 
			
		||||
		cgroupsPath := getCgroupsPath(config.GetLinux().GetCgroupParent(), id)
 | 
			
		||||
		cgroupsPath := getCgroupsPath(config.GetLinux().GetCgroupParent(), id,
 | 
			
		||||
			c.config.SystemdCgroup)
 | 
			
		||||
		g.SetLinuxCgroupsPath(cgroupsPath)
 | 
			
		||||
	}
 | 
			
		||||
	// When cgroup parent is not set, containerd-shim will create container in a child cgroup
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ func getRunPodSandboxTestData() (*runtime.PodSandboxConfig, *imagespec.ImageConf
 | 
			
		||||
	}
 | 
			
		||||
	specCheck := func(t *testing.T, id string, spec *runtimespec.Spec) {
 | 
			
		||||
		assert.Equal(t, "test-hostname", spec.Hostname)
 | 
			
		||||
		assert.Equal(t, getCgroupsPath("/test/cgroup/parent", id), spec.Linux.CgroupsPath)
 | 
			
		||||
		assert.Equal(t, getCgroupsPath("/test/cgroup/parent", id, false), spec.Linux.CgroupsPath)
 | 
			
		||||
		assert.Equal(t, relativeRootfsPath, spec.Root.Path)
 | 
			
		||||
		assert.Equal(t, true, spec.Root.Readonly)
 | 
			
		||||
		assert.Contains(t, spec.Process.Env, "a=b", "c=d")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user