Quellcode durchsuchen

Merge pull request #42089 from cpuguy83/windows_containerd

Allow switching Windows runtimes.
Sebastiaan van Stijn vor 3 Jahren
Ursprung
Commit
ed83e2e20e

+ 2 - 0
cmd/dockerd/config.go

@@ -99,6 +99,8 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
 	flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", daemon.ContainersNamespace, "Containerd namespace to use")
 	flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", daemon.ContainersNamespace, "Containerd namespace to use")
 	flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", containerd.PluginNamespace, "Containerd namespace to use for plugins")
 	flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", containerd.PluginNamespace, "Containerd namespace to use for plugins")
 
 
+	flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers")
+
 	return nil
 	return nil
 }
 }
 
 

+ 0 - 2
cmd/dockerd/config_common_unix.go

@@ -60,6 +60,4 @@ func installUnixConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
 	flags.BoolVar(&conf.BridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication")
 	flags.BoolVar(&conf.BridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication")
 	flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports")
 	flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports")
 	flags.Var(opts.NewNamedRuntimeOpt("runtimes", &conf.Runtimes, config.StockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime")
 	flags.Var(opts.NewNamedRuntimeOpt("runtimes", &conf.Runtimes, config.StockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime")
-	flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers")
-
 }
 }

+ 12 - 3
daemon/config/config.go

@@ -48,9 +48,7 @@ const (
 	// DefaultRuntimeBinary is the default runtime to be used by
 	// DefaultRuntimeBinary is the default runtime to be used by
 	// containerd if none is specified
 	// containerd if none is specified
 	DefaultRuntimeBinary = "runc"
 	DefaultRuntimeBinary = "runc"
-	// StockRuntimeName is the reserved name/alias used to represent the
-	// OCI runtime being shipped with the docker daemon package.
-	StockRuntimeName = "runc"
+
 	// LinuxV1RuntimeName is the runtime used to specify the containerd v1 shim with the runc binary
 	// LinuxV1RuntimeName is the runtime used to specify the containerd v1 shim with the runc binary
 	// Note this is different than io.containerd.runc.v1 which would be the v1 shim using the v2 shim API.
 	// Note this is different than io.containerd.runc.v1 which would be the v1 shim using the v2 shim API.
 	// This is specifically for the v1 shim using the v1 shim API.
 	// This is specifically for the v1 shim using the v1 shim API.
@@ -273,6 +271,8 @@ type CommonConfig struct {
 
 
 	ContainerdNamespace       string `json:"containerd-namespace,omitempty"`
 	ContainerdNamespace       string `json:"containerd-namespace,omitempty"`
 	ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"`
 	ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"`
+
+	DefaultRuntime string `json:"default-runtime,omitempty"`
 }
 }
 
 
 // IsValueSet returns true if a configuration value
 // IsValueSet returns true if a configuration value
@@ -636,3 +636,12 @@ func ModifiedDiscoverySettings(config *Config, backendType, advertise string, cl
 
 
 	return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
 	return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
 }
 }
+
+// GetDefaultRuntimeName returns the current default runtime
+func (conf *Config) GetDefaultRuntimeName() string {
+	conf.Lock()
+	rt := conf.DefaultRuntime
+	conf.Unlock()
+
+	return rt
+}

+ 4 - 10
daemon/config/config_linux.go

@@ -19,6 +19,10 @@ const (
 
 
 	// DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1.
 	// DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1.
 	DefaultCgroupV1NamespaceMode = containertypes.CgroupnsModeHost
 	DefaultCgroupV1NamespaceMode = containertypes.CgroupnsModeHost
+
+	// StockRuntimeName is the reserved name/alias used to represent the
+	// OCI runtime being shipped with the docker daemon package.
+	StockRuntimeName = "runc"
 )
 )
 
 
 // BridgeConfig stores all the bridge driver specific
 // BridgeConfig stores all the bridge driver specific
@@ -51,7 +55,6 @@ type Config struct {
 
 
 	// Fields below here are platform specific.
 	// Fields below here are platform specific.
 	Runtimes             map[string]types.Runtime `json:"runtimes,omitempty"`
 	Runtimes             map[string]types.Runtime `json:"runtimes,omitempty"`
-	DefaultRuntime       string                   `json:"default-runtime,omitempty"`
 	DefaultInitBinary    string                   `json:"default-init,omitempty"`
 	DefaultInitBinary    string                   `json:"default-init,omitempty"`
 	CgroupParent         string                   `json:"cgroup-parent,omitempty"`
 	CgroupParent         string                   `json:"cgroup-parent,omitempty"`
 	EnableSelinuxSupport bool                     `json:"selinux-enabled,omitempty"`
 	EnableSelinuxSupport bool                     `json:"selinux-enabled,omitempty"`
@@ -83,15 +86,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime {
 	return nil
 	return nil
 }
 }
 
 
-// GetDefaultRuntimeName returns the current default runtime
-func (conf *Config) GetDefaultRuntimeName() string {
-	conf.Lock()
-	rt := conf.DefaultRuntime
-	conf.Unlock()
-
-	return rt
-}
-
 // GetAllRuntimes returns a copy of the runtimes map
 // GetAllRuntimes returns a copy of the runtimes map
 func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
 func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
 	conf.Lock()
 	conf.Lock()

+ 3 - 1
daemon/config/config_linux_test.go

@@ -150,7 +150,9 @@ func TestUnixValidateConfigurationErrors(t *testing.T) {
 				Runtimes: map[string]types.Runtime{
 				Runtimes: map[string]types.Runtime{
 					"foo": {},
 					"foo": {},
 				},
 				},
-				DefaultRuntime: "bar",
+				CommonConfig: CommonConfig{
+					DefaultRuntime: "bar",
+				},
 			},
 			},
 		},
 		},
 	}
 	}

