Use new namespace mode and support shared pid namespace.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-02-08 00:18:31 +00:00
parent 605b4a7b6a
commit 46fc92f65f
9 changed files with 87 additions and 63 deletions

View File

@ -104,7 +104,7 @@ func WithHostNetwork(p *runtime.PodSandboxConfig) {
}
if p.Linux.SecurityContext.NamespaceOptions == nil {
p.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{
HostNetwork: true,
Network: runtime.NamespaceMode_NODE,
}
}
}

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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)]

View File

@ -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
}

View File

@ -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
}

View File

@ -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},
}

View File

@ -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(),
},
},
},

View File

@ -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,
},
},
},