Browse Source

Merge pull request #17613 from Microsoft/10662-isolationexecopt

Windows: Add default isolation exec driver option
Sebastiaan van Stijn 9 năm trước cách đây
mục cha
commit
d4c4557b1a

+ 1 - 1
daemon/container_windows.go

@@ -136,7 +136,7 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
 		LayerFolder: layerFolder,
 		LayerPaths:  layerPaths,
 		Hostname:    c.Config.Hostname,
-		Isolated:    c.hostConfig.Isolation.IsHyperV(),
+		Isolation:   c.hostConfig.Isolation,
 	}
 
 	return nil

+ 9 - 6
daemon/execdriver/driver_windows.go

@@ -1,6 +1,9 @@
 package execdriver
 
-import "github.com/docker/docker/pkg/nat"
+import (
+	"github.com/docker/docker/pkg/nat"
+	"github.com/docker/docker/runconfig"
+)
 
 // Mount contains information for a mount operation.
 type Mount struct {
@@ -40,11 +43,11 @@ type Command struct {
 
 	// Fields below here are platform specific
 
-	FirstStart  bool     `json:"first_start"`  // Optimisation for first boot of Windows
-	Hostname    string   `json:"hostname"`     // Windows sets the hostname in the execdriver
-	LayerFolder string   `json:"layer_folder"` // Layer folder for a command
-	LayerPaths  []string `json:"layer_paths"`  // Layer paths for a command
-	Isolated    bool     `json:"isolated"`     // True if a Hyper-V container
+	FirstStart  bool                     `json:"first_start"`  // Optimisation for first boot of Windows
+	Hostname    string                   `json:"hostname"`     // Windows sets the hostname in the execdriver
+	LayerFolder string                   `json:"layer_folder"` // Layer folder for a command
+	LayerPaths  []string                 `json:"layer_paths"`  // Layer paths for a command
+	Isolation   runconfig.IsolationLevel `json:"isolation"`    // Isolation level for the container
 }
 
 // ExitStatus provides exit reasons for a container.

+ 10 - 5
daemon/execdriver/windows/info.go

@@ -2,18 +2,23 @@
 
 package windows
 
-import "github.com/docker/docker/daemon/execdriver"
+import (
+	"github.com/docker/docker/daemon/execdriver"
+	"github.com/docker/docker/runconfig"
+)
 
 type info struct {
-	ID     string
-	driver *Driver
+	ID        string
+	driver    *Driver
+	isolation runconfig.IsolationLevel
 }
 
 // Info implements the exec driver Driver interface.
 func (d *Driver) Info(id string) execdriver.Info {
 	return &info{
-		ID:     id,
-		driver: d,
+		ID:        id,
+		driver:    d,
+		isolation: defaultIsolation,
 	}
 }
 

+ 10 - 2
daemon/execdriver/windows/run.go

@@ -110,10 +110,18 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
 		LayerFolderPath:         c.LayerFolder,
 		ProcessorWeight:         c.Resources.CPUShares,
 		HostName:                c.Hostname,
-		HvPartition:             c.Isolated,
 	}
 