+ 6 - 5
daemon/config/config_windows.go

@@ -4,6 +4,12 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 )
 )
 
 
+const (
+	// This is used by the `default-runtime` flag in dockerd as the default value.
+	// On windows we'd prefer to keep this empty so the value is auto-detected based on other options.
+	StockRuntimeName = ""
+)
+
 // BridgeConfig stores all the bridge driver specific
 // BridgeConfig stores all the bridge driver specific
 // configuration.
 // configuration.
 type BridgeConfig struct {
 type BridgeConfig struct {
@@ -26,11 +32,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime {
 	return nil
 	return nil
 }
 }
 
 
-// GetDefaultRuntimeName returns the current default runtime
-func (conf *Config) GetDefaultRuntimeName() string {
-	return StockRuntimeName
-}
-
 // GetAllRuntimes returns a copy of the runtimes map
 // GetAllRuntimes returns a copy of the runtimes map
 func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
 func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
 	return map[string]types.Runtime{}
 	return map[string]types.Runtime{}

+ 2 - 5
daemon/daemon.go

@@ -42,7 +42,6 @@ import (
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/layer"
-	"github.com/docker/docker/libcontainerd"
 	libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
 	libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
 	"github.com/docker/docker/libnetwork"
 	"github.com/docker/docker/libnetwork"
 	"github.com/docker/docker/libnetwork/cluster"
 	"github.com/docker/docker/libnetwork/cluster"
@@ -922,6 +921,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
 		grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
 		grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
 		grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)),
 		grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)),
 	}
 	}
