[lxc-devel] [lxd/master] containers: add limits.kernel.[limit name] support
brauner on Github
lxc-bot at linuxcontainers.org
Mon Oct 9 10:39:11 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 449 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171009/04a33839/attachment.bin>
-------------- next part --------------
From 551e0f6e8af088da5393dc3285a6dec780eacf4a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 9 Oct 2017 12:16:35 +0200
Subject: [PATCH 1/2] containers: add limits.kernel.[limit name] support
This adds support for liblxc's lxc.prlimit.[limit name] feature.
Closes #3272.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
doc/api-extensions.md | 4 ++++
doc/containers.md | 1 +
lxd/api_1.0.go | 1 +
lxd/container_lxc.go | 24 ++++++++++++++++++++++++
shared/container.go | 5 +++++
5 files changed, 35 insertions(+)
diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 92cc342cc..c9b4ec0c0 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -339,3 +339,7 @@ use by another LXD instance.
## storage\_block\_filesystem\_btrfs
This adds support for btrfs as a storage volume filesystem, in addition to ext4
and xfs.
+
+## kernel\_limits
+This adds support for setting process limits such as maximum number of open
+files for the container via `nofile`. The format is `limits.kernel.[limit name]`.
diff --git a/doc/containers.md b/doc/containers.md
index 591868919..2d3404b86 100644
--- a/doc/containers.md
+++ b/doc/containers.md
@@ -33,6 +33,7 @@ limits.cpu | string | - (all) | yes
limits.cpu.allowance | string | 100% | yes | - | How much of the CPU can be used. Can be a percentage (e.g. 50%) for a soft limit or hard a chunk of time (25ms/100ms)
limits.cpu.priority | integer | 10 (maximum) | yes | - | CPU scheduling priority compared to other containers sharing the same CPUs (overcommit) (integer between 0 and 10)
limits.disk.priority | integer | 5 (medium) | yes | - | When under load, how much priority to give to the container's I/O requests (integer between 0 and 10)
+limits.kernel.\* | string | - | no | kernel\_limits | This limits kernel resources per container (e.g. number of open files)
limits.memory | string | - (all) | yes | - | Percentage of the host's memory or fixed value in bytes (supports kB, MB, GB, TB, PB and EB suffixes)
limits.memory.enforce | string | hard | yes | - | If hard, container can't exceed its memory limit. If soft, the container can exceed its memory limit when extra host memory is available.
limits.memory.swap | boolean | true | yes | - | Whether to allow some of the container's memory to be swapped out to disk
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index 0dd41bfaa..a17d1a111 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -125,6 +125,7 @@ func api10Get(d *Daemon, r *http.Request) Response {
"storage_volatile_initial_source",
"storage_ceph_force_osd_reuse",
"storage_block_filesystem_btrfs",
+ "kernel_limits",
},
APIStatus: "stable",
APIVersion: version.APIVersion,
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index c4f7d761c..ce8918179 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -154,6 +154,12 @@ func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
}
}
+ if strings.HasPrefix(key, "lxc.prlimit.") {
+ if !lxc.VersionAtLeast(2, 1, 0) {
+ return fmt.Errorf(`Process limits require libxc >= 2.1`)
+ }
+ }
+
err := c.SetConfigItem(key, value)
if err != nil {
return fmt.Errorf("Failed to set LXC config: %s=%s", key, value)
@@ -198,6 +204,12 @@ func lxcValidConfig(rawLxc string) error {
return fmt.Errorf("Setting lxc.ephemeral is not allowed")
}
+ if strings.HasPrefix(key, "lxc.prlimit.") {
+ return fmt.Errorf(`Process limits should be set via ` +
+ `"limits.kernel.[limit name]" and not ` +
+ `directly via "lxc.prlimit.[limit name]"`)
+ }
+
networkKeyPrefix := "lxc.net."
if !lxc.VersionAtLeast(2, 1, 0) {
networkKeyPrefix = "lxc.network."
@@ -1284,6 +1296,18 @@ func (c *containerLXC) initLXC() error {
}
}
+ // Setup process limits
+ for k, v := range c.expandedConfig {
+ if strings.HasPrefix(k, "limits.kernel.") {
+ prlimitSuffix := strings.TrimPrefix(k, "limits.kernel.")
+ prlimitKey := fmt.Sprintf("lxc.prlimit.%s", prlimitSuffix)
+ err = lxcSetConfigItem(cc, prlimitKey, v)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
// Setup devices
networkidx := 0
for _, k := range c.expandedDevices.DeviceNames() {
diff --git a/shared/container.go b/shared/container.go
index 96a348b17..94835dcc5 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -231,5 +231,10 @@ func ConfigKeyChecker(key string) (func(value string) error, error) {
return IsAny, nil
}
+ if strings.HasPrefix(key, "limits.kernel.") &&
+ (len(key) > len("limits.kernel.")) {
+ return IsAny, nil
+ }
+
return nil, fmt.Errorf("Bad key: %s", key)
}
From ad268b9444c6322e875d146049870d5fede0d250 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 9 Oct 2017 12:37:14 +0200
Subject: [PATCH 2/2] tests: api extension kernel_limits
Closes #3272.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
test/main.sh | 1 +
test/suites/kernel_limits.sh | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
create mode 100644 test/suites/kernel_limits.sh
diff --git a/test/main.sh b/test/main.sh
index c49b481ec..9b76f3faa 100755
--- a/test/main.sh
+++ b/test/main.sh
@@ -184,6 +184,7 @@ run_test test_storage_profiles "storage profiles"
run_test test_container_import "container import"
run_test test_storage_volume_attach "attaching storage volumes"
run_test test_storage_driver_ceph "ceph storage driver"
+run_test test_kernel_limits "kernel limits"
# shellcheck disable=SC2034
TEST_RESULT=success
diff --git a/test/suites/kernel_limits.sh b/test/suites/kernel_limits.sh
new file mode 100644
index 000000000..8873c5ea5
--- /dev/null
+++ b/test/suites/kernel_limits.sh
@@ -0,0 +1,17 @@
+test_kernel_limits() {
+ echo "==> API extension kernel_limits"
+
+ ensure_import_testimage
+ lxc init testimage limits
+ # Set it to a limit < 65536 because older systemd's do not have my nofile
+ # limit patch.
+ lxc config set limits limits.kernel.nofile 3000
+ lxc start limits
+ pid=$(lxc info limits | grep ^Pid | awk '{print $2}')
+ soft=$(cat /proc/"${pid}"/limits | grep ^"Max open files" | awk '{print $4}')
+ hard=$(cat /proc/"${pid}"/limits | grep ^"Max open files" | awk '{print $5}')
+
+ lxc delete --force limits
+
+ [ "${soft}" = "3000" ] && [ "${hard}" = "3000" ]
+}
More information about the lxc-devel
mailing list