diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go index 73d5b81cb31b2..c53f4f3559dcc 100644 --- a/cmd/dockerd/config.go +++ b/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.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 } diff --git a/cmd/dockerd/config_common_unix.go b/cmd/dockerd/config_common_unix.go index 5993674d29f6e..dfbc3e2e3d0e3 100644 --- a/cmd/dockerd/config_common_unix.go +++ b/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.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.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers") - } diff --git a/daemon/config/config.go b/daemon/config/config.go index ef5320ccec379..bcf803edd0e76 100644 --- a/daemon/config/config.go +++ b/daemon/config/config.go @@ -48,9 +48,7 @@ const ( // DefaultRuntimeBinary is the default runtime to be used by // containerd if none is specified 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 // 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. @@ -273,6 +271,8 @@ type CommonConfig struct { ContainerdNamespace string `json:"containerd-namespace,omitempty"` ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"` + + DefaultRuntime string `json:"default-runtime,omitempty"` } // 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) } + +// GetDefaultRuntimeName returns the current default runtime +func (conf *Config) GetDefaultRuntimeName() string { + conf.Lock() + rt := conf.DefaultRuntime + conf.Unlock() + + return rt +} diff --git a/daemon/config/config_linux.go b/daemon/config/config_linux.go index 46acf0a849e4a..498e9e74fb511 100644 --- a/daemon/config/config_linux.go +++ b/daemon/config/config_linux.go @@ -19,6 +19,10 @@ const ( // DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1. 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 @@ -51,7 +55,6 @@ type Config struct { // Fields below here are platform specific. Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` - DefaultRuntime string `json:"default-runtime,omitempty"` DefaultInitBinary string `json:"default-init,omitempty"` CgroupParent string `json:"cgroup-parent,omitempty"` EnableSelinuxSupport bool `json:"selinux-enabled,omitempty"` @@ -83,15 +86,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime { 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 func (conf *Config) GetAllRuntimes() map[string]types.Runtime { conf.Lock() diff --git a/daemon/config/config_linux_test.go b/daemon/config/config_linux_test.go index 424bfc00e6ce8..cfc635567dfd4 100644 --- a/daemon/config/config_linux_test.go +++ b/daemon/config/config_linux_test.go @@ -150,7 +150,9 @@ func TestUnixValidateConfigurationErrors(t *testing.T) { Runtimes: map[string]types.Runtime{ "foo": {}, }, - DefaultRuntime: "bar", + CommonConfig: CommonConfig{ + DefaultRuntime: "bar", + }, }, }, } diff --git a/daemon/config/config_windows.go b/daemon/config/config_windows.go index eb9e71cbc4d93..29d7dbaa16c58 100644 --- a/daemon/config/config_windows.go +++ b/daemon/config/config_windows.go @@ -4,6 +4,12 @@ import ( "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 // configuration. type BridgeConfig struct { @@ -26,11 +32,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime { return nil } -// GetDefaultRuntimeName returns the current default runtime -func (conf *Config) GetDefaultRuntimeName() string { - return StockRuntimeName -} - // GetAllRuntimes returns a copy of the runtimes map func (conf *Config) GetAllRuntimes() map[string]types.Runtime { return map[string]types.Runtime{} diff --git a/daemon/daemon.go b/daemon/daemon.go index 4e75d5ee3ca87..15bfee1b7d03e 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -42,7 +42,6 @@ import ( "github.com/docker/docker/errdefs" "github.com/docker/docker/image" "github.com/docker/docker/layer" - "github.com/docker/docker/libcontainerd" libcontainerdtypes "github.com/docker/docker/libcontainerd/types" "github.com/docker/docker/libnetwork" "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.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), } + if config.ContainerdAddr != "" { d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) 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) { var pluginCli *containerd.Client - // Windows is not currently using containerd, keep the - // client as nil if config.ContainerdAddr != "" { pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) if err != nil { @@ -1113,8 +1111,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S 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 } diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 526b6d6ecae8f..d96fa805db97d 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -29,6 +29,7 @@ import ( "github.com/docker/docker/daemon/config" "github.com/docker/docker/daemon/initlayer" "github.com/docker/docker/errdefs" + "github.com/docker/docker/libcontainerd/remote" "github.com/docker/docker/libnetwork" nwconfig "github.com/docker/docker/libnetwork/config" "github.com/docker/docker/libnetwork/drivers/bridge" @@ -1736,3 +1737,15 @@ func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo { func recursiveUnmount(target string) error { 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 +} diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index f333b737aa47d..cea0ebf59ee12 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -14,6 +14,8 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/daemon/config" + "github.com/docker/docker/libcontainerd/local" + "github.com/docker/docker/libcontainerd/remote" "github.com/docker/docker/libnetwork" nwconfig "github.com/docker/docker/libnetwork/config" "github.com/docker/docker/libnetwork/datastore" @@ -40,6 +42,9 @@ const ( windowsMaxCPUShares = 10000 windowsMinCPUPercent = 1 windowsMaxCPUPercent = 100 + + windowsV1RuntimeName = "com.docker.hcsshim.v1" + windowsV2RuntimeName = "io.containerd.runhcs.v1" ) // 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 { 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 +}