Преглед изворни кода

Merge pull request #14004 from ktraghavendra/13938_container_swappiness

Add the memory swappiness tuning option to docker.
Phil Estes пре 10 година
родитељ
комит
441ae6c943

+ 11 - 10
daemon/container_unix.go

@@ -262,16 +262,17 @@ func populateCommand(c *Container, env []string) error {
 	}
 	}
 
 
 	resources := &execdriver.Resources{
 	resources := &execdriver.Resources{
-		Memory:         c.hostConfig.Memory,
-		MemorySwap:     c.hostConfig.MemorySwap,
-		CpuShares:      c.hostConfig.CpuShares,
-		CpusetCpus:     c.hostConfig.CpusetCpus,
-		CpusetMems:     c.hostConfig.CpusetMems,
-		CpuPeriod:      c.hostConfig.CpuPeriod,
-		CpuQuota:       c.hostConfig.CpuQuota,
-		BlkioWeight:    c.hostConfig.BlkioWeight,
-		Rlimits:        rlimits,
-		OomKillDisable: c.hostConfig.OomKillDisable,
+		Memory:           c.hostConfig.Memory,
+		MemorySwap:       c.hostConfig.MemorySwap,
+		CpuShares:        c.hostConfig.CpuShares,
+		CpusetCpus:       c.hostConfig.CpusetCpus,
+		CpusetMems:       c.hostConfig.CpusetMems,
+		CpuPeriod:        c.hostConfig.CpuPeriod,
+		CpuQuota:         c.hostConfig.CpuQuota,
+		BlkioWeight:      c.hostConfig.BlkioWeight,
+		Rlimits:          rlimits,
+		OomKillDisable:   c.hostConfig.OomKillDisable,
+		MemorySwappiness: c.hostConfig.MemorySwappiness,
 	}
 	}
 
 
 	processConfig := execdriver.ProcessConfig{
 	processConfig := execdriver.ProcessConfig{

+ 11 - 10
daemon/execdriver/driver.go

@@ -107,16 +107,17 @@ type NetworkInterface struct {
 
 
 // TODO Windows: Factor out ulimit.Rlimit
 // TODO Windows: Factor out ulimit.Rlimit
 type Resources struct {
 type Resources struct {
-	Memory         int64            `json:"memory"`
-	MemorySwap     int64            `json:"memory_swap"`
-	CpuShares      int64            `json:"cpu_shares"`
-	CpusetCpus     string           `json:"cpuset_cpus"`
-	CpusetMems     string           `json:"cpuset_mems"`
-	CpuPeriod      int64            `json:"cpu_period"`
-	CpuQuota       int64            `json:"cpu_quota"`
-	BlkioWeight    int64            `json:"blkio_weight"`
-	Rlimits        []*ulimit.Rlimit `json:"rlimits"`
-	OomKillDisable bool             `json:"oom_kill_disable"`
+	Memory           int64            `json:"memory"`
+	MemorySwap       int64            `json:"memory_swap"`
+	CpuShares        int64            `json:"cpu_shares"`
+	CpusetCpus       string           `json:"cpuset_cpus"`
+	CpusetMems       string           `json:"cpuset_mems"`
+	CpuPeriod        int64            `json:"cpu_period"`
+	CpuQuota         int64            `json:"cpu_quota"`
+	BlkioWeight      int64            `json:"blkio_weight"`
+	Rlimits          []*ulimit.Rlimit `json:"rlimits"`
+	OomKillDisable   bool             `json:"oom_kill_disable"`
+	MemorySwappiness int64            `json:"memory_swappiness"`
 }
 }
 
 
 type ResourceStats struct {
 type ResourceStats struct {

+ 1 - 0
daemon/execdriver/driver_linux.go

@@ -58,6 +58,7 @@ func SetupCgroups(container *configs.Config, c *Command) error {
 		container.Cgroups.CpuQuota = c.Resources.CpuQuota
 		container.Cgroups.CpuQuota = c.Resources.CpuQuota
 		container.Cgroups.BlkioWeight = c.Resources.BlkioWeight
 		container.Cgroups.BlkioWeight = c.Resources.BlkioWeight
 		container.Cgroups.OomKillDisable = c.Resources.OomKillDisable
 		container.Cgroups.OomKillDisable = c.Resources.OomKillDisable
+		container.Cgroups.MemorySwappiness = c.Resources.MemorySwappiness
 	}
 	}
 
 
 	return nil
 	return nil

+ 3 - 0
daemon/execdriver/lxc/lxc_template.go

@@ -115,6 +115,9 @@ lxc.cgroup.blkio.weight = {{.Resources.BlkioWeight}}
 {{if .Resources.OomKillDisable}}
 {{if .Resources.OomKillDisable}}
 lxc.cgroup.memory.oom_control = {{.Resources.OomKillDisable}}
 lxc.cgroup.memory.oom_control = {{.Resources.OomKillDisable}}
 {{end}}
 {{end}}
+{{if .Resources.MemorySwappiness}}
+lxc.cgroup.memory.swappiness = {{.Resources.MemorySwappiness}}
+{{end}}
 {{end}}
 {{end}}
 
 
 {{if .LxcConfig}}
 {{if .LxcConfig}}

+ 2 - 0
docs/reference/api/docker_remote_api_v1.20.md

@@ -160,6 +160,7 @@ Create a container
              "CpusetCpus": "0,1",
              "CpusetCpus": "0,1",
              "CpusetMems": "0,1",
              "CpusetMems": "0,1",
              "BlkioWeight": 300,
              "BlkioWeight": 300,
+             "MemorySwappiness": 60,
              "OomKillDisable": false,
              "OomKillDisable": false,
              "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
              "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
              "PublishAllPorts": false,
              "PublishAllPorts": false,
@@ -208,6 +209,7 @@ Json Parameters:
 -   **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use.
 -   **CpusetCpus** - String value containing the `cgroups CpusetCpus` to use.
 -   **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
 -   **CpusetMems** - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
 -   **BlkioWeight** - Block IO weight (relative weight) accepts a weight value between 10 and 1000.
 -   **BlkioWeight** - Block IO weight (relative weight) accepts a weight value between 10 and 1000.
+-   **MemorySwappiness** - Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
 -   **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not.
 -   **OomKillDisable** - Boolean value, whether to disable OOM Killer for the container or not.
 -   **AttachStdin** - Boolean value, attaches to `stdin`.
 -   **AttachStdin** - Boolean value, attaches to `stdin`.
 -   **AttachStdout** - Boolean value, attaches to `stdout`.
 -   **AttachStdout** - Boolean value, attaches to `stdout`.

+ 1 - 0
docs/reference/commandline/create.md

@@ -57,6 +57,7 @@ Creates a new container.
       --privileged=false         Give extended privileges to this container
       --privileged=false         Give extended privileges to this container
       --read-only=false          Mount the container's root filesystem as read only
       --read-only=false          Mount the container's root filesystem as read only
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)
+      --memory-swappiness=""     Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
       --security-opt=[]          Security options
       --security-opt=[]          Security options
       -t, --tty=false            Allocate a pseudo-TTY
       -t, --tty=false            Allocate a pseudo-TTY
       -u, --user=""              Username or UID
       -u, --user=""              Username or UID

+ 1 - 0
docs/reference/commandline/run.md

@@ -58,6 +58,7 @@ weight=1
       --read-only=false          Mount the container's root filesystem as read only
       --read-only=false          Mount the container's root filesystem as read only
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)
       --restart="no"             Restart policy (no, on-failure[:max-retry], always)
       --rm=false                 Automatically remove the container when it exits
       --rm=false                 Automatically remove the container when it exits
+      --memory-swappiness=""     Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
       --security-opt=[]          Security Options
       --security-opt=[]          Security Options
       --sig-proxy=true           Proxy received signals to the process
       --sig-proxy=true           Proxy received signals to the process
       -t, --tty=false            Allocate a pseudo-TTY
       -t, --tty=false            Allocate a pseudo-TTY

+ 15 - 0
docs/reference/run.md

@@ -514,6 +514,7 @@ container:
     --cpu-quota=0: Limit the CPU CFS (Completely Fair Scheduler) quota
     --cpu-quota=0: Limit the CPU CFS (Completely Fair Scheduler) quota
     --blkio-weight=0: Block IO weight (relative weight) accepts a weight value between 10 and 1000.
     --blkio-weight=0: Block IO weight (relative weight) accepts a weight value between 10 and 1000.
     --oom-kill-disable=true|false: Whether to disable OOM Killer for the container or not.
     --oom-kill-disable=true|false: Whether to disable OOM Killer for the container or not.
+    --memory-swappiness="": Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
 
 
 ### Memory constraints
 ### Memory constraints
 
 
@@ -611,6 +612,20 @@ The following example, illustrates a dangerous way to use the flag:
 The container has unlimited memory which can cause the host to run out memory
 The container has unlimited memory which can cause the host to run out memory
 and require killing system processes to free memory.
 and require killing system processes to free memory.
 
 
+### Swappiness constraint
+
+By default, a container's kernel can swap out a percentage of anonymous pages.
+To set this percentage for a container, specify a `--memory-swappiness` value
+between 0 and 100. A value of 0 turns off anonymous page swapping. A value of
+100 sets all anonymous pages as swappable.
+
+For example, you can set:
+
+    $ docker run -ti --memory-swappiness=0 ubuntu:14.04 /bin/bash
+
+Setting the `--memory-swappiness` option is helpful when you want to retain the
+container's working set and to avoid swapping performance penalties.
+
 ### CPU share constraint
 ### CPU share constraint
 
 
 By default, all containers get the same proportion of CPU cycles. This proportion
 By default, all containers get the same proportion of CPU cycles. This proportion

+ 21 - 0
integration-cli/docker_cli_run_test.go

@@ -61,6 +61,27 @@ func (s *DockerSuite) TestRunWithoutMemoryswapLimit(c *check.C) {
 	}
 	}
 }
 }
 
 
