浏览代码

Merge pull request #30657 from madhanrm/ns1

Support --net=container:<NameOrID> for windows (Shared Pod Network)
Alexander Morozov 8 年之前
父节点
当前提交
9358189fa3

+ 41 - 3
api/types/container/host_config.go

@@ -10,9 +10,6 @@ import (
 	"github.com/docker/go-units"
 )
 
-// NetworkMode represents the container network stack.
-type NetworkMode string
-
 // Isolation represents the isolation technology of a container. The supported
 // values are platform specific
 type Isolation string
@@ -66,6 +63,47 @@ func (n IpcMode) Container() string {
 	return ""
 }
 
+// NetworkMode represents the container network stack.
+type NetworkMode string
+
+// IsNone indicates whether container isn't using a network stack.
+func (n NetworkMode) IsNone() bool {
+	return n == "none"
+}
+
+// IsDefault indicates whether container uses the default network stack.
+func (n NetworkMode) IsDefault() bool {
+	return n == "default"
+}
+
+// IsPrivate indicates whether container uses its private network stack.
+func (n NetworkMode) IsPrivate() bool {
+	return !(n.IsHost() || n.IsContainer())
+}
+
+// IsContainer indicates whether container uses a container network stack.
+func (n NetworkMode) IsContainer() bool {
+	parts := strings.SplitN(string(n), ":", 2)
+	return len(parts) > 1 && parts[0] == "container"
+}
+
+// ConnectedContainer is the id of the container which network this container is connected to.
+func (n NetworkMode) ConnectedContainer() string {
+	parts := strings.SplitN(string(n), ":", 2)
+	if len(parts) > 1 {
+		return parts[1]
+	}
+	return ""
+}
+
+//UserDefined indicates user-created network
+func (n NetworkMode) UserDefined() string {
+	if n.IsUserDefined() {
+		return string(n)
+	}
+	return ""
+}
+
 // UsernsMode represents userns mode in the container.
 type UsernsMode string
 

+ 0 - 40
api/types/container/hostconfig_unix.go

@@ -2,23 +2,11 @@
 
 package container
 
-import "strings"
-
 // IsValid indicates if an isolation technology is valid
 func (i Isolation) IsValid() bool {
 	return i.IsDefault()
 }
 
