// CreateContainer creates a new container in the given PodSandbox
// Note: docker doesn't use LogPath yet.
// TODO: check if the default values returned by the runtime API are ok.
func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) {
	if config == nil {
		return "", fmt.Errorf("container config is nil")
	}
	if sandboxConfig == nil {
		return "", fmt.Errorf("sandbox config is nil for container %q", config.Metadata.GetName())
	}

	labels := makeLabels(config.GetLabels(), config.GetAnnotations())
	// Apply a the container type label.
	labels[containerTypeLabelKey] = containerTypeLabelContainer
	// Write the container log path in the labels.
	labels[containerLogPathLabelKey] = filepath.Join(sandboxConfig.GetLogDirectory(), config.GetLogPath())
	// Write the sandbox ID in the labels.
	labels[sandboxIDLabelKey] = podSandboxID

	image := ""
	if iSpec := config.GetImage(); iSpec != nil {
		image = iSpec.GetImage()
	}
	createConfig := dockertypes.ContainerCreateConfig{
		Name: makeContainerName(sandboxConfig, config),
		Config: &dockercontainer.Config{
			// TODO: set User.
			Entrypoint: dockerstrslice.StrSlice(config.GetCommand()),
			Cmd:        dockerstrslice.StrSlice(config.GetArgs()),
			Env:        generateEnvList(config.GetEnvs()),
			Image:      image,
			WorkingDir: config.GetWorkingDir(),
			Labels:     labels,
			// Interactive containers:
			OpenStdin: config.GetStdin(),
			StdinOnce: config.GetStdinOnce(),
			Tty:       config.GetTty(),
		},
	}

	// Fill the HostConfig.
	hc := &dockercontainer.HostConfig{
		Binds:          generateMountBindings(config.GetMounts()),
		ReadonlyRootfs: config.GetReadonlyRootfs(),
		Privileged:     config.GetPrivileged(),
	}

	// Apply options derived from the sandbox config.
	if lc := sandboxConfig.GetLinux(); lc != nil {
		// Apply Cgroup options.
		// TODO: Check if this works with per-pod cgroups.
		hc.CgroupParent = lc.GetCgroupParent()

		// Apply namespace options.
		sandboxNSMode := fmt.Sprintf("container:%v", podSandboxID)
		hc.NetworkMode = dockercontainer.NetworkMode(sandboxNSMode)
		hc.IpcMode = dockercontainer.IpcMode(sandboxNSMode)
		hc.UTSMode = ""
		hc.PidMode = ""

		nsOpts := lc.GetNamespaceOptions()
		if nsOpts != nil {
			if nsOpts.GetHostNetwork() {
				hc.UTSMode = namespaceModeHost
			}
			if nsOpts.GetHostPid() {
				hc.PidMode = namespaceModeHost
			}
		}
	}

	// Apply Linux-specific options if applicable.
	if lc := config.GetLinux(); lc != nil {
		// Apply resource options.
		// TODO: Check if the units are correct.
		// TODO: Can we assume the defaults are sane?
		rOpts := lc.GetResources()
		if rOpts != nil {
			hc.Resources = dockercontainer.Resources{
				Memory:     rOpts.GetMemoryLimitInBytes(),
				MemorySwap: -1, // Always disable memory swap.
				CPUShares:  rOpts.GetCpuShares(),
				CPUQuota:   rOpts.GetCpuQuota(),
				CPUPeriod:  rOpts.GetCpuPeriod(),
				// TODO: Need to set devices.
			}
			hc.OomScoreAdj = int(rOpts.GetOomScoreAdj())
		}
		// Note: ShmSize is handled in kube_docker_client.go
	}

	var err error
	hc.SecurityOpt, err = getContainerSecurityOpts(config.Metadata.GetName(), sandboxConfig, ds.seccompProfileRoot)
	if err != nil {
		return "", fmt.Errorf("failed to generate container security options for container %q: %v", config.Metadata.GetName(), err)
	}
	// TODO: Add or drop capabilities.

	createConfig.HostConfig = hc
	createResp, err := ds.client.CreateContainer(createConfig)
	if createResp != nil {
		return createResp.ID, err
	}
	return "", err
}
示例#2
0
// CreateContainer creates a new container in the given PodSandbox
// Note: docker doesn't use LogPath yet.
// TODO: check if the default values returned by the runtime API are ok.
func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi.ContainerConfig, sandboxConfig *runtimeApi.PodSandboxConfig) (string, error) {
	if config == nil {
		return "", fmt.Errorf("container config is nil")
	}
	if sandboxConfig == nil {
		return "", fmt.Errorf("sandbox config is nil for container %q", config.Metadata.GetName())
	}

	labels := makeLabels(config.GetLabels(), config.GetAnnotations())
	// Apply a the container type label.
	labels[containerTypeLabelKey] = containerTypeLabelContainer
	// Write the container log path in the labels.
	labels[containerLogPathLabelKey] = filepath.Join(sandboxConfig.GetLogDirectory(), config.GetLogPath())
	// Write the sandbox ID in the labels.
	labels[sandboxIDLabelKey] = podSandboxID

	image := ""
	if iSpec := config.GetImage(); iSpec != nil {
		image = iSpec.GetImage()
	}
	createConfig := dockertypes.ContainerCreateConfig{
		Name: makeContainerName(sandboxConfig, config),
		Config: &dockercontainer.Config{
			// TODO: set User.
			Entrypoint: dockerstrslice.StrSlice(config.GetCommand()),
			Cmd:        dockerstrslice.StrSlice(config.GetArgs()),
			Env:        generateEnvList(config.GetEnvs()),
			Image:      image,
			WorkingDir: config.GetWorkingDir(),
			Labels:     labels,
			// Interactive containers:
			OpenStdin: config.GetStdin(),
			StdinOnce: config.GetStdinOnce(),
			Tty:       config.GetTty(),
		},
	}

	// Fill the HostConfig.
	hc := &dockercontainer.HostConfig{
		Binds: generateMountBindings(config.GetMounts()),
	}

	// Apply cgroupsParent derived from the sandbox config.
	if lc := sandboxConfig.GetLinux(); lc != nil {
		// Apply Cgroup options.
		// TODO: Check if this works with per-pod cgroups.
		// TODO: we need to pass the cgroup in syntax expected by cgroup driver but shim does not use docker info yet...
		hc.CgroupParent = lc.GetCgroupParent()
	}

	// Apply Linux-specific options if applicable.
	if lc := config.GetLinux(); lc != nil {
		// Apply resource options.
		// TODO: Check if the units are correct.
		// TODO: Can we assume the defaults are sane?
		rOpts := lc.GetResources()
		if rOpts != nil {
			hc.Resources = dockercontainer.Resources{
				Memory:     rOpts.GetMemoryLimitInBytes(),
				MemorySwap: -1, // Always disable memory swap.
				CPUShares:  rOpts.GetCpuShares(),
				CPUQuota:   rOpts.GetCpuQuota(),
				CPUPeriod:  rOpts.GetCpuPeriod(),
			}
			hc.OomScoreAdj = int(rOpts.GetOomScoreAdj())
		}
		// Note: ShmSize is handled in kube_docker_client.go

		// Apply security context.
		applyContainerSecurityContext(lc, podSandboxID, createConfig.Config, hc)
	}

	// Set devices for container.
	devices := make([]dockercontainer.DeviceMapping, len(config.Devices))
	for i, device := range config.Devices {
		devices[i] = dockercontainer.DeviceMapping{
			PathOnHost:        device.GetHostPath(),
			PathInContainer:   device.GetContainerPath(),
			CgroupPermissions: device.GetPermissions(),
		}
	}
	hc.Resources.Devices = devices

	// Apply appArmor and seccomp options.
	securityOpts, err := getContainerSecurityOpts(config.Metadata.GetName(), sandboxConfig, ds.seccompProfileRoot)
	if err != nil {
		return "", fmt.Errorf("failed to generate container security options for container %q: %v", config.Metadata.GetName(), err)
	}
	hc.SecurityOpt = append(hc.SecurityOpt, securityOpts...)

	createConfig.HostConfig = hc
	createResp, err := ds.client.CreateContainer(createConfig)
	if createResp != nil {
		return createResp.ID, err
	}
	return "", err
}