Skip to content

Commit 7ccf750

Browse files
committed
Allow switching Windows runtimes.
This adds support for 2 runtimes on Windows, one that uses the built-in HCSv1 integration and another which uses containerd with the runhcs shim. Signed-off-by: Brian Goff <[email protected]>
1 parent 5176095 commit 7ccf750

9 files changed

Lines changed: 86 additions & 26 deletions

File tree

cmd/dockerd/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
9999
flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", daemon.ContainersNamespace, "Containerd namespace to use")
100100
flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", containerd.PluginNamespace, "Containerd namespace to use for plugins")
101101

102+
flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers")
103+
102104
return nil
103105
}
104106

cmd/dockerd/config_common_unix.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,4 @@ func installUnixConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
6060
flags.BoolVar(&conf.BridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication")
6161
flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports")
6262
flags.Var(opts.NewNamedRuntimeOpt("runtimes", &conf.Runtimes, config.StockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime")
63-
flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers")
64-
6563
}

daemon/config/config.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ const (
4848
// DefaultRuntimeBinary is the default runtime to be used by
4949
// containerd if none is specified
5050
DefaultRuntimeBinary = "runc"
51-
// StockRuntimeName is the reserved name/alias used to represent the
52-
// OCI runtime being shipped with the docker daemon package.
53-
StockRuntimeName = "runc"
51+
5452
// LinuxV1RuntimeName is the runtime used to specify the containerd v1 shim with the runc binary
5553
// Note this is different than io.containerd.runc.v1 which would be the v1 shim using the v2 shim API.
5654
// This is specifically for the v1 shim using the v1 shim API.
@@ -273,6 +271,8 @@ type CommonConfig struct {
273271

274272
ContainerdNamespace string `json:"containerd-namespace,omitempty"`
275273
ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"`
274+
275+
DefaultRuntime string `json:"default-runtime,omitempty"`
276276
}
277277

278278
// IsValueSet returns true if a configuration value
@@ -636,3 +636,12 @@ func ModifiedDiscoverySettings(config *Config, backendType, advertise string, cl
636636

637637
return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
638638
}
639+
640+
// GetDefaultRuntimeName returns the current default runtime
641+
func (conf *Config) GetDefaultRuntimeName() string {
642+
conf.Lock()
643+
rt := conf.DefaultRuntime
644+
conf.Unlock()
645+
646+
return rt
647+
}

daemon/config/config_linux.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ const (
1919

2020
// DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1.
2121
DefaultCgroupV1NamespaceMode = containertypes.CgroupnsModeHost
22+
23+
// StockRuntimeName is the reserved name/alias used to represent the
24+
// OCI runtime being shipped with the docker daemon package.
25+
StockRuntimeName = "runc"
2226
)
2327

2428
// BridgeConfig stores all the bridge driver specific
@@ -51,7 +55,6 @@ type Config struct {
5155

5256
// Fields below here are platform specific.
5357
Runtimes map[string]types.Runtime `json:"runtimes,omitempty"`
54-
DefaultRuntime string `json:"default-runtime,omitempty"`
5558
DefaultInitBinary string `json:"default-init,omitempty"`
5659
CgroupParent string `json:"cgroup-parent,omitempty"`
5760
EnableSelinuxSupport bool `json:"selinux-enabled,omitempty"`
@@ -83,15 +86,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime {
8386
return nil
8487
}
8588

86-
// GetDefaultRuntimeName returns the current default runtime
87-
func (conf *Config) GetDefaultRuntimeName() string {
88-
conf.Lock()
89-
rt := conf.DefaultRuntime
90-
conf.Unlock()
91-
92-
return rt
93-
}
94-
9589
// GetAllRuntimes returns a copy of the runtimes map
9690
func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
9791
conf.Lock()

daemon/config/config_linux_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ func TestUnixValidateConfigurationErrors(t *testing.T) {
150150
Runtimes: map[string]types.Runtime{
151151
"foo": {},
152152
},
153-
DefaultRuntime: "bar",
153+
CommonConfig: CommonConfig{
154+
DefaultRuntime: "bar",
155+
},
154156
},
155157
},
156158
}

daemon/config/config_windows.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import (
44
"github.com/docker/docker/api/types"
55
)
66

7+
const (
8+
// This is used by the `default-runtime` flag in dockerd as the default value.
9+
// On windows we'd prefer to keep this empty so the value is auto-detected based on other options.
10+
StockRuntimeName = ""
11+
)
12+
713
// BridgeConfig stores all the bridge driver specific
814
// configuration.
915
type BridgeConfig struct {
@@ -26,11 +32,6 @@ func (conf *Config) GetRuntime(name string) *types.Runtime {
2632
return nil
2733
}
2834

29-
// GetDefaultRuntimeName returns the current default runtime
30-
func (conf *Config) GetDefaultRuntimeName() string {
31-
return StockRuntimeName
32-
}
33-
3435
// GetAllRuntimes returns a copy of the runtimes map
3536
func (conf *Config) GetAllRuntimes() map[string]types.Runtime {
3637
return map[string]types.Runtime{}

daemon/daemon.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import (
4242
"github.com/docker/docker/errdefs"
4343
"github.com/docker/docker/image"
4444
"github.com/docker/docker/layer"
45-
"github.com/docker/docker/libcontainerd"
4645
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
4746
"github.com/docker/docker/libnetwork"
4847
"github.com/docker/docker/libnetwork/cluster"
@@ -922,6 +921,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
922921
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
923922
grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)),
924923
}
924+
925925
if config.ContainerdAddr != "" {
926926
d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
927927
if err != nil {
@@ -932,8 +932,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
932932
createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
933933
var pluginCli *containerd.Client
934934

935-
// Windows is not currently using containerd, keep the
936-
// client as nil
937935
if config.ContainerdAddr != "" {
938936
pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second))
939937
if err != nil {
@@ -1113,8 +1111,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
11131111

11141112
go d.execCommandGC()
11151113

1116-
d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d)
1117-
if err != nil {
1114+
if err := d.initLibcontainerd(ctx); err != nil {
11181115
return nil, err
11191116
}
11201117

daemon/daemon_unix.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/docker/docker/daemon/config"
3030
"github.com/docker/docker/daemon/initlayer"
3131
"github.com/docker/docker/errdefs"
32+
"github.com/docker/docker/libcontainerd/remote"
3233
"github.com/docker/docker/libnetwork"
3334
nwconfig "github.com/docker/docker/libnetwork/config"
3435
"github.com/docker/docker/libnetwork/drivers/bridge"
@@ -1736,3 +1737,15 @@ func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
17361737
func recursiveUnmount(target string) error {
17371738
return mount.RecursiveUnmount(target)
17381739
}
1740+
1741+
func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
1742+
var err error
1743+
daemon.containerd, err = remote.NewClient(
1744+
ctx,
1745+
daemon.containerdCli,
1746+
filepath.Join(daemon.configStore.ExecRoot, "containerd"),
1747+
daemon.configStore.ContainerdNamespace,
1748+
daemon,
1749+
)
1750+
return err
1751+
}

daemon/daemon_windows.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
containertypes "github.com/docker/docker/api/types/container"
1515
"github.com/docker/docker/container"
1616
"github.com/docker/docker/daemon/config"
17+
"github.com/docker/docker/libcontainerd/local"
18+
"github.com/docker/docker/libcontainerd/remote"
1719
"github.com/docker/docker/libnetwork"
1820
nwconfig "github.com/docker/docker/libnetwork/config"
1921
"github.com/docker/docker/libnetwork/datastore"
@@ -40,6 +42,9 @@ const (
4042
windowsMaxCPUShares = 10000
4143
windowsMinCPUPercent = 1
4244
windowsMaxCPUPercent = 100
45+
46+
windowsV1RuntimeName = "com.docker.hcsshim.v1"
47+
windowsV2RuntimeName = "io.containerd.runhcs.v1"
4348
)
4449

4550
// Windows containers are much larger than Linux containers and each of them
@@ -649,3 +654,42 @@ func setupResolvConf(config *config.Config) {
649654
func (daemon *Daemon) RawSysInfo() *sysinfo.SysInfo {
650655
return sysinfo.New()
651656
}
657+
658+
func (daemon *Daemon) initLibcontainerd(ctx context.Context) error {
659+
var err error
660+
661+
rt := daemon.configStore.GetDefaultRuntimeName()
662+
if rt == "" {
663+
if daemon.configStore.ContainerdAddr == "" {
664+
rt = windowsV1RuntimeName
665+
} else {
666+
rt = windowsV2RuntimeName
667+
}
668+
}
669+
670+
switch rt {
671+
case windowsV1RuntimeName:
672+
daemon.containerd, err = local.NewClient(
673+
ctx,
674+
daemon.containerdCli,
675+
filepath.Join(daemon.configStore.ExecRoot, "containerd"),
676+
daemon.configStore.ContainerdNamespace,
677+
daemon,
678+
)
679+
case windowsV2RuntimeName:
680+
if daemon.configStore.ContainerdAddr == "" {
681+
return fmt.Errorf("cannot use the specified runtime %q without containerd", rt)
682+
}
683+
daemon.containerd, err = remote.NewClient(
684+
ctx,
685+
daemon.containerdCli,
686+
filepath.Join(daemon.configStore.ExecRoot, "containerd"),
687+
daemon.configStore.ContainerdNamespace,
688+
daemon,
689+
)
690+
default:
691+
return fmt.Errorf("unknown windows runtime %s", rt)
692+
}
693+
694+
return err
695+
}

0 commit comments

Comments
 (0)