From 13a1ffdd44487c275e21e93920f5ce1eb456abe6 Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Wed, 9 Aug 2017 16:39:10 +0100 Subject: [PATCH] Add Cgroup resource limits into Yaml spec This adds all the cgroup restrictions into the spec. Signed-off-by: Justin Cormack --- docs/yaml.md | 2 +- src/moby/config.go | 33 +++++------ src/moby/schema.go | 135 ++++++++++++++++++++++++++++++++++++++++++++- test/test.yml | 6 ++ 4 files changed, 156 insertions(+), 20 deletions(-) diff --git a/docs/yaml.md b/docs/yaml.md index 1980e38c3..9b3233a23 100644 --- a/docs/yaml.md +++ b/docs/yaml.md @@ -172,9 +172,9 @@ bind mounted into a container. - `noNewPrivileges` is `true` means no additional capabilities can be acquired and `suid` binaries do not work. - `hostname` sets the hostname inside the image. - `oomScoreAdj` changes the OOM score. -- `disableOOMKiller` disables the OOM killer for the service. - `rootfsPropagation` sets the rootfs propagation, eg `shared`, `slave` or (default) `private`. - `cgroupsPath` sets the path for cgroups. +- `resources` sets cgroup resource limits as per the OCI spec. - `sysctl` sets a list of `sysctl` key value pairs that are set inside the container namespace. - `rmlimits` sets a list of `rlimit` values in the form `name,soft,hard`, eg `nofile,100,200`. You can use `unlimited` as a value too. diff --git a/src/moby/config.go b/src/moby/config.go index abf1d80fe..39603f1e0 100644 --- a/src/moby/config.go +++ b/src/moby/config.go @@ -81,9 +81,9 @@ type Image struct { AdditionalGids *[]interface{} `yaml:"additionalGids" json:"additionalGids,omitempty"` NoNewPrivileges *bool `yaml:"noNewPrivileges" json:"noNewPrivileges,omitempty"` OOMScoreAdj *int `yaml:"oomScoreAdj" json:"oomScoreAdj,omitempty"` - DisableOOMKiller *bool `yaml:"disableOOMKiller" json:"disableOOMKiller,omitempty"` RootfsPropagation *string `yaml:"rootfsPropagation" json:"rootfsPropagation,omitempty"` CgroupsPath *string `yaml:"cgroupsPath" json:"cgroupsPath,omitempty"` + Resources *specs.LinuxResources `yaml:"resources" json:"resources,omitempty"` Sysctl *map[string]string `yaml:"sysctl" json:"sysctl,omitempty"` Rlimits *[]string `yaml:"rlimits" json:"rlimits,omitempty"` UIDMappings *[]specs.LinuxIDMapping `yaml:"uidMappings" json:"uidMappings,omitempty"` @@ -460,6 +460,17 @@ func assignMappings(v1, v2 *[]specs.LinuxIDMapping) []specs.LinuxIDMapping { return []specs.LinuxIDMapping{} } +// assignResources does ordered overrides from Resources +func assignResources(v1, v2 *specs.LinuxResources) specs.LinuxResources { + if v2 != nil { + return *v2 + } + if v1 != nil { + return *v1 + } + return specs.LinuxResources{} +} + // assignStringEmpty does ordered overrides if strings are empty, for // values where there is always an explicit override eg "none" func assignStringEmpty(v1, v2 string) string { @@ -883,27 +894,13 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect, idMap map[string oci.Hostname = assignStringEmpty(label.Hostname, yaml.Hostname) oci.Mounts = mountList + resources := assignResources(label.Resources, yaml.Resources) + oci.Linux = &specs.Linux{ UIDMappings: assignMappings(label.UIDMappings, yaml.UIDMappings), GIDMappings: assignMappings(label.GIDMappings, yaml.GIDMappings), Sysctl: assignMaps(label.Sysctl, yaml.Sysctl), - Resources: &specs.LinuxResources{ - // Devices - Memory: &specs.LinuxMemory{ - // Limit - // Reservation - // Swap - // Kernel - // KernelTCP - // Swappiness - DisableOOMKiller: assignBoolPtr(label.DisableOOMKiller, yaml.DisableOOMKiller), - }, - // CPU - // Pids - // BlockIO - // HugepageLimits - // Network - }, + Resources: &resources, CgroupsPath: assignString(label.CgroupsPath, yaml.CgroupsPath), Namespaces: namespaces, // Devices diff --git a/src/moby/schema.go b/src/moby/schema.go index 16a81208f..043c88d9e 100644 --- a/src/moby/schema.go +++ b/src/moby/schema.go @@ -75,6 +75,139 @@ var schema = string(` "type": "array", "items": { "$ref": "#/definitions/idmapping" } }, + "devicecgroups": { + "type": "array", + "items": { "$ref": "#/definitions/devicecgroup" } + }, + "devicecgroup": { + "type": "object", + "additionalProperties": false, + "properties": { + "allow": {"type": "boolean"}, + "type": {"type": "string"}, + "major": {"type": "integer"}, + "minor": {"type": "integer"}, + "access": {"type": "string"} + } + }, + "memory": { + "type": "object", + "additionalProperties": false, + "properties": { + "limit": {"type": "integer"}, + "reservation": {"type": "integer"}, + "swap": {"type": "integer"}, + "kernel": {"type": "integer"}, + "kernelTCP": {"type": "integer"}, + "swappiness": {"type": "integer"}, + "disableOOMKiller": {"type": "boolean"} + } + }, + "cpu": { + "type": "object", + "additionalProperties": false, + "properties": { + "shares": {"type": "integer"}, + "quota": {"type": "integer"}, + "period": {"type": "integer"}, + "realtimeRuntime": {"type": "integer"}, + "realtimePeriod": {"type": "integer"}, + "cpus": {"type": "string"}, + "mems": {"type": "string"} + } + }, + "pids": { + "type": "object", + "additionalProperties": false, + "properties": { + "limit": {"type": "integer"} + } + }, + "weightdevices": { + "type": "array", + "items": {"$ref": "#/definitions/weightdevice"} + }, + "weightdevice": { + "type": "object", + "additionalProperties": false, + "properties": { + "major": {"type": "integer"}, + "minor": {"type": "integer"}, + "weight": {"type": "integer"}, + "leafWeight": {"type": "integer"} + } + }, + "throttledevices": { + "type": "array", + "items": {"$ref": "#/definitions/throttledevice"} + }, + "throttledevice": { + "type": "object", + "additionalProperties": false, + "properties": { + "major": {"type": "integer"}, + "minor": {"type": "integer"}, + "rate": {"type": "integer"} + } + }, + "blockio": { + "type": "object", + "additionalProperties": false, + "properties": { + "weight": {"type": "integer"}, + "leafWeight": {"type": "integer"}, + "weightDevice": {"$ref": "#/definitions/weightdevices"}, + "throttleReadBpsDevice": {"$ref": "#/definitions/throttledevices"}, + "throttleWriteBpsDevice": {"$ref": "#/definitions/throttledevices"}, + "throttleReadIOPSDevice": {"$ref": "#/definitions/throttledevices"}, + "throttleWriteIOPSDevice": {"$ref": "#/definitions/throttledevices"} + } + }, + "hugepagelimits": { + "type": "array", + "items": {"$ref": "#/definitions/hugepagelimit"} + }, + "hugepagelimit": { + "type": "object", + "additionalProperties": false, + "properties": { + "pageSize": {"type": "integer"}, + "limit": {"type": "integer"} + } + }, + "interfacepriorities": { + "type": "array", + "items": {"$ref": "#/definitions/interfacepriority"} + }, + "interfacepriority": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": {"type": "string"}, + "priority": {"type": "integer"} + } + }, + "network": { + "type": "object", + "additionalProperties": false, + "properties": { + "classID": {"type": "integer"}, + "priorities": {"$ref": "#/definitions/interfacepriorities"} + } + }, + "resources": { + "type": "object", + "additionalProperties": false, + "properties": { + "devices": {"$ref": "#/definitions/devicecgroups"}, + "memory": {"$ref": "#/definitions/memory"}, + "cpu": {"$ref": "#/definitions/cpu"}, + "pids": {"$ref": "#/definitions/pids"}, + "blockio": {"$ref": "#/definitions/blockio"}, + "hugepageLimits": {"$ref": "#/definitions/hugepagelimits"}, + "network": {"$ref": "#/definitions/network"} + } + }, "image": { "type": "object", "additionalProperties": false, @@ -107,9 +240,9 @@ var schema = string(` "noNewPrivileges": {"type": "boolean"}, "hostname": {"type": "string"}, "oomScoreAdj": {"type": "integer"}, - "disableOOMKiller": {"type": "boolean"}, "rootfsPropagation": {"type": "string"}, "cgroupsPath": {"type": "string"}, + "resources": {"$ref": "#/definitions/resources"}, "sysctl": { "type": "array", "items": { "$ref": "#/definitions/strings" } diff --git a/test/test.yml b/test/test.yml index d2d210f36..e4385cad8 100644 --- a/test/test.yml +++ b/test/test.yml @@ -30,6 +30,12 @@ services: - CAP_SETGID - CAP_DAC_OVERRIDE net: host + resources: + devices: + - allow: true + access: rwm + pids: + limit: 10 files: - path: etc/docker/daemon.json contents: '{"debug": true}'