From f2522d2155b687698cd3f8b256ddf3053bb2e759 Mon Sep 17 00:00:00 2001 From: skoo87 Date: Fri, 5 Jan 2018 15:51:49 +0800 Subject: [PATCH] feature: add memory option for container Signed-off-by: skoo87 --- apis/server/container_bridge.go | 13 ++++---- cli/container.go | 52 ++++++++++++++++++++++++-------- cli/create.go | 3 ++ cli/run.go | 3 ++ daemon/mgr/spec.go | 3 ++ daemon/mgr/spec_cgroup_memory.go | 41 +++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 daemon/mgr/spec_cgroup_memory.go diff --git a/apis/server/container_bridge.go b/apis/server/container_bridge.go index 15454cec1..37ca9120b 100644 --- a/apis/server/container_bridge.go +++ b/apis/server/container_bridge.go @@ -249,12 +249,13 @@ func (s *Server) getContainer(ctx context.Context, rw http.ResponseWriter, req * } container := types.ContainerJSON{ - ID: meta.ID, - Name: meta.Name, - Image: meta.Config.Image, - Created: meta.State.StartedAt, - State: meta.State, - Config: meta.Config, + ID: meta.ID, + Name: meta.Name, + Image: meta.Config.Image, + Created: meta.State.StartedAt, + State: meta.State, + Config: meta.Config, + HostConfig: meta.HostConfig, } return EncodeResponse(rw, http.StatusOK, container) } diff --git a/cli/container.go b/cli/container.go index 35c796c15..5ae7be613 100644 --- a/cli/container.go +++ b/cli/container.go @@ -6,22 +6,26 @@ import ( "github.com/alibaba/pouch/apis/types" + units "github.com/docker/go-units" strfmt "github.com/go-openapi/strfmt" ) type container struct { - labels []string - name string - tty bool - volume []string - runtime string - env []string - entrypoint string - workdir string - hostname string - cpushare int64 - cpusetcpus string - cpusetmems string + labels []string + name string + tty bool + volume []string + runtime string + env []string + entrypoint string + workdir string + hostname string + cpushare int64 + cpusetcpus string + cpusetmems string + memory string + memorySwap string + memorySwappiness int64 } func (c *container) config() (*types.ContainerCreateConfig, error) { @@ -63,5 +67,29 @@ func (c *container) config() (*types.ContainerCreateConfig, error) { config.HostConfig.CpusetCpus = c.cpusetcpus config.HostConfig.CpusetMems = c.cpusetmems + if c.memorySwappiness != -1 && (c.memorySwappiness < 0 || c.memorySwappiness > 100) { + return nil, fmt.Errorf("invalid memory swappiness: %d (it's range is 0-100)", c.memorySwappiness) + } + config.HostConfig.MemorySwappiness = &c.memorySwappiness + + if c.memory != "" { + v, err := units.RAMInBytes(c.memory) + if err != nil { + return nil, err + } + config.HostConfig.Memory = v + } + if c.memorySwap != "" { + if c.memorySwap == "-1" { + config.HostConfig.MemorySwap = -1 + } else { + v, err := units.RAMInBytes(c.memorySwap) + if err != nil { + return nil, err + } + config.HostConfig.MemorySwap = v + } + } + return config, nil } diff --git a/cli/create.go b/cli/create.go index fb7820798..e9d3fe8d5 100644 --- a/cli/create.go +++ b/cli/create.go @@ -52,6 +52,9 @@ func (cc *CreateCommand) addFlags() { flagSet.Int64Var(&cc.cpushare, "cpu-share", 0, "CPU shares") flagSet.StringVar(&cc.cpusetcpus, "cpuset-cpus", "", "CPUs in cpuset") flagSet.StringVar(&cc.cpusetmems, "cpuset-mems", "", "MEMs in cpuset") + flagSet.Int64Var(&cc.memorySwappiness, "memory-wappiness", -1, "Container memory swappiness [0, 100]") + flagSet.StringVarP(&cc.memory, "memory", "m", "", "Container memory limit") + flagSet.StringVar(&cc.memorySwap, "memory-swap", "", "Container swap limit") } // runCreate is the entry of create command. diff --git a/cli/run.go b/cli/run.go index 51a0b3df7..5d6356d0d 100644 --- a/cli/run.go +++ b/cli/run.go @@ -61,6 +61,9 @@ func (rc *RunCommand) addFlags() { flagSet.Int64Var(&rc.cpushare, "cpu-share", 0, "CPU shares") flagSet.StringVar(&rc.cpusetcpus, "cpuset-cpus", "", "CPUs in cpuset") flagSet.StringVar(&rc.cpusetmems, "cpuset-mems", "", "MEMs in cpuset") + flagSet.Int64Var(&rc.memorySwappiness, "memory-wappiness", -1, "Container memory swappiness [0, 100]") + flagSet.StringVarP(&rc.memory, "memory", "m", "", "Container memory limit") + flagSet.StringVar(&rc.memorySwap, "memory-swap", "", "Container swap limit") } // runRun is the entry of run command. diff --git a/daemon/mgr/spec.go b/daemon/mgr/spec.go index 9b9a088cc..3abfe1f6f 100644 --- a/daemon/mgr/spec.go +++ b/daemon/mgr/spec.go @@ -21,6 +21,9 @@ var setupFunc = []SetupFunc{ // cgroup setupCgroupCPUShare, setupCgroupCPUSet, + setupCgroupMemory, + setupCgroupMemorySwap, + setupCgroupMemorySwappiness, // namespaces setupUserNamespace, diff --git a/daemon/mgr/spec_cgroup_memory.go b/daemon/mgr/spec_cgroup_memory.go new file mode 100644 index 000000000..07a417e3a --- /dev/null +++ b/daemon/mgr/spec_cgroup_memory.go @@ -0,0 +1,41 @@ +package mgr + +import ( + "context" + + specs "github.com/opencontainers/runtime-spec/specs-go" +) + +func getCgroupMemory(s *specs.Spec) *specs.LinuxMemory { + if s.Linux.Resources.Memory == nil { + s.Linux.Resources.Memory = &specs.LinuxMemory{} + } + return s.Linux.Resources.Memory +} + +func setupCgroupMemory(ctx context.Context, meta *ContainerMeta, s *specs.Spec) error { + mem := getCgroupMemory(s) + + v := meta.HostConfig.Memory + mem.Limit = &v + return nil +} + +func setupCgroupMemorySwap(ctx context.Context, meta *ContainerMeta, s *specs.Spec) error { + mem := getCgroupMemory(s) + + v := meta.HostConfig.MemorySwap + mem.Swap = &v + return nil +} + +func setupCgroupMemorySwappiness(ctx context.Context, meta *ContainerMeta, s *specs.Spec) error { + mem := getCgroupMemory(s) + + var v uint64 + if meta.HostConfig.MemorySwappiness != nil { + v = uint64(*(meta.HostConfig.MemorySwappiness)) + } + mem.Swappiness = &v + return nil +}