Change:
What happened: Latest kubelet + Windows Docker version 1.14.0-dev refused to start any containers, error output: "invalid option: Windows does not support MemorySwap" How to reproduce it (as minimally and precisely as possible): It's always reproducible with Windows Docker 1.14.0-dev + latest kubelet code base. Anything else do we need to know: It didn't happen for Windows Docker 1.12.2-cs2-ws-beta. The reason behind the issue was because new code was for Windows Docker to check Resources parameters, it doesn't accept a non-zero value for MemorySwap: But kubelet was default to set an unlimited (-1) value. The issue was gone in my setup after applied a private fix to disable MemorySwap by set it to zero for Windows.

Discussion:
if rOpts != nil { hc.Resources = dockercontainer.Resources{ Memory:     rOpts.GetMemoryLimitInBytes(), <del> MemorySwap: -1, </del> <ins> MemorySwap: dockertools.DefaultMemorySwap(), </ins> CPUShares:  rOpts.GetCpuShares(), CPUQuota:   rOpts.GetCpuQuota(), CPUPeriod:  rOpts.GetCpuPeriod(),

runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" <ins> "k8s.io/kubernetes/pkg/kubelet/dockertools" </ins> "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/kubelet/types" )

func setSandboxResources(hc *dockercontainer.HostConfig) { hc.Resources = dockercontainer.Resources{ <del> MemorySwap: -1, </del> <ins> MemorySwap: dockertools.DefaultMemorySwap(), </ins> CPUShares:  defaultSandboxCPUshares, // Use docker's default cpu quota/period. }

"os/exec" "path" "path/filepath" <del> "runtime" </del> "strconv" "strings" "sync"

SecurityOpt: fmtSecurityOpts, } <del> // There is no /etc/resolv.conf in Windows, DNS and DNSSearch options would have to be passed to Docker runtime instead if runtime.GOOS == "windows" { hc.DNS = opts.DNS hc.DNSSearch = opts.DNSSearch } </del> <ins> updateHostConfig(hc, opts) </ins> // Set sysctls if requested if container.Name == PodInfraContainerName {

import ( dockertypes "github.com/docker/engine-api/types" <ins> dockercontainer "github.com/docker/engine-api/types/container" </ins> "k8s.io/kubernetes/pkg/api" <ins> kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" </ins> ) <ins> // These two functions are OS specific (for now at least) func updateHostConfig(hc *dockercontainer.HostConfig, opts *kubecontainer.RunContainerOptions) { // no-op, there is a windows implementation that is different. } func DefaultMemorySwap() int64 { return 0 } </ins> func getContainerIP(container *dockertypes.ContainerJSON) string { result := "" if container.NetworkSettings != nil {

package dockertools import ( <del> "k8s.io/kubernetes/pkg/api" </del> dockertypes "github.com/docker/engine-api/types" <ins> dockercontainer "github.com/docker/engine-api/types/container" "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" </ins> ) <ins> // These two functions are OS specific (for now at least) func updateHostConfig(hc *dockercontainer.HostConfig, opts *kubecontainer.RunContainerOptions) { } func DefaultMemorySwap() int64 { return -1 } </ins> func getContainerIP(container *dockertypes.ContainerJSON) string { return "" }

import ( "os" <del> "k8s.io/kubernetes/pkg/api" </del> dockertypes "github.com/docker/engine-api/types" <ins> dockercontainer "github.com/docker/engine-api/types/container" "k8s.io/kubernetes/pkg/api" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" </ins> ) <ins> // These two functions are OS specific (for now at least) func updateHostConfig(hc *dockercontainer.HostConfig, opts *kubecontainer.RunContainerOptions) { // There is no /etc/resolv.conf in Windows, DNS and DNSSearch options would have to be passed to Docker runtime instead hc.DNS = opts.DNS hc.DNSSearch = opts.DNSSearch // MemorySwap == -1 is not currently supported in Docker 1.14 on Windows // https://github.com/docker/docker/blob/master/daemon/daemon_windows.go#L175 hc.Resources.MemorySwap = 0 } func DefaultMemorySwap() int64 { return 0 } </ins> func getContainerIP(container *dockertypes.ContainerJSON) string { if container.NetworkSettings != nil { for _, network := range container.NetworkSettings.Networks {