+func (s *DockerSuite) TestRunWithSwappiness(c *check.C) {
+	runCmd := exec.Command(dockerBinary, "run", "--memory-swappiness", "0", "busybox", "true")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("failed to run container, output: %q", out)
+	}
+}
+
+func (s *DockerSuite) TestRunWithSwappinessInvalid(c *check.C) {
+	runCmd := exec.Command(dockerBinary, "run", "--memory-swappiness", "101", "busybox", "true")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err == nil {
+		c.Fatalf("failed. test was able to set invalid value, output: %q", out)
+	}
+	runCmd = exec.Command(dockerBinary, "run", "--memory-swappiness", "-1", "busybox", "true")
+	out, _, err = runCommandWithOutput(runCmd)
+	if err == nil {
+		c.Fatalf("failed. test was able to set invalid value, output: %q", out)
+	}
+}
+
 // "test" should be printed
 // "test" should be printed
 func (s *DockerSuite) TestRunEchoStdoutWitCPULimit(c *check.C) {
 func (s *DockerSuite) TestRunEchoStdoutWitCPULimit(c *check.C) {
 	runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "busybox", "echo", "test")
 	runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "busybox", "echo", "test")

+ 4 - 0
man/docker-create.1.md

@@ -48,6 +48,7 @@ docker-create - Create a new container
 [**--read-only**[=*false*]]
 [**--read-only**[=*false*]]
 [**--restart**[=*RESTART*]]
 [**--restart**[=*RESTART*]]
 [**--security-opt**[=*[]*]]
 [**--security-opt**[=*[]*]]
+[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
 [**-t**|**--tty**[=*false*]]
 [**-t**|**--tty**[=*false*]]
 [**-u**|**--user**[=*USER*]]
 [**-u**|**--user**[=*USER*]]
 [**-v**|**--volume**[=*[]*]]
 [**-v**|**--volume**[=*[]*]]
@@ -225,6 +226,9 @@ This value should always larger than **-m**, so you should always use this with
 **--security-opt**=[]
 **--security-opt**=[]
    Security Options
    Security Options
 
 
+**--memory-swappiness**=""
+   Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
+
 **-t**, **--tty**=*true*|*false*
 **-t**, **--tty**=*true*|*false*
    Allocate a pseudo-TTY. The default is *false*.
    Allocate a pseudo-TTY. The default is *false*.
 
 

+ 4 - 0
man/docker-run.1.md

@@ -51,6 +51,7 @@ docker-run - Run a command in a new container
 [**--rm**[=*false*]]
 [**--rm**[=*false*]]
 [**--security-opt**[=*[]*]]
 [**--security-opt**[=*[]*]]
 [**--sig-proxy**[=*true*]]
 [**--sig-proxy**[=*true*]]
+[**--memory-swappiness**[=*MEMORY-SWAPPINESS*]]
 [**-t**|**--tty**[=*false*]]
 [**-t**|**--tty**[=*false*]]
 [**-u**|**--user**[=*USER*]]
 [**-u**|**--user**[=*USER*]]
 [**-v**|**--volume**[=*[]*]]
 [**-v**|**--volume**[=*[]*]]
@@ -371,6 +372,9 @@ its root filesystem mounted as read only prohibiting any writes.
 **--sig-proxy**=*true*|*false*
 **--sig-proxy**=*true*|*false*
    Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is *true*.
    Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied. The default is *true*.
 
 
+**--memory-swappiness**=""
+   Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
+
 **-t**, **--tty**=*true*|*false*
 **-t**, **--tty**=*true*|*false*
    Allocate a pseudo-TTY. The default is *false*.
    Allocate a pseudo-TTY. The default is *false*.
 
 

+ 4 - 3
pkg/sysinfo/sysinfo.go

@@ -13,9 +13,10 @@ type SysInfo struct {
 }
 }
 
 
 type cgroupMemInfo struct {
 type cgroupMemInfo struct {
-	MemoryLimit    bool
-	SwapLimit      bool
-	OomKillDisable bool
+	MemoryLimit      bool
+	SwapLimit        bool
+	OomKillDisable   bool
+	MemorySwappiness bool
 }
 }
 
 
 type cgroupCpuInfo struct {
 type cgroupCpuInfo struct {

+ 4 - 0
pkg/sysinfo/sysinfo_linux.go

@@ -50,6 +50,10 @@ func checkCgroupMem(quiet bool) *cgroupMemInfo {
 	if !quiet && !info.OomKillDisable {
 	if !quiet && !info.OomKillDisable {
 		logrus.Warnf("Your kernel does not support oom control.")
 		logrus.Warnf("Your kernel does not support oom control.")
 	}
 	}
+	info.MemorySwappiness = cgroupEnabled(mountPoint, "memory.swappiness")
+	if !quiet && !info.MemorySwappiness {
+		logrus.Warnf("Your kernel does not support memory swappiness.")
+	}
 
 
 	return info
 	return info
 }
 }

+ 35 - 34
runconfig/hostconfig.go

@@ -221,40 +221,41 @@ func NewCapList(caps []string) *CapList {
 }
 }
 
 
 type HostConfig struct {
 type HostConfig struct {
-	Binds           []string
-	ContainerIDFile string
-	LxcConf         *LxcConfig
-	Memory          int64 // Memory limit (in bytes)
-	MemorySwap      int64 // Total memory usage (memory + swap); set `-1` to disable swap
-	CpuShares       int64 // CPU shares (relative weight vs. other containers)
-	CpuPeriod       int64
-	CpusetCpus      string // CpusetCpus 0-2, 0,1
-	CpusetMems      string // CpusetMems 0-2, 0,1
-	CpuQuota        int64
-	BlkioWeight     int64 // Block IO weight (relative weight vs. other containers)
-	OomKillDisable  bool  // Whether to disable OOM Killer or not
-	Privileged      bool
-	PortBindings    nat.PortMap
-	Links           []string
-	PublishAllPorts bool
-	Dns             []string
-	DnsSearch       []string
-	ExtraHosts      []string
-	VolumesFrom     []string
-	Devices         []DeviceMapping
-	NetworkMode     NetworkMode
-	IpcMode         IpcMode
-	PidMode         PidMode
-	UTSMode         UTSMode
-	CapAdd          *CapList
-	CapDrop         *CapList
-	RestartPolicy   RestartPolicy
-	SecurityOpt     []string
-	ReadonlyRootfs  bool
-	Ulimits         []*ulimit.Ulimit
-	LogConfig       LogConfig
-	CgroupParent    string // Parent cgroup.
-	ConsoleSize     [2]int // Initial console size on Windows
+	Binds            []string
+	ContainerIDFile  string
+	LxcConf          *LxcConfig
+	Memory           int64 // Memory limit (in bytes)
+	MemorySwap       int64 // Total memory usage (memory + swap); set `-1` to disable swap
+	CpuShares        int64 // CPU shares (relative weight vs. other containers)
+	CpuPeriod        int64
+	CpusetCpus       string // CpusetCpus 0-2, 0,1
+	CpusetMems       string // CpusetMems 0-2, 0,1
+	CpuQuota         int64
+	BlkioWeight      int64 // Block IO weight (relative weight vs. other containers)
+	OomKillDisable   bool  // Whether to disable OOM Killer or not
+	MemorySwappiness int64 // Tuning container memory swappiness behaviour
+	Privileged       bool
+	PortBindings     nat.PortMap
+	Links            []string
+	PublishAllPorts  bool
+	Dns              []string
+	DnsSearch        []string
+	ExtraHosts       []string
+	VolumesFrom      []string
+	Devices          []DeviceMapping
+	NetworkMode      NetworkMode
+	IpcMode          IpcMode
+	PidMode          PidMode
+	UTSMode          UTSMode
+	CapAdd           *CapList
+	CapDrop          *CapList
+	RestartPolicy    RestartPolicy
+	SecurityOpt      []string
+	ReadonlyRootfs   bool
+	Ulimits          []*ulimit.Ulimit
+	LogConfig        LogConfig
+	CgroupParent     string // Parent cgroup.
+	ConsoleSize      [2]int // Initial console size on Windows
 }
 }
 
 
 func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper {
 func MergeConfigs(config *Config, hostConfig *HostConfig) *ContainerConfigWrapper {

+ 48 - 33
runconfig/parse.go

@@ -72,6 +72,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		flStdin           = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
 		flStdin           = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
 		flTty             = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
 		flTty             = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
 		flOomKillDisable  = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
 		flOomKillDisable  = cmd.Bool([]string{"-oom-kill-disable"}, false, "Disable OOM Killer")
+		flSwappinessStr   = cmd.String([]string{"-memory-swappiness"}, "", "Tuning container memory swappiness (0 to 100)")
 		flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
 		flContainerIDFile = cmd.String([]string{"#cidfile", "-cidfile"}, "", "Write the container ID to the file")
 		flEntrypoint      = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image")
 		flEntrypoint      = cmd.String([]string{"#entrypoint", "-entrypoint"}, "", "Overwrite the default ENTRYPOINT of the image")
 		flHostname        = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
 		flHostname        = cmd.String([]string{"h", "-hostname"}, "", "Container host name")
@@ -187,6 +188,19 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 		}
 		}
 	}
 	}
 
 