-// IsPrivate indicates whether container uses its private network stack.
-func (n NetworkMode) IsPrivate() bool {
-	return !(n.IsHost() || n.IsContainer())
-}
-
-// IsDefault indicates whether container uses the default network stack.
-func (n NetworkMode) IsDefault() bool {
-	return n == "default"
-}
-
 // NetworkName returns the name of the network stack.
 func (n NetworkMode) NetworkName() string {
 	if n.IsBridge() {
@@ -47,35 +35,7 @@ func (n NetworkMode) IsHost() bool {
 	return n == "host"
 }
 
-// IsContainer indicates whether container uses a container network stack.
-func (n NetworkMode) IsContainer() bool {
-	parts := strings.SplitN(string(n), ":", 2)
-	return len(parts) > 1 && parts[0] == "container"
-}
-
-// IsNone indicates whether container isn't using a network stack.
-func (n NetworkMode) IsNone() bool {
-	return n == "none"
-}
-
-// ConnectedContainer is the id of the container which network this container is connected to.
-func (n NetworkMode) ConnectedContainer() string {
-	parts := strings.SplitN(string(n), ":", 2)
-	if len(parts) > 1 {
-		return parts[1]
-	}
-	return ""
-}
-
 // IsUserDefined indicates user-created network
 func (n NetworkMode) IsUserDefined() bool {
 	return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()
 }
-
-//UserDefined indicates user-created network
-func (n NetworkMode) UserDefined() string {
-	if n.IsUserDefined() {
-		return string(n)
-	}
-	return ""
-}

+ 3 - 36
api/types/container/hostconfig_windows.go

@@ -4,22 +4,6 @@ import (
 	"strings"
 )
 
-// IsDefault indicates whether container uses the default network stack.
-func (n NetworkMode) IsDefault() bool {
-	return n == "default"
-}
-
-// IsNone indicates whether container isn't using a network stack.
-func (n NetworkMode) IsNone() bool {
-	return n == "none"
-}
-
-// IsContainer indicates whether container uses a container network stack.
-// Returns false as windows doesn't support this mode
-func (n NetworkMode) IsContainer() bool {
-	return false
-}
-
 // IsBridge indicates whether container uses the bridge network stack
 // in windows it is given the name NAT
 func (n NetworkMode) IsBridge() bool {
@@ -32,20 +16,9 @@ func (n NetworkMode) IsHost() bool {
 	return false
 }
 
-// IsPrivate indicates whether container uses its private network stack.
-func (n NetworkMode) IsPrivate() bool {
-	return !(n.IsHost() || n.IsContainer())
-}
-
-// ConnectedContainer is the id of the container which network this container is connected to.
-// Returns blank string on windows
-func (n NetworkMode) ConnectedContainer() string {
-	return ""
-}
-
 // IsUserDefined indicates user-created network
 func (n NetworkMode) IsUserDefined() bool {
-	return !n.IsDefault() && !n.IsNone() && !n.IsBridge()
+	return !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()
 }
 
 // IsHyperV indicates the use of a Hyper-V partition for isolation
@@ -71,17 +44,11 @@ func (n NetworkMode) NetworkName() string {
 		return "nat"
 	} else if n.IsNone() {
 		return "none"
+	} else if n.IsContainer() {
+		return "container"
 	} else if n.IsUserDefined() {
 		return n.UserDefined()
 	}
 
 	return ""
 }
-
-//UserDefined indicates user-created network
-func (n NetworkMode) UserDefined() string {
-	if n.IsUserDefined() {
-		return string(n)
-	}
-	return ""
-}

+ 1 - 0
container/container_windows.go

@@ -16,6 +16,7 @@ type Container struct {
 	CommonContainer
 
 	// Fields below here are platform specific.
+	NetworkSharedContainerID string
 }
 
 // ExitStatus provides exit reasons for a container.

+ 5 - 4
daemon/container_operations.go

@@ -505,12 +505,13 @@ func (daemon *Daemon) allocateNetwork(container *container.Container) error {
 		logrus.Errorf("failed to cleanup up stale network sandbox for container %s", container.ID)
 	}
 
+	if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
+		return nil
+	}
+
 	updateSettings := false
-	if len(container.NetworkSettings.Networks) == 0 {
-		if container.Config.NetworkDisabled || container.HostConfig.NetworkMode.IsContainer() {
-			return nil
-		}
 
+	if len(container.NetworkSettings.Networks) == 0 {
 		daemon.updateContainerNetworkSettings(container, nil)
 		updateSettings = true
 	}

+ 1 - 0
daemon/container_operations_windows.go

@@ -56,4 +56,5 @@ func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]
 }
 
 func initializeNetworkingPaths(container *container.Container, nc *container.Container) {
+	container.NetworkSharedContainerID = nc.ID
 }

+ 10 - 7
daemon/start_windows.go

@@ -157,14 +157,17 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain
 	createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore})
 	createOptions = append(createOptions, hvOpts)
 	createOptions = append(createOptions, layerOpts)
-	if epList != nil {
-		createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{
-			Endpoints:                epList,
-			AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery,
-			DNSSearchList:            dnsSearch,
-		})
-	}
 
+	var networkSharedContainerID string
+	if container.HostConfig.NetworkMode.IsContainer() {
+		networkSharedContainerID = container.NetworkSharedContainerID
+	}
+	createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{
+		Endpoints:                epList,
+		AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery,
+		DNSSearchList:            dnsSearch,
+		NetworkSharedContainerID: networkSharedContainerID,
+	})
 	return createOptions, nil
 }
 

+ 1 - 0
libcontainerd/client_windows.go

@@ -170,6 +170,7 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir
 			if n.DNSSearchList != nil {
 				configuration.DNSSearchList = strings.Join(n.DNSSearchList, ",")
 			}
+			configuration.NetworkSharedContainerName = n.NetworkSharedContainerID
 			continue
 		}
 		if c, ok := option.(*CredentialsOption); ok {

+ 1 - 0
libcontainerd/types_windows.go

@@ -60,6 +60,7 @@ type NetworkEndpointsOption struct {
 	Endpoints                []string
 	AllowUnqualifiedDNSQuery bool
 	DNSSearchList            []string
+	NetworkSharedContainerID string
 }
 
 // CredentialsOption is a CreateOption that indicates the credentials from

+ 46 - 0
runconfig/hostconfig.go

@@ -2,7 +2,9 @@ package runconfig
 
 import (
 	"encoding/json"
+	"fmt"
 	"io"
+	"strings"
 
 	"github.com/docker/docker/api/types/container"
 )
@@ -32,3 +34,47 @@ func SetDefaultNetModeIfBlank(hc *container.HostConfig) {
 		}
 	}
 }
+
+// ValidateNetContainerMode ensures that the various combinations of requested
+// network settings wrt container mode are valid.
+func ValidateNetContainerMode(c *container.Config, hc *container.HostConfig) error {
+	// We may not be passed a host config, such as in the case of docker commit
+	if hc == nil {
+		return nil
+	}
+	parts := strings.Split(string(hc.NetworkMode), ":")
+	if parts[0] == "container" {
+		if len(parts) < 2 || parts[1] == "" {
+			return fmt.Errorf("--net: invalid net mode: invalid container format container:<name|id>")
+		}
+	}
+
+	if hc.NetworkMode.IsContainer() && c.Hostname != "" {
+		return ErrConflictNetworkHostname
+	}
+
+	if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
+		return ErrConflictContainerNetworkAndLinks
+	}
+
+	if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
+		return ErrConflictNetworkAndDNS
+	}
+
+	if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
+		return ErrConflictNetworkHosts
+	}
+
+	if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
+		return ErrConflictContainerNetworkAndMac
+	}
+
+	if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts == true) {
+		return ErrConflictNetworkPublishPorts
+	}
+
+	if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
+		return ErrConflictNetworkExposePorts
+	}
+	return nil
+}

+ 3 - 32
runconfig/hostconfig_unix.go

@@ -5,7 +5,6 @@ package runconfig
 import (
 	"fmt"
 	"runtime"
-	"strings"
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/pkg/sysinfo"
@@ -30,15 +29,10 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
 	if hc == nil {
 		return nil
 	}
-	parts := strings.Split(string(hc.NetworkMode), ":")
-	if parts[0] == "container" {
-		if len(parts) < 2 || parts[1] == "" {
-			return fmt.Errorf("--net: invalid net mode: invalid container format container:<name|id>")
-		}
-	}
 
-	if hc.NetworkMode.IsContainer() && c.Hostname != "" {
-		return ErrConflictNetworkHostname
+	err := ValidateNetContainerMode(c, hc)
+	if err != nil {
+		return err
 	}
 
 	if hc.UTSMode.IsHost() && c.Hostname != "" {
@@ -49,29 +43,6 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
 		return ErrConflictHostNetworkAndLinks
 	}
 
-	if hc.NetworkMode.IsContainer() && len(hc.Links) > 0 {
-		return ErrConflictContainerNetworkAndLinks
-	}
-
-	if hc.NetworkMode.IsContainer() && len(hc.DNS) > 0 {
-		return ErrConflictNetworkAndDNS
-	}
-
-	if hc.NetworkMode.IsContainer() && len(hc.ExtraHosts) > 0 {
-		return ErrConflictNetworkHosts
-	}
-
-	if (hc.NetworkMode.IsContainer() || hc.NetworkMode.IsHost()) && c.MacAddress != "" {
-		return ErrConflictContainerNetworkAndMac
-	}
-
-	if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts == true) {
-		return ErrConflictNetworkPublishPorts
-	}
-
-	if hc.NetworkMode.IsContainer() && len(c.ExposedPorts) > 0 {
-		return ErrConflictNetworkExposePorts
-	}
 	return nil
 }
 

+ 9 - 4
runconfig/hostconfig_windows.go

@@ -2,7 +2,6 @@ package runconfig
 
 import (
 	"fmt"
-	"strings"
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/pkg/sysinfo"
@@ -25,10 +24,16 @@ func ValidateNetMode(c *container.Config, hc *container.HostConfig) error {
 	if hc == nil {
 		return nil
 	}
-	parts := strings.Split(string(hc.NetworkMode), ":")
-	if len(parts) > 1 {
-		return fmt.Errorf("invalid --net: %s", hc.NetworkMode)
+
+	err := ValidateNetContainerMode(c, hc)
+	if err != nil {
+		return err
+	}
+
+	if hc.NetworkMode.IsContainer() && hc.Isolation.IsHyperV() {
+		return fmt.Errorf("net mode --net=container:<NameOrId> unsupported for hyperv isolation")
 	}
+
 	return nil
 }