-	if c.Isolated {
+	// Work out the isolation (whether it is a hypervisor partition)
+	if c.Isolation.IsDefault() {
+		// Not specified by caller. Take daemon default
+		cu.HvPartition = defaultIsolation.IsHyperV()
+	} else {
+		// Take value specified by caller
+		cu.HvPartition = c.Isolation.IsHyperV()
+	}
+
+	if cu.HvPartition {
 		cu.SandboxPath = filepath.Dir(c.LayerFolder)
 	} else {
 		cu.VolumePath = c.Rootfs

+ 16 - 1
daemon/execdriver/windows/windows.go

@@ -11,6 +11,7 @@ import (
 	"github.com/docker/docker/daemon/execdriver"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/runconfig"
 )
 
 // This is a daemon development variable only and should not be
@@ -21,6 +22,12 @@ var dummyMode bool
 // This allows the daemon to force kill (HCS terminate) rather than shutdown
 var forceKill bool
 
+// defaultIsolation allows users to specify a default isolation mode for
+// when running a container on Windows. For example docker daemon -D
+// --exec-opt isolation=hyperv will cause Windows to always run containers
+// as Hyper-V containers unless otherwise specified.
+var defaultIsolation runconfig.IsolationLevel = "process"
+
 // Define name and version for windows
 var (
 	DriverName = "Windows 1854"
@@ -42,7 +49,7 @@ type Driver struct {
 
 // Name implements the exec driver Driver interface.
 func (d *Driver) Name() string {
-	return fmt.Sprintf("%s %s", DriverName, Version)
+	return fmt.Sprintf("\n Name: %s\n Build: %s \n Default Isolation: %s", DriverName, Version, defaultIsolation)
 }
 
 // NewDriver returns a new windows driver, called from NewDriver of execdriver.
@@ -70,6 +77,14 @@ func NewDriver(root, initPath string, options []string) (*Driver, error) {
 				logrus.Warn("Using force kill mode in Windows exec driver. This is for testing purposes only.")
 			}
 
+		case "isolation":
+			if !runconfig.IsolationLevel(val).IsValid() {
+				return nil, fmt.Errorf("Unrecognised exec driver option 'isolation':'%s'", val)
+			}
+			if runconfig.IsolationLevel(val).IsHyperV() {
+				defaultIsolation = "hyperv"
+			}
+			logrus.Infof("Windows default isolation level: '%s'", val)
 		default:
 			return nil, fmt.Errorf("Unrecognised exec driver option %s\n", key)
 		}

+ 1 - 1
docs/reference/api/docker_remote_api_v1.22.md

@@ -116,7 +116,7 @@ Query Parameters:
   -   `exited=<int>`; -- containers with exit code of  `<int>` ;
   -   `status=`(`created`|`restarting`|`running`|`paused`|`exited`)
   -   `label=key` or `label="key=value"` of a container label
-  -   `isolation=`(`default`|`hyperv`)   (Windows daemon only)
+  -   `isolation=`(`default`|`process`|`hyperv`)   (Windows daemon only)
 
 Status Codes:
 

+ 1 - 1
docs/reference/commandline/ps.md

@@ -51,7 +51,7 @@ The currently supported filters are:
 * exited (int - the code of exited containers. Only useful with `--all`)
 * status (created|restarting|running|paused|exited)
 * ancestor (`<image-name>[:<tag>]`,  `<image id>` or `<image@digest>`) - filters containers that were created from the given image or a descendant.
-* isolation (default|hyperv)   (Windows daemon only)
+* isolation (default|process|hyperv)   (Windows daemon only)
 
 
 #### Label

+ 9 - 6
runconfig/hostconfig_windows.go

@@ -10,15 +10,19 @@ func (n NetworkMode) IsDefault() bool {
 	return n == "default"
 }
 
-// IsHyperV indicates the use of Hyper-V Containers for isolation (as opposed
-// to Windows Server Containers
+// IsHyperV indicates the use of a Hyper-V partition for isolation
 func (i IsolationLevel) IsHyperV() bool {
 	return strings.ToLower(string(i)) == "hyperv"
 }
 
+// IsProcess indicates the use of process isolation
+func (i IsolationLevel) IsProcess() bool {
+	return strings.ToLower(string(i)) == "process"
+}
+
 // IsValid indicates is an isolation level is valid
 func (i IsolationLevel) IsValid() bool {
-	return i.IsDefault() || i.IsHyperV()
+	return i.IsDefault() || i.IsHyperV() || i.IsProcess()
 }
 
 // DefaultDaemonNetworkMode returns the default network stack the daemon should
@@ -67,15 +71,14 @@ func ValidateNetMode(c *Config, hc *HostConfig) error {
 
 // ValidateIsolationLevel performs platform specific validation of the
 // isolation level in the hostconfig structure. Windows supports 'default' (or
-// blank), and 'hyperv'. These refer to Windows Server Containers and
-// Hyper-V Containers respectively.
+// blank), 'process', or 'hyperv'.
 func ValidateIsolationLevel(hc *HostConfig) error {
 	// We may not be passed a host config, such as in the case of docker commit
 	if hc == nil {
 		return nil
 	}
 	if !hc.Isolation.IsValid() {
-		return fmt.Errorf("invalid --isolation: %q. Windows supports 'default' (Windows Server Container) or 'hyperv' (Hyper-V Container)", hc.Isolation)
+		return fmt.Errorf("invalid --isolation: %q. Windows supports 'default', 'process', or 'hyperv'", hc.Isolation)
 	}
 	return nil
 }