mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add ulimits support to services
Add Ulimits field to the ContainerSpec API type and wire it to Swarmkit. This is related to #40639. Signed-off-by: Albin Kerouanton <albin@akerouanton.name>
This commit is contained in:
parent
1fdb1033c4
commit
c76f380bea
7 changed files with 81 additions and 1 deletions
|
@ -97,10 +97,11 @@ func adjustForAPIVersion(cliVersion string, service *swarm.ServiceSpec) {
|
||||||
}
|
}
|
||||||
if versions.LessThan(cliVersion, "1.41") {
|
if versions.LessThan(cliVersion, "1.41") {
|
||||||
if service.TaskTemplate.ContainerSpec != nil {
|
if service.TaskTemplate.ContainerSpec != nil {
|
||||||
// Capabilities for docker swarm services weren't
|
// Capabilities and Ulimits for docker swarm services weren't
|
||||||
// supported before API version 1.41
|
// supported before API version 1.41
|
||||||
service.TaskTemplate.ContainerSpec.CapabilityAdd = nil
|
service.TaskTemplate.ContainerSpec.CapabilityAdd = nil
|
||||||
service.TaskTemplate.ContainerSpec.CapabilityDrop = nil
|
service.TaskTemplate.ContainerSpec.CapabilityDrop = nil
|
||||||
|
service.TaskTemplate.ContainerSpec.Ulimits = nil
|
||||||
}
|
}
|
||||||
if service.TaskTemplate.Resources != nil && service.TaskTemplate.Resources.Limits != nil {
|
if service.TaskTemplate.Resources != nil && service.TaskTemplate.Resources.Limits != nil {
|
||||||
// Limits.Pids not supported before API version 1.41
|
// Limits.Pids not supported before API version 1.41
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/go-units"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAdjustForAPIVersion(t *testing.T) {
|
func TestAdjustForAPIVersion(t *testing.T) {
|
||||||
|
@ -39,6 +40,13 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
||||||
ConfigName: "configRuntime",
|
ConfigName: "configRuntime",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Ulimits: []*units.Ulimit{
|
||||||
|
{
|
||||||
|
Name: "nofile",
|
||||||
|
Soft: 100,
|
||||||
|
Hard: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Placement: &swarm.Placement{
|
Placement: &swarm.Placement{
|
||||||
MaxReplicas: 222,
|
MaxReplicas: 222,
|
||||||
|
@ -78,6 +86,10 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
||||||
t.Error("MaxReplicas was stripped from spec")
|
t.Error("MaxReplicas was stripped from spec")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(spec.TaskTemplate.ContainerSpec.Ulimits) == 0 {
|
||||||
|
t.Error("Ulimits were stripped from spec")
|
||||||
|
}
|
||||||
|
|
||||||
// next, does calling this with an earlier version correctly strip fields?
|
// next, does calling this with an earlier version correctly strip fields?
|
||||||
adjustForAPIVersion("1.29", spec)
|
adjustForAPIVersion("1.29", spec)
|
||||||
if spec.TaskTemplate.ContainerSpec.Sysctls != nil {
|
if spec.TaskTemplate.ContainerSpec.Sysctls != nil {
|
||||||
|
@ -100,4 +112,8 @@ func TestAdjustForAPIVersion(t *testing.T) {
|
||||||
t.Error("MaxReplicas was not stripped from spec")
|
t.Error("MaxReplicas was not stripped from spec")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(spec.TaskTemplate.ContainerSpec.Ulimits) != 0 {
|
||||||
|
t.Error("Ulimits were not stripped from spec")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3306,6 +3306,22 @@ definitions:
|
||||||
type: "string"
|
type: "string"
|
||||||
example:
|
example:
|
||||||
- "CAP_NET_RAW"
|
- "CAP_NET_RAW"
|
||||||
|
Ulimits:
|
||||||
|
description: |
|
||||||
|
A list of resource limits to set in the container. For example: `{"Name": "nofile", "Soft": 1024, "Hard": 2048}`"
|
||||||
|
type: "array"
|
||||||
|
items:
|
||||||
|
type: "object"
|
||||||
|
properties:
|
||||||
|
Name:
|
||||||
|
description: "Name of ulimit"
|
||||||
|
type: "string"
|
||||||
|
Soft:
|
||||||
|
description: "Soft limit"
|
||||||
|
type: "integer"
|
||||||
|
Hard:
|
||||||
|
description: "Hard limit"
|
||||||
|
type: "integer"
|
||||||
NetworkAttachmentSpec:
|
NetworkAttachmentSpec:
|
||||||
description: |
|
description: |
|
||||||
Read-only spec type for non-swarm containers attached to swarm overlay
|
Read-only spec type for non-swarm containers attached to swarm overlay
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
|
"github.com/docker/go-units"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
|
// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
|
||||||
|
@ -75,4 +76,5 @@ type ContainerSpec struct {
|
||||||
Sysctls map[string]string `json:",omitempty"`
|
Sysctls map[string]string `json:",omitempty"`
|
||||||
CapabilityAdd []string `json:",omitempty"`
|
CapabilityAdd []string `json:",omitempty"`
|
||||||
CapabilityDrop []string `json:",omitempty"`
|
CapabilityDrop []string `json:",omitempty"`
|
||||||
|
Ulimits []*units.Ulimit `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
mounttypes "github.com/docker/docker/api/types/mount"
|
mounttypes "github.com/docker/docker/api/types/mount"
|
||||||
types "github.com/docker/docker/api/types/swarm"
|
types "github.com/docker/docker/api/types/swarm"
|
||||||
|
"github.com/docker/go-units"
|
||||||
swarmapi "github.com/docker/swarmkit/api"
|
swarmapi "github.com/docker/swarmkit/api"
|
||||||
gogotypes "github.com/gogo/protobuf/types"
|
gogotypes "github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -39,6 +40,7 @@ func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
|
||||||
Sysctls: c.Sysctls,
|
Sysctls: c.Sysctls,
|
||||||
CapabilityAdd: c.CapabilityAdd,
|
CapabilityAdd: c.CapabilityAdd,
|
||||||
CapabilityDrop: c.CapabilityDrop,
|
CapabilityDrop: c.CapabilityDrop,
|
||||||
|
Ulimits: ulimitsFromGRPC(c.Ulimits),
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.DNSConfig != nil {
|
if c.DNSConfig != nil {
|
||||||
|
@ -267,6 +269,7 @@ func containerToGRPC(c *types.ContainerSpec) (*swarmapi.ContainerSpec, error) {
|
||||||
Sysctls: c.Sysctls,
|
Sysctls: c.Sysctls,
|
||||||
CapabilityAdd: c.CapabilityAdd,
|
CapabilityAdd: c.CapabilityAdd,
|
||||||
CapabilityDrop: c.CapabilityDrop,
|
CapabilityDrop: c.CapabilityDrop,
|
||||||
|
Ulimits: ulimitsToGRPC(c.Ulimits),
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.DNSConfig != nil {
|
if c.DNSConfig != nil {
|
||||||
|
@ -471,3 +474,31 @@ func isolationToGRPC(i container.Isolation) swarmapi.ContainerSpec_Isolation {
|
||||||
}
|
}
|
||||||
return swarmapi.ContainerIsolationDefault
|
return swarmapi.ContainerIsolationDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ulimitsFromGRPC(u []*swarmapi.ContainerSpec_Ulimit) []*units.Ulimit {
|
||||||
|
ulimits := make([]*units.Ulimit, len(u))
|
||||||
|
|
||||||
|
for i, ulimit := range u {
|
||||||
|
ulimits[i] = &units.Ulimit{
|
||||||
|
Name: ulimit.Name,
|
||||||
|
Soft: ulimit.Soft,
|
||||||
|
Hard: ulimit.Hard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulimits
|
||||||
|
}
|
||||||
|
|
||||||
|
func ulimitsToGRPC(u []*units.Ulimit) []*swarmapi.ContainerSpec_Ulimit {
|
||||||
|
ulimits := make([]*swarmapi.ContainerSpec_Ulimit, len(u))
|
||||||
|
|
||||||
|
for i, ulimit := range u {
|
||||||
|
ulimits[i] = &swarmapi.ContainerSpec_Ulimit{
|
||||||
|
Name: ulimit.Name,
|
||||||
|
Soft: ulimit.Soft,
|
||||||
|
Hard: ulimit.Hard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulimits
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
executorpkg "github.com/docker/docker/daemon/cluster/executor"
|
||||||
clustertypes "github.com/docker/docker/daemon/cluster/provider"
|
clustertypes "github.com/docker/docker/daemon/cluster/provider"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
|
"github.com/docker/go-units"
|
||||||
netconst "github.com/docker/libnetwork/datastore"
|
netconst "github.com/docker/libnetwork/datastore"
|
||||||
"github.com/docker/swarmkit/agent/exec"
|
"github.com/docker/swarmkit/agent/exec"
|
||||||
"github.com/docker/swarmkit/api"
|
"github.com/docker/swarmkit/api"
|
||||||
|
@ -438,6 +439,15 @@ func (c *containerConfig) resources() enginecontainer.Resources {
|
||||||
resources.PidsLimit = &pidsLimit
|
resources.PidsLimit = &pidsLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resources.Ulimits = make([]*units.Ulimit, len(c.spec().Ulimits))
|
||||||
|
for i, ulimit := range c.spec().Ulimits {
|
||||||
|
resources.Ulimits[i] = &units.Ulimit{
|
||||||
|
Name: ulimit.Name,
|
||||||
|
Soft: ulimit.Soft,
|
||||||
|
Hard: ulimit.Hard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If no limits are specified let the engine use its defaults.
|
// If no limits are specified let the engine use its defaults.
|
||||||
//
|
//
|
||||||
// TODO(aluzzardi): We might want to set some limits anyway otherwise
|
// TODO(aluzzardi): We might want to set some limits anyway otherwise
|
||||||
|
|
|
@ -76,6 +76,10 @@ keywords: "API, Docker, rcli, REST, documentation"
|
||||||
single set of stats instead of waiting for two collection cycles to have 2 CPU stats over a 1 second period.
|
single set of stats instead of waiting for two collection cycles to have 2 CPU stats over a 1 second period.
|
||||||
* The `KernelMemory` field in `HostConfig.Resources` is now deprecated.
|
* The `KernelMemory` field in `HostConfig.Resources` is now deprecated.
|
||||||
* The `KernelMemory` field in `Info` is now deprecated.
|
* The `KernelMemory` field in `Info` is now deprecated.
|
||||||
|
* `GET /services` now returns `Ulimits` as part of `ContainerSpec`.
|
||||||
|
* `GET /services/{id}` now returns `Ulimits` as part of `ContainerSpec`.
|
||||||
|
* `POST /services/create` now accepts `Ulimits` as part of `ContainerSpec`.
|
||||||
|
* `POST /services/{id}/update` now accepts `Ulimits` as part of `ContainerSpec`.
|
||||||
|
|
||||||
## v1.40 API changes
|
## v1.40 API changes
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue