Browse Source

Merge pull request #35621 from kolyshkin/ipc-private

daemon: use 'private' ipc mode by default
Sebastiaan van Stijn 6 years ago
parent
commit
ca0b64ee3b

+ 6 - 3
api/server/router/container/container_routes.go

@@ -474,11 +474,14 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo
 		}
 		}
 		// Ignore KernelMemoryTCP because it was added in API 1.40.
 		// Ignore KernelMemoryTCP because it was added in API 1.40.
 		hostConfig.KernelMemoryTCP = 0
 		hostConfig.KernelMemoryTCP = 0
-	}
 
 
-	// Ignore Capabilities because it was added in API 1.40.
-	if hostConfig != nil && versions.LessThan(version, "1.40") {
+		// Ignore Capabilities because it was added in API 1.40.
 		hostConfig.Capabilities = nil
 		hostConfig.Capabilities = nil
+
+		// Older clients (API < 1.40) expects the default to be shareable, make them happy
+		if hostConfig.IpcMode.IsEmpty() {
+			hostConfig.IpcMode = container.IpcMode("shareable")
+		}
 	}
 	}
 
 
 	ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
 	ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{

+ 1 - 1
daemon/config/config_unix.go

@@ -12,7 +12,7 @@ import (
 
 
 const (
 const (
 	// DefaultIpcMode is default for container's IpcMode, if not set otherwise
 	// DefaultIpcMode is default for container's IpcMode, if not set otherwise
-	DefaultIpcMode = "shareable" // TODO: change to private
+	DefaultIpcMode = "private"
 )
 )
 
 
 // Config defines the configuration of a docker daemon.
 // Config defines the configuration of a docker daemon.

+ 1 - 1
daemon/container_operations_unix.go

@@ -72,7 +72,7 @@ func (daemon *Daemon) getIpcContainer(id string) (*container.Container, error) {
 	// Check the container ipc is shareable
 	// Check the container ipc is shareable
 	if st, err := os.Stat(container.ShmPath); err != nil || !st.IsDir() {
 	if st, err := os.Stat(container.ShmPath); err != nil || !st.IsDir() {
 		if err == nil || os.IsNotExist(err) {
 		if err == nil || os.IsNotExist(err) {
-			return nil, errors.New(errMsg + ": non-shareable IPC")
+			return nil, errors.New(errMsg + ": non-shareable IPC (hint: use IpcMode:shareable for the donor container)")
 		}
 		}
 		// stat() failed?
 		// stat() failed?
 		return nil, errors.Wrap(err, errMsg+": unexpected error from stat "+container.ShmPath)
 		return nil, errors.Wrap(err, errMsg+": unexpected error from stat "+container.ShmPath)

+ 3 - 0
docs/api/version-history.md

@@ -61,6 +61,9 @@ keywords: "API, Docker, rcli, REST, documentation"
 * `POST /containers/create` now takes a `Capabilities` field to set the list of
 * `POST /containers/create` now takes a `Capabilities` field to set the list of
   kernel capabilities to be available for the container (this overrides the default
   kernel capabilities to be available for the container (this overrides the default
   set).
   set).
+* `POST /containers/create` on Linux now creates a container with `HostConfig.IpcMode=private`
+  by default, if IpcMode is not explicitly specified. The per-daemon default can be changed
+  back to `shareable` by using `DefaultIpcMode` daemon configuration parameter.
 * `POST /containers/{id}/update` now accepts a `PidsLimit` field to tune a container's
 * `POST /containers/{id}/update` now accepts a `PidsLimit` field to tune a container's
   PID limit. Set `0` or `-1` for unlimited. Leave `null` to not change the current value.
   PID limit. Set `0` or `-1` for unlimited. Leave `null` to not change the current value.
 
 

+ 28 - 0
integration/container/ipcmode_linux_test.go

@@ -11,8 +11,11 @@ import (
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/versions"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/internal/test/daemon"
 	"github.com/docker/docker/internal/test/daemon"
+	"github.com/docker/docker/internal/test/request"
 	"gotest.tools/assert"
 	"gotest.tools/assert"
 	is "gotest.tools/assert/cmp"
 	is "gotest.tools/assert/cmp"
 	"gotest.tools/fs"
 	"gotest.tools/fs"
@@ -292,3 +295,28 @@ func TestDaemonIpcModeShareableFromConfig(t *testing.T) {
 
 
 	testDaemonIpcFromConfig(t, "shareable", true)
 	testDaemonIpcFromConfig(t, "shareable", true)
 }
 }
+
+// TestIpcModeOlderClient checks that older client gets shareable IPC mode
+// by default, even when the daemon default is private.
+func TestIpcModeOlderClient(t *testing.T) {
+	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "requires a daemon with DefaultIpcMode: private")
+	t.Parallel()
+
+	ctx := context.Background()
+
+	// pre-check: default ipc mode in daemon is private
+	c := testEnv.APIClient()
+	cID := container.Create(t, ctx, c, container.WithAutoRemove)
+
+	inspect, err := c.ContainerInspect(ctx, cID)
+	assert.NilError(t, err)
+	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "private"))
+
+	// main check: using older client creates "shareable" container
+	c = request.NewAPIClient(t, client.WithVersion("1.39"))
+	cID = container.Create(t, ctx, c, container.WithAutoRemove)
+
+	inspect, err = c.ContainerInspect(ctx, cID)
+	assert.NilError(t, err)
+	assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "shareable"))
+}