+	var parsedSwappiness int64
+	var flSwappiness int64
+
+	if *flSwappinessStr != "" {
+		parsedSwappiness, err = strconv.ParseInt(*flSwappinessStr, 10, 64)
+		if err != nil || parsedSwappiness < 0 || parsedSwappiness > 100 {
+			return nil, nil, cmd, fmt.Errorf("invalid value:%s. valid memory swappiness range is 0-100", *flSwappinessStr)
+		}
+		flSwappiness = parsedSwappiness
+	} else {
+		flSwappiness = -1
+	}
+
 	var binds []string
 	var binds []string
 	// add any bind targets to the list of container volumes
 	// add any bind targets to the list of container volumes
 	for bind := range flVolumes.GetMap() {
 	for bind := range flVolumes.GetMap() {
@@ -327,39 +341,40 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
 	}
 	}
 
 
 	hostConfig := &HostConfig{
 	hostConfig := &HostConfig{
-		Binds:           binds,
-		ContainerIDFile: *flContainerIDFile,
-		LxcConf:         lxcConf,
-		Memory:          flMemory,
-		MemorySwap:      MemorySwap,
-		CpuShares:       *flCpuShares,
-		CpuPeriod:       *flCpuPeriod,
-		CpusetCpus:      *flCpusetCpus,
-		CpusetMems:      *flCpusetMems,
-		CpuQuota:        *flCpuQuota,
-		BlkioWeight:     *flBlkioWeight,
-		OomKillDisable:  *flOomKillDisable,
-		Privileged:      *flPrivileged,
-		PortBindings:    portBindings,
-		Links:           flLinks.GetAll(),
-		PublishAllPorts: *flPublishAll,
-		Dns:             flDns.GetAll(),
-		DnsSearch:       flDnsSearch.GetAll(),
-		ExtraHosts:      flExtraHosts.GetAll(),
-		VolumesFrom:     flVolumesFrom.GetAll(),
-		NetworkMode:     netMode,
-		IpcMode:         ipcMode,
-		PidMode:         pidMode,
-		UTSMode:         utsMode,
-		Devices:         deviceMappings,
-		CapAdd:          NewCapList(flCapAdd.GetAll()),
-		CapDrop:         NewCapList(flCapDrop.GetAll()),
-		RestartPolicy:   restartPolicy,
-		SecurityOpt:     flSecurityOpt.GetAll(),
-		ReadonlyRootfs:  *flReadonlyRootfs,
-		Ulimits:         flUlimits.GetList(),
-		LogConfig:       LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
-		CgroupParent:    *flCgroupParent,
+		Binds:            binds,
+		ContainerIDFile:  *flContainerIDFile,
+		LxcConf:          lxcConf,
+		Memory:           flMemory,
+		MemorySwap:       MemorySwap,
+		CpuShares:        *flCpuShares,
+		CpuPeriod:        *flCpuPeriod,
+		CpusetCpus:       *flCpusetCpus,
+		CpusetMems:       *flCpusetMems,
+		CpuQuota:         *flCpuQuota,
+		BlkioWeight:      *flBlkioWeight,
+		OomKillDisable:   *flOomKillDisable,
+		MemorySwappiness: flSwappiness,
+		Privileged:       *flPrivileged,
+		PortBindings:     portBindings,
+		Links:            flLinks.GetAll(),
+		PublishAllPorts:  *flPublishAll,
+		Dns:              flDns.GetAll(),
+		DnsSearch:        flDnsSearch.GetAll(),
+		ExtraHosts:       flExtraHosts.GetAll(),
+		VolumesFrom:      flVolumesFrom.GetAll(),
+		NetworkMode:      netMode,
+		IpcMode:          ipcMode,
+		PidMode:          pidMode,
+		UTSMode:          utsMode,
+		Devices:          deviceMappings,
+		CapAdd:           NewCapList(flCapAdd.GetAll()),
+		CapDrop:          NewCapList(flCapDrop.GetAll()),
+		RestartPolicy:    restartPolicy,
+		SecurityOpt:      flSecurityOpt.GetAll(),
+		ReadonlyRootfs:   *flReadonlyRootfs,
+		Ulimits:          flUlimits.GetList(),
+		LogConfig:        LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
+		CgroupParent:     *flCgroupParent,
 	}
 	}
 
 
 	applyExperimentalFlags(expFlags, config, hostConfig)
 	applyExperimentalFlags(expFlags, config, hostConfig)