Run Linux Images (LCOW) and Windows Containers side by side (#7850)

Makes it possible to run Linux Containers On Windows with Nomad alongside Windows Containers. Fingerprint prevents only to run Nomad in Windows 10 with Linux Containers
This commit is contained in:
Juan Larriba
2020-05-04 19:08:47 +02:00
committed by GitHub
parent b3d43b8e66
commit 65f09ed119
3 changed files with 29 additions and 5 deletions

View File

@@ -10,7 +10,7 @@ var (
// directory shared across tasks in a task group.
SharedAllocContainerPath = filepath.Join("c:\\", SharedAllocName)
// TaskLocalContainer is the path inside a container for mounted directory
// TaskLocalContainerPath is the path inside a container for mounted directory
// for local storage.
TaskLocalContainerPath = filepath.Join("c:\\", TaskLocal)

View File

@@ -274,6 +274,13 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
return nil, nil, err
}
if runtime.GOOS == "windows" {
err = d.convertAllocPathsForWindowsLCOW(cfg, driverConfig.Image)
if err != nil {
return nil, nil, err
}
}
containerCfg, err := d.createContainerConfig(cfg, &driverConfig, driverConfig.Image)
if err != nil {
d.logger.Error("failed to create container configuration", "image_name", driverConfig.Image,
@@ -616,8 +623,24 @@ func (d *Driver) loadImage(task *drivers.TaskConfig, driverConfig *TaskConfig, c
return dockerImage.ID, nil
}
func (d *Driver) containerBinds(task *drivers.TaskConfig, driverConfig *TaskConfig) ([]string, error) {
func (d *Driver) convertAllocPathsForWindowsLCOW(task *drivers.TaskConfig, image string) error {
imageConfig, err := client.InspectImage(image)
if err != nil {
return fmt.Errorf("the image does not exist: %v", err)
}
// LCOW If we are running a Linux Container on Windows, we need to mount it correctly, as c:\ does not exist on unix
if imageConfig.OS == "linux" {
a := []rune(task.Env[taskenv.AllocDir])
task.Env[taskenv.AllocDir] = strings.ReplaceAll(string(a[2:]), "\\", "/")
l := []rune(task.Env[taskenv.TaskLocalDir])
task.Env[taskenv.TaskLocalDir] = strings.ReplaceAll(string(l[2:]), "\\", "/")
s := []rune(task.Env[taskenv.SecretsDir])
task.Env[taskenv.SecretsDir] = strings.ReplaceAll(string(s[2:]), "\\", "/")
}
return nil
}
func (d *Driver) containerBinds(task *drivers.TaskConfig, driverConfig *TaskConfig) ([]string, error) {
allocDirBind := fmt.Sprintf("%s:%s", task.TaskDir().SharedAllocDir, task.Env[taskenv.AllocDir])
taskLocalBind := fmt.Sprintf("%s:%s", task.TaskDir().LocalDir, task.Env[taskenv.TaskLocalDir])
secretDirBind := fmt.Sprintf("%s:%s", task.TaskDir().SecretsDir, task.Env[taskenv.SecretsDir])
@@ -723,7 +746,6 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T
logger.Error("task.Resources is empty")
return c, fmt.Errorf("task.Resources is empty")
}
binds, err := d.containerBinds(task, driverConfig)
if err != nil {
return c, err
@@ -817,6 +839,7 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T
logger.Debug("configured resources", "memory", hostConfig.Memory,
"cpu_shares", hostConfig.CPUShares, "cpu_quota", hostConfig.CPUQuota,
"cpu_period", hostConfig.CPUPeriod)
logger.Debug("binding directories", "binds", hclog.Fmt("%#v", hostConfig.Binds))
// set privileged mode

View File

@@ -168,15 +168,16 @@ func (d *Driver) buildFingerprint() *drivers.Fingerprint {
strings.Join(runtimeNames, ","))
fp.Attributes["driver.docker.os_type"] = pstructs.NewStringAttribute(dockerInfo.OSType)
// If this situations arises, we are running in Windows 10 with Linux Containers enabled via VM
if runtime.GOOS == "windows" && dockerInfo.OSType == "linux" {
if d.fingerprintSuccessful() {
d.logger.Warn("detected Linux docker containers on Windows; only Windows containers are supported")
d.logger.Warn("Docker is configured with Linux containers; switch to Windows Containers")
}
d.setFingerprintFailure()
return &drivers.Fingerprint{
Health: drivers.HealthStateUnhealthy,
HealthDescription: "Docker is configured with Linux containers; only Windows containers are supported",
HealthDescription: "Docker is configured with Linux containers; switch to Windows Containers",
}
}
}