exec: use an independent name=systemd cgroup path
We aim for containers to be part of a new cgroups hierarchy independent from nomad agent. However, we've been setting a relative path as libcontainer `cfg.Cgroups.Path`, which makes libcontainer concatinate the executor process cgroup with passed cgroup, as set in [1]. By setting an absolute path, we ensure that all cgroups subsystem (including `name=systemd` get a dedicated one). This matches behavior in Nomad 0.8, and behavior of how Docker and OCI sets CgroupsPath[2] Fixes #5736 [1]d7edf9b2e4/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go (L326-L340)
[2]238f8eaa31/vendor/github.com/containerd/containerd/oci/spec.go (L229)
This commit is contained in:
parent
6742ef5d73
commit
f7608c4cef
|
@ -436,7 +436,7 @@ func TestExecDriver_HandlerExec(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Skip systemd and rdma cgroups; rdma was added in most recent kernels and libcontainer/docker
|
// Skip systemd and rdma cgroups; rdma was added in most recent kernels and libcontainer/docker
|
||||||
// don't isolate them by default.
|
// don't isolate them by default.
|
||||||
if strings.HasPrefix(line, "1:name=systemd") || strings.Contains(line, ":rdma:") {
|
if strings.Contains(line, ":rdma:") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !strings.Contains(line, ":/nomad/") {
|
if !strings.Contains(line, ":/nomad/") {
|
||||||
|
|
|
@ -684,7 +684,7 @@ func configureCgroups(cfg *lconfigs.Config, command *ExecCommand) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
id := uuid.Generate()
|
id := uuid.Generate()
|
||||||
cfg.Cgroups.Path = filepath.Join(defaultCgroupParent, id)
|
cfg.Cgroups.Path = filepath.Join("/", defaultCgroupParent, id)
|
||||||
|
|
||||||
if command.Resources == nil || command.Resources.NomadResources == nil {
|
if command.Resources == nil || command.Resources.NomadResources == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -164,6 +164,59 @@ passwd`
|
||||||
}, func(err error) { t.Error(err) })
|
}, func(err error) { t.Error(err) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestExecutor_CgroupPaths asserts that process starts with independent cgroups
|
||||||
|
// hierarchy created for this process
|
||||||
|
func TestExecutor_CgroupPaths(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
require := require.New(t)
|
||||||
|
testutil.ExecCompatible(t)
|
||||||
|
|
||||||
|
testExecCmd := testExecutorCommandWithChroot(t)
|
||||||
|
execCmd, allocDir := testExecCmd.command, testExecCmd.allocDir
|
||||||
|
execCmd.Cmd = "/bin/bash"
|
||||||
|
execCmd.Args = []string{"-c", "sleep 0.2; cat /proc/self/cgroup"}
|
||||||
|
defer allocDir.Destroy()
|
||||||
|
|
||||||
|
execCmd.ResourceLimits = true
|
||||||
|
|
||||||
|
executor := NewExecutorWithIsolation(testlog.HCLogger(t))
|
||||||
|
defer executor.Shutdown("SIGKILL", 0)
|
||||||
|
|
||||||
|
ps, err := executor.Launch(execCmd)
|
||||||
|
require.NoError(err)
|
||||||
|
require.NotZero(ps.Pid)
|
||||||
|
|
||||||
|
state, err := executor.Wait(context.Background())
|
||||||
|
require.NoError(err)
|
||||||
|
require.Zero(state.ExitCode)
|
||||||
|
|
||||||
|
tu.WaitForResult(func() (bool, error) {
|
||||||
|
output := strings.TrimSpace(testExecCmd.stdout.String())
|
||||||
|
// sanity check that we got some cgroups
|
||||||
|
if !strings.Contains(output, ":devices:") {
|
||||||
|
return false, fmt.Errorf("was expected cgroup files but found:\n%v", output)
|
||||||
|
}
|
||||||
|
lines := strings.Split(output, "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
// Every cgroup entry should be /nomad/$ALLOC_ID
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip systemd and rdma cgroups; rdma was added in most recent kernels and libcontainer/docker
|
||||||
|
// don't isolate them by default.
|
||||||
|
if strings.Contains(line, ":rdma:") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(line, ":/nomad/") {
|
||||||
|
return false, fmt.Errorf("Not a member of the alloc's cgroup: expected=...:/nomad/... -- found=%q", line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}, func(err error) { t.Error(err) })
|
||||||
|
}
|
||||||
|
|
||||||
func TestUniversalExecutor_LookupTaskBin(t *testing.T) {
|
func TestUniversalExecutor_LookupTaskBin(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
Loading…
Reference in a new issue