+
 	if config.ContainerdAddr != "" {
 	if config.ContainerdAddr != "" {
 		d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
 		d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
 		if err != nil {
 		if err != nil {
@@ -932,8 +932,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
 	createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
 	createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
 		var pluginCli *containerd.Client
 		var pluginCli *containerd.Client
 
 
-		// Windows is not currently using containerd, keep the
-		// client as nil
 		if config.ContainerdAddr != "" {
 		if config.ContainerdAddr != "" {
 			pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
 			pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
 			if err != nil {
 			if err != nil {
@@ -1113,8 +1111,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
 
 
 	go d.execCommandGC()
 	go d.execCommandGC()
 
 
-	d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d)
-	if err != nil {
+	if err := d.initLibcontainerd(ctx); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 

+ 13 - 0
daemon/daemon_unix.go

@@ -29,6 +29,7 @@ import (
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/initlayer"
 	"github.com/docker/docker/daemon/initlayer"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
+	"github.com/docker/docker/libcontainerd/remote"
 	"github.com/docker/docker/libnetwork"
 	"github.com/docker/docker/libnetwork"
 	nwconfig "github.com/docker/docker/libnetwork/config"
 	nwconfig "github.com/docker/docker/libnetwork/config"
 	"github.com/docker/docker/libnetwork/drivers/bridge"
 	"github.com/docker/docker/libnetwork/drivers/bridge"
@@ -1736,3 +1737,15 @@ func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 func recursiveUnmount(target string) error {
 func recursiveUnmount(target string) error {
 	return mount.RecursiveUnmount(target)
 	return mount.RecursiveUnmount(target)
 }
 }
+
+func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
+	var err error
+	daemon.containerd, err = remote.NewClient(
+		ctx,
+		daemon.containerdCli,
+		filepath.Join(daemon.configStore.ExecRoot, "containerd"),
+		daemon.configStore.ContainerdNamespace,
+		daemon,
+	)
+	return err
+}

+ 44 - 0
daemon/daemon_windows.go

@@ -14,6 +14,8 @@ import (
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/config"
+	"github.com/docker/docker/libcontainerd/local"
+	"github.com/docker/docker/libcontainerd/remote"
 	"github.com/docker/docker/libnetwork"
 	"github.com/docker/docker/libnetwork"
 	nwconfig "github.com/docker/docker/libnetwork/config"
 	nwconfig "github.com/docker/docker/libnetwork/config"
 	"github.com/docker/docker/libnetwork/datastore"
 	"github.com/docker/docker/libnetwork/datastore"
@@ -40,6 +42,9 @@ const (
 	windowsMaxCPUShares  = 10000
 	windowsMaxCPUShares  = 10000
 	windowsMinCPUPercent = 1
 	windowsMinCPUPercent = 1
 	windowsMaxCPUPercent = 100
 	windowsMaxCPUPercent = 100
+
+	windowsV1RuntimeName = "com.docker.hcsshim.v1"
+	windowsV2RuntimeName = "io.containerd.runhcs.v1"
 )
 )
 
 
 // Windows containers are much larger than Linux containers and each of them
 // Windows containers are much larger than Linux containers and each of them
@@ -649,3 +654,42 @@ func setupResolvConf(config *config.Config) {
 func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
 	return sysinfo.New()
 	return sysinfo.New()
 }
 }
+
+func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
+	var err error
+
+	rt := daemon.configStore.GetDefaultRuntimeName()
+	if rt == "" {
+		if daemon.configStore.ContainerdAddr == "" {
+			rt = windowsV1RuntimeName
+		} else {
+			rt = windowsV2RuntimeName
+		}
+	}
+
+	switch rt {
+	case windowsV1RuntimeName:
+		daemon.containerd, err = local.NewClient(
+			ctx,
+			daemon.containerdCli,
+			filepath.Join(daemon.configStore.ExecRoot, "containerd"),
+			daemon.configStore.ContainerdNamespace,
+			daemon,
+		)
+	case windowsV2RuntimeName:
+		if daemon.configStore.ContainerdAddr == "" {
+			return fmt.Errorf("cannot use the specified runtime %q without containerd", rt)
+		}
+		daemon.containerd, err = remote.NewClient(
+			ctx,
+			daemon.containerdCli,
+			filepath.Join(daemon.configStore.ExecRoot, "containerd"),
+			daemon.configStore.ContainerdNamespace,
+			daemon,
+		)
+	default:
+		return fmt.Errorf("unknown windows runtime %s", rt)
+	}
+
+	return err
+}