From b16c4f2f03ef5d51d0d864c31b22d5d5da65c8e7 Mon Sep 17 00:00:00 2001 From: Lantao Liu Date: Thu, 8 Feb 2018 00:18:31 +0000 Subject: [PATCH] Use new namespace mode and support shared pid namespace. Signed-off-by: Lantao Liu --- pkg/server/container_create.go | 10 +++--- pkg/server/container_create_test.go | 56 +++++++++++++++++++---------- pkg/server/helpers.go | 9 ++++- pkg/server/restart.go | 4 +-- pkg/server/sandbox_run.go | 15 ++++---- pkg/server/sandbox_run_test.go | 28 +++++++-------- pkg/server/sandbox_status.go | 12 +++---- pkg/server/sandbox_status_test.go | 14 ++++---- 8 files changed, 86 insertions(+), 62 deletions(-) diff --git a/pkg/server/container_create.go b/pkg/server/container_create.go index eafd670b0..dee76a55d 100644 --- a/pkg/server/container_create.go +++ b/pkg/server/container_create.go @@ -43,7 +43,7 @@ import ( "github.com/syndtr/gocapability/capability" "golang.org/x/net/context" "golang.org/x/sys/unix" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "github.com/containerd/cri-containerd/pkg/annotations" customopts "github.com/containerd/cri-containerd/pkg/containerd/opts" @@ -427,7 +427,7 @@ func (c *criContainerdService) generateContainerMounts(sandboxRootDir string, co if !isInCRIMounts(devShm, config.GetMounts()) { sandboxDevShm := getSandboxDevShm(sandboxRootDir) - if securityContext.GetNamespaceOptions().GetHostIpc() { + if securityContext.GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE { sandboxDevShm = devShm } mounts = append(mounts, &runtime.Mount{ @@ -718,9 +718,9 @@ func setOCINamespaces(g *generate.Generator, namespaces *runtime.NamespaceOption g.AddOrReplaceLinuxNamespace(string(runtimespec.NetworkNamespace), getNetworkNamespace(sandboxPid)) // nolint: errcheck g.AddOrReplaceLinuxNamespace(string(runtimespec.IPCNamespace), getIPCNamespace(sandboxPid)) // nolint: errcheck g.AddOrReplaceLinuxNamespace(string(runtimespec.UTSNamespace), getUTSNamespace(sandboxPid)) // nolint: errcheck - // Do not share pid namespace for now. - if namespaces.GetHostPid() { - g.RemoveLinuxNamespace(string(runtimespec.PIDNamespace)) // nolint: errcheck + // Do not share pid namespace if namespace mode is CONTAINER. + if namespaces.GetPid() != runtime.NamespaceMode_CONTAINER { + g.AddOrReplaceLinuxNamespace(string(runtimespec.PIDNamespace), getPIDNamespace(sandboxPid)) // nolint: errcheck } } diff --git a/pkg/server/container_create_test.go b/pkg/server/container_create_test.go index 0d4ce0ebf..951c246f4 100644 --- a/pkg/server/container_create_test.go +++ b/pkg/server/container_create_test.go @@ -30,7 +30,7 @@ import ( "github.com/opencontainers/runtime-tools/generate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "github.com/containerd/cri-containerd/pkg/annotations" ostesting "github.com/containerd/cri-containerd/pkg/os/testing" @@ -169,6 +169,10 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox Type: runtimespec.UTSNamespace, Path: getUTSNamespace(sandboxPid), }) + assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ + Type: runtimespec.PIDNamespace, + Path: getPIDNamespace(sandboxPid), + }) t.Logf("Check PodSandbox annotations") assert.Contains(t, spec.Annotations, annotations.SandboxID) @@ -543,7 +547,7 @@ func TestGenerateContainerMounts(t *testing.T) { }, "should use host /dev/shm when host ipc is set": { securityContext: &runtime.LinuxContainerSecurityContext{ - NamespaceOptions: &runtime.NamespaceOption{HostIpc: true}, + NamespaceOptions: &runtime.NamespaceOption{Ipc: runtime.NamespaceMode_NODE}, }, expectedMounts: []*runtime.Mount{ { @@ -748,25 +752,39 @@ func TestPidNamespace(t *testing.T) { testID := "test-id" testPid := uint32(1234) testSandboxID := "sandbox-id" - config, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData() + config, sandboxConfig, imageConfig, _ := getCreateContainerTestData() c := newTestCRIContainerdService() - t.Logf("should not set pid namespace when host pid is true") - config.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{HostPid: true} - spec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil) - require.NoError(t, err) - specCheck(t, testID, testSandboxID, testPid, spec) - for _, ns := range spec.Linux.Namespaces { - assert.NotEqual(t, ns.Type, runtimespec.PIDNamespace) + for desc, test := range map[string]struct { + pidNS runtime.NamespaceMode + expected runtimespec.LinuxNamespace + }{ + "node namespace mode": { + pidNS: runtime.NamespaceMode_NODE, + expected: runtimespec.LinuxNamespace{ + Type: runtimespec.PIDNamespace, + Path: getPIDNamespace(testPid), + }, + }, + "container namespace mode": { + pidNS: runtime.NamespaceMode_CONTAINER, + expected: runtimespec.LinuxNamespace{ + Type: runtimespec.PIDNamespace, + }, + }, + "pod namespace mode": { + pidNS: runtime.NamespaceMode_POD, + expected: runtimespec.LinuxNamespace{ + Type: runtimespec.PIDNamespace, + Path: getPIDNamespace(testPid), + }, + }, + } { + t.Logf("TestCase %q", desc) + config.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{Pid: test.pidNS} + spec, err := c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil) + require.NoError(t, err) + assert.Contains(t, spec.Linux.Namespaces, test.expected) } - - t.Logf("should set pid namespace when host pid is false") - config.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{HostPid: false} - spec, err = c.generateContainerSpec(testID, testSandboxID, testPid, config, sandboxConfig, imageConfig, nil) - require.NoError(t, err) - specCheck(t, testID, testSandboxID, testPid, spec) - assert.Contains(t, spec.Linux.Namespaces, runtimespec.LinuxNamespace{ - Type: runtimespec.PIDNamespace, - }) } func TestDefaultRuntimeSpec(t *testing.T) { diff --git a/pkg/server/helpers.go b/pkg/server/helpers.go index dbc6fffb1..a7956a28e 100644 --- a/pkg/server/helpers.go +++ b/pkg/server/helpers.go @@ -36,7 +36,7 @@ import ( "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" "golang.org/x/net/context" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "k8s.io/kubernetes/pkg/util/sysctl" "github.com/containerd/cri-containerd/pkg/store" @@ -84,6 +84,8 @@ const ( ipcNSFormat = "/proc/%v/ns/ipc" // utsNSFormat is the format of uts namespace of a process. utsNSFormat = "/proc/%v/ns/uts" + // pidNSFormat is the format of pid namespace of a process. + pidNSFormat = "/proc/%v/ns/pid" // devShm is the default path of /dev/shm. devShm = "/dev/shm" // etcHosts is the default path of /etc/hosts file. @@ -183,6 +185,11 @@ func getUTSNamespace(pid uint32) string { return fmt.Sprintf(utsNSFormat, pid) } +// getPIDNamespace returns the pid namespace of a process. +func getPIDNamespace(pid uint32) string { + return fmt.Sprintf(pidNSFormat, pid) +} + // criContainerStateToString formats CRI container state to string. func criContainerStateToString(state runtime.ContainerState) string { return runtime.ContainerState_name[int32(state)] diff --git a/pkg/server/restart.go b/pkg/server/restart.go index ee8f471ec..af590e85e 100644 --- a/pkg/server/restart.go +++ b/pkg/server/restart.go @@ -33,7 +33,7 @@ import ( "github.com/docker/docker/pkg/system" "github.com/sirupsen/logrus" "golang.org/x/net/context" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" cio "github.com/containerd/cri-containerd/pkg/server/io" containerstore "github.com/containerd/cri-containerd/pkg/store/container" @@ -352,7 +352,7 @@ func loadSandbox(ctx context.Context, cntr containerd.Container) (sandboxstore.S sandbox.Container = cntr // Load network namespace. - if meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostNetwork() { + if meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE { // Don't need to load netns for host network sandbox. return sandbox, nil } diff --git a/pkg/server/sandbox_run.go b/pkg/server/sandbox_run.go index b26cc4b3d..2e08d684d 100644 --- a/pkg/server/sandbox_run.go +++ b/pkg/server/sandbox_run.go @@ -33,7 +33,7 @@ import ( "github.com/sirupsen/logrus" "golang.org/x/net/context" "golang.org/x/sys/unix" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" "github.com/containerd/cri-containerd/pkg/annotations" customopts "github.com/containerd/cri-containerd/pkg/containerd/opts" @@ -87,7 +87,7 @@ func (c *criContainerdService) RunPodSandbox(ctx context.Context, r *runtime.Run } securityContext := config.GetLinux().GetSecurityContext() //Create Network Namespace if it is not in host network - hostNet := securityContext.GetNamespaceOptions().GetHostNetwork() + hostNet := securityContext.GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE if !hostNet { // If it is not in host network namespace then create a namespace and set the sandbox // handle. NetNSPath in sandbox metadata and NetNS is non empty only for non host network @@ -362,17 +362,16 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r // Set namespace options. securityContext := config.GetLinux().GetSecurityContext() nsOptions := securityContext.GetNamespaceOptions() - if nsOptions.GetHostNetwork() { + if nsOptions.GetNetwork() == runtime.NamespaceMode_NODE { g.RemoveLinuxNamespace(string(runtimespec.NetworkNamespace)) // nolint: errcheck } else { //TODO(Abhi): May be move this to containerd spec opts (WithLinuxSpaceOption) g.AddOrReplaceLinuxNamespace(string(runtimespec.NetworkNamespace), nsPath) // nolint: errcheck } - if nsOptions.GetHostPid() { + if nsOptions.GetPid() == runtime.NamespaceMode_NODE { g.RemoveLinuxNamespace(string(runtimespec.PIDNamespace)) // nolint: errcheck } - - if nsOptions.GetHostIpc() { + if nsOptions.GetIpc() == runtime.NamespaceMode_NODE { g.RemoveLinuxNamespace(string(runtimespec.IPCNamespace)) // nolint: errcheck } @@ -439,7 +438,7 @@ func (c *criContainerdService) setupSandboxFiles(rootDir string, config *runtime } // Setup sandbox /dev/shm. - if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostIpc() { + if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetIpc() == runtime.NamespaceMode_NODE { if _, err := c.os.Stat(devShm); err != nil { return fmt.Errorf("host %q is not available for host ipc: %v", devShm, err) } @@ -486,7 +485,7 @@ func parseDNSOptions(servers, searches, options []string) (string, error) { // 1) The mount point is already unmounted. // 2) The mount point doesn't exist. func (c *criContainerdService) unmountSandboxFiles(rootDir string, config *runtime.PodSandboxConfig) error { - if !config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostIpc() { + if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetIpc() != runtime.NamespaceMode_NODE { if err := c.os.Unmount(getSandboxDevShm(rootDir), unix.MNT_DETACH); err != nil && !os.IsNotExist(err) { return err } diff --git a/pkg/server/sandbox_run_test.go b/pkg/server/sandbox_run_test.go index daf57c70c..30e4ed901 100644 --- a/pkg/server/sandbox_run_test.go +++ b/pkg/server/sandbox_run_test.go @@ -27,7 +27,7 @@ import ( runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" ostesting "github.com/containerd/cri-containerd/pkg/os/testing" sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox" @@ -105,9 +105,9 @@ func TestGenerateSandboxContainerSpec(t *testing.T) { configChange: func(c *runtime.PodSandboxConfig) { c.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ NamespaceOptions: &runtime.NamespaceOption{ - HostNetwork: true, - HostPid: true, - HostIpc: true, + Network: runtime.NamespaceMode_NODE, + Pid: runtime.NamespaceMode_NODE, + Ipc: runtime.NamespaceMode_NODE, }, } }, @@ -179,11 +179,11 @@ func TestSetupSandboxFiles(t *testing.T) { testRootDir := "test-sandbox-root" for desc, test := range map[string]struct { dnsConfig *runtime.DNSConfig - hostIpc bool + ipcMode runtime.NamespaceMode expectedCalls []ostesting.CalledDetail }{ - "should check host /dev/shm existence when hostIpc is true": { - hostIpc: true, + "should check host /dev/shm existence when ipc mode is NODE": { + ipcMode: runtime.NamespaceMode_NODE, expectedCalls: []ostesting.CalledDetail{ { Name: "CopyFile", @@ -209,7 +209,7 @@ func TestSetupSandboxFiles(t *testing.T) { Searches: []string{"114.114.114.114"}, Options: []string{"timeout:1"}, }, - hostIpc: true, + ipcMode: runtime.NamespaceMode_NODE, expectedCalls: []ostesting.CalledDetail{ { Name: "CopyFile", @@ -232,8 +232,8 @@ options timeout:1 }, }, }, - "should create sandbox shm when hostIpc is false": { - hostIpc: false, + "should create sandbox shm when ipc namespace mode is not NODE": { + ipcMode: runtime.NamespaceMode_POD, expectedCalls: []ostesting.CalledDetail{ { Name: "CopyFile", @@ -267,7 +267,7 @@ options timeout:1 Linux: &runtime.LinuxPodSandboxConfig{ SecurityContext: &runtime.LinuxSandboxSecurityContext{ NamespaceOptions: &runtime.NamespaceOption{ - HostIpc: test.hostIpc, + Ipc: test.ipcMode, }, }, }, @@ -402,9 +402,9 @@ func TestTypeurlMarshalUnmarshalSandboxMeta(t *testing.T) { configChange: func(c *runtime.PodSandboxConfig) { c.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ NamespaceOptions: &runtime.NamespaceOption{ - HostNetwork: true, - HostPid: true, - HostIpc: true, + Network: runtime.NamespaceMode_NODE, + Pid: runtime.NamespaceMode_NODE, + Ipc: runtime.NamespaceMode_NODE, }, SupplementalGroups: []int64{1111, 2222}, } diff --git a/pkg/server/sandbox_status.go b/pkg/server/sandbox_status.go index d8b9307a2..aba1b07e3 100644 --- a/pkg/server/sandbox_status.go +++ b/pkg/server/sandbox_status.go @@ -24,7 +24,7 @@ import ( "github.com/containerd/containerd/errdefs" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/net/context" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox" ) @@ -57,8 +57,8 @@ func (c *criContainerdService) PodSandboxStatus(ctx context.Context, r *runtime. func (c *criContainerdService) getIP(sandbox sandboxstore.Sandbox) string { config := sandbox.Config - if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetHostNetwork() { - // For sandboxes using the host network we are not + if config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE { + // For sandboxes using the node network we are not // responsible for reporting the IP. return "" } @@ -88,9 +88,9 @@ func toCRISandboxStatus(meta sandboxstore.Metadata, status sandboxstore.Status, Linux: &runtime.LinuxPodSandboxStatus{ Namespaces: &runtime.Namespace{ Options: &runtime.NamespaceOption{ - HostNetwork: nsOpts.GetHostNetwork(), - HostPid: nsOpts.GetHostPid(), - HostIpc: nsOpts.GetHostIpc(), + Network: nsOpts.GetNetwork(), + Pid: nsOpts.GetPid(), + Ipc: nsOpts.GetIpc(), }, }, }, diff --git a/pkg/server/sandbox_status_test.go b/pkg/server/sandbox_status_test.go index c857d5dc4..43fa56e90 100644 --- a/pkg/server/sandbox_status_test.go +++ b/pkg/server/sandbox_status_test.go @@ -21,7 +21,7 @@ import ( "time" "github.com/stretchr/testify/assert" - "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" + runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" sandboxstore "github.com/containerd/cri-containerd/pkg/store/sandbox" ) @@ -42,9 +42,9 @@ func TestPodSandboxStatus(t *testing.T) { Linux: &runtime.LinuxPodSandboxConfig{ SecurityContext: &runtime.LinuxSandboxSecurityContext{ NamespaceOptions: &runtime.NamespaceOption{ - HostNetwork: true, - HostPid: false, - HostIpc: true, + Network: runtime.NamespaceMode_NODE, + Pid: runtime.NamespaceMode_CONTAINER, + Ipc: runtime.NamespaceMode_POD, }, }, }, @@ -65,9 +65,9 @@ func TestPodSandboxStatus(t *testing.T) { Linux: &runtime.LinuxPodSandboxStatus{ Namespaces: &runtime.Namespace{ Options: &runtime.NamespaceOption{ - HostNetwork: true, - HostPid: false, - HostIpc: true, + Network: runtime.NamespaceMode_NODE, + Pid: runtime.NamespaceMode_CONTAINER, + Ipc: runtime.NamespaceMode_POD, }, }, },