func setSandboxResources(hc *dockercontainer.HostConfig) { hc.Resources = dockercontainer.Resources{ MemorySwap: dockertools.DefaultMemorySwap(), CPUShares: defaultSandboxCPUshares, // Use docker's default cpu quota/period. } // TODO: Get rid of the dependency on kubelet internal package. hc.OomScoreAdj = qos.PodInfraOOMAdj }
// CreateContainer creates a new container in the given PodSandbox // Docker cannot store the log to an arbitrary location (yet), so we create an // symlink at LogPath, linking to the actual path of the log. // 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 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: dockertools.DefaultMemorySwap(), 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) } // Apply cgroupsParent derived from the sandbox config. if lc := sandboxConfig.GetLinux(); lc != nil { // Apply Cgroup options. cgroupParent, err := ds.GenerateExpectedCgroupParent(lc.GetCgroupParent()) if err != nil { return "", fmt.Errorf("failed to generate cgroup parent in expected syntax for container %q: %v", config.Metadata.GetName(), err) } hc.CgroupParent = cgroupParent } // 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) recoverFromConflictIfNeeded(ds.client, err) if createResp != nil { return createResp.ID, err } return "", err }