From 1e26a8c5d18eb93c2786eff9eeede77f3b8162df Mon Sep 17 00:00:00 2001 From: lujingxiao Date: Sat, 19 Jan 2019 11:14:23 +0800 Subject: [PATCH 007/111] filelimit: Add file fds limit Change-Id: I4255fc648ad71dcba78fe38fae9d26454e2e41d8 Signed-off-by: yangshukui Signed-off-by: lujingxiao --- components/cli/cli/command/container/opts.go | 3 +++ components/cli/contrib/completion/bash/docker | 1 + components/cli/contrib/completion/zsh/_docker | 1 + .../cli/docs/reference/commandline/create.md | 1 + components/cli/docs/reference/commandline/run.md | 1 + components/cli/man/docker-run.1.md | 4 ++++ .../vendor/github.com/docker/docker/api/Checklist | 1 + .../docker/api/types/container/host_config.go | 1 + .../engine/api/types/container/host_config.go | 1 + components/engine/daemon/daemon_unix.go | 6 ++++++ components/engine/daemon/oci_linux.go | 3 +++ .../integration-cli/docker_cli_run_unix_test.go | 10 ++++++++++ .../integration-cli/requirements_unix_test.go | 4 ++++ components/engine/pkg/sysinfo/sysinfo.go | 6 ++++++ components/engine/pkg/sysinfo/sysinfo_linux.go | 15 +++++++++++++++ .../opencontainers/runtime-spec/Checklist | 1 + .../runtime-spec/specs-go/config.go | 8 ++++++++ 17 files changed, 67 insertions(+) create mode 100644 components/cli/vendor/github.com/docker/docker/api/Checklist create mode 100644 components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go index 97906b6722..efb28a2cdf 100644 --- a/components/cli/cli/command/container/opts.go +++ b/components/cli/cli/command/container/opts.go @@ -100,6 +100,7 @@ type containerOptions struct { ipv6Address string ipcMode string pidsLimit int64 + filesLimit int64 restartPolicy string readonlyRootfs bool loggingDriver string @@ -271,6 +272,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.BoolVar(&copts.oomKillDisable, "oom-kill-disable", false, "Disable OOM Killer") flags.IntVar(&copts.oomScoreAdj, "oom-score-adj", 0, "Tune host's OOM preferences (-1000 to 1000)") flags.Int64Var(&copts.pidsLimit, "pids-limit", 0, "Tune container pids limit (set -1 for unlimited)") + flags.Int64Var(&copts.filesLimit, "files-limit", 0, "Tune container files limit (set -1 for unlimited)") // Low-level execution (cgroups, namespaces, ...) flags.StringVar(&copts.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container") @@ -531,6 +533,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err CPURealtimePeriod: copts.cpuRealtimePeriod, CPURealtimeRuntime: copts.cpuRealtimeRuntime, PidsLimit: copts.pidsLimit, + FilesLimit: copts.filesLimit, BlkioWeight: copts.blkioWeight, BlkioWeightDevice: copts.blkioWeightDevice.GetList(), BlkioDeviceReadBps: copts.deviceReadBps.GetList(), diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 44ac8f3e0e..2e2c8cb04f 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -1789,6 +1789,7 @@ _docker_container_run_and_create() { --env -e --env-file --expose + --files-limit --group-add --health-cmd --health-interval diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker index 94f042204d..cbbdfdb798 100644 --- a/components/cli/contrib/completion/zsh/_docker +++ b/components/cli/contrib/completion/zsh/_docker @@ -621,6 +621,7 @@ __docker_container_subcommand() { "($help)--entrypoint=[Overwrite the default entrypoint of the image]:entry point: " "($help)*--env-file=[Read environment variables from a file]:environment file:_files" "($help)*--expose=[Expose a port from the container without publishing it]: " + "($help)--files-limit[Tune container files limit (set -1 for max)]" "($help)*--group=[Set one or more supplementary user groups for the container]:group:_groups" "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts" "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" diff --git a/components/cli/docs/reference/commandline/create.md b/components/cli/docs/reference/commandline/create.md index d585da40ae..5d888183b3 100644 --- a/components/cli/docs/reference/commandline/create.md +++ b/components/cli/docs/reference/commandline/create.md @@ -57,6 +57,7 @@ Options: -e, --env value Set environment variables (default []) --env-file value Read in a file of environment variables (default []) --expose value Expose a port or a range of ports (default []) + --files-limit int Tune container files limit (set -1 for unlimited) --group-add value Add additional groups to join (default []) --health-cmd string Command to run to check health --health-interval duration Time between running the check (ns|us|ms|s|m|h) (default 0s) diff --git a/components/cli/docs/reference/commandline/run.md b/components/cli/docs/reference/commandline/run.md index 08b9f18d68..21b4fdf261 100644 --- a/components/cli/docs/reference/commandline/run.md +++ b/components/cli/docs/reference/commandline/run.md @@ -61,6 +61,7 @@ Options: -e, --env value Set environment variables (default []) --env-file value Read in a file of environment variables (default []) --expose value Expose a port or a range of ports (default []) + --files-limit int Tune container files limit (set -1 for unlimited) --group-add value Add additional groups to join (default []) --health-cmd string Command to run to check health --health-interval duration Time between running the check (ns|us|ms|s|m|h) (default 0s) diff --git a/components/cli/man/docker-run.1.md b/components/cli/man/docker-run.1.md index e03377001d..41f501d5b9 100644 --- a/components/cli/man/docker-run.1.md +++ b/components/cli/man/docker-run.1.md @@ -39,6 +39,7 @@ docker-run - Run a command in a new container [**--entrypoint**[=*ENTRYPOINT*]] [**--env-file**[=*[]*]] [**--expose**[=*[]*]] +[**--files-limit**[=*FILES_LIMIT*]] [**--group-add**[=*[]*]] [**-h**|**--hostname**[=*HOSTNAME*]] [**--help**] @@ -315,6 +316,9 @@ that the container listens on the specified network ports at runtime. Docker uses this information to interconnect containers using links and to set up port redirection on the host system. +**--files-limit**="" + Tune the container's files limit. Set `-1` to have max files for the container. + **--group-add**=[] Add additional groups to run as diff --git a/components/cli/vendor/github.com/docker/docker/api/Checklist b/components/cli/vendor/github.com/docker/docker/api/Checklist new file mode 100644 index 0000000000..9594f235e4 --- /dev/null +++ b/components/cli/vendor/github.com/docker/docker/api/Checklist @@ -0,0 +1 @@ +Add FilesLimit to components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go for supporting --files-limit diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go index 4ef26fa6c8..1565b5e091 100644 --- a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go +++ b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go @@ -334,6 +334,7 @@ type Resources struct { MemorySwappiness *int64 // Tuning container memory swappiness behaviour OomKillDisable *bool // Whether to disable OOM Killer or not PidsLimit int64 // Setting pids limit for a container + FilesLimit int64 // Setting files limit for a container Ulimits []*units.Ulimit // List of ulimits to be set in the container // Applicable to Windows diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go index 4ef26fa6c8..1565b5e091 100644 --- a/components/engine/api/types/container/host_config.go +++ b/components/engine/api/types/container/host_config.go @@ -334,6 +334,7 @@ type Resources struct { MemorySwappiness *int64 // Tuning container memory swappiness behaviour OomKillDisable *bool // Whether to disable OOM Killer or not PidsLimit int64 // Setting pids limit for a container + FilesLimit int64 // Setting files limit for a container Ulimits []*units.Ulimit // List of ulimits to be set in the container // Applicable to Windows diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go index 1b35df4950..138b8ac544 100644 --- a/components/engine/daemon/daemon_unix.go +++ b/components/engine/daemon/daemon_unix.go @@ -425,6 +425,12 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi resources.PidsLimit = 0 } + if resources.FilesLimit != 0 && !sysInfo.FilesLimit { + warnings = append(warnings, "Your kernel does not support files limit capabilities, files limit discarded.") + logrus.Warnf("Your kernel does not support files limit capabilities, files limit discarded.") + resources.FilesLimit = 0 + } + // cpu subsystem checks and adjustments if resources.NanoCPUs > 0 && resources.CPUPeriod > 0 { return warnings, fmt.Errorf("Conflicting options: Nano CPUs and CPU Period cannot both be set") diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go index 864d22fbcb..210d2ad3f6 100644 --- a/components/engine/daemon/oci_linux.go +++ b/components/engine/daemon/oci_linux.go @@ -70,6 +70,9 @@ func setResources(s *specs.Spec, r containertypes.Resources) error { Pids: &specs.LinuxPids{ Limit: r.PidsLimit, }, + Files: &specs.Files{ + Limit: &r.FilesLimit, + }, } if s.Linux.Resources != nil && len(s.Linux.Resources.Devices) > 0 { diff --git a/components/engine/integration-cli/docker_cli_run_unix_test.go b/components/engine/integration-cli/docker_cli_run_unix_test.go index 5f782ee530..a618316d4b 100644 --- a/components/engine/integration-cli/docker_cli_run_unix_test.go +++ b/components/engine/integration-cli/docker_cli_run_unix_test.go @@ -1414,6 +1414,16 @@ func (s *DockerSuite) TestRunPIDsLimit(c *check.C) { c.Assert(out, checker.Equals, "4", check.Commentf("setting the pids limit failed")) } +// TestRunFilesLimit makes sure the files cgroup is set with --files-limit +func (s *DockerSuite) TestRunFilesLimit(c *check.C) { + testRequires(c, filesLimit) + file := "/sys/fs/cgroup/files/files.limit" + out, _ := dockerCmd(c, "run", "--name", "fileslimit", "--files-limit", "32", "busybox", "cat", file) + c.Assert(strings.TrimSpace(out), checker.Equals, "32") + out = inspectField(c, "fileslimit", "HostConfig.FilesLimit") + c.Assert(out, checker.Equals, "32", check.Commentf("setting the files limit failed")) +} + func (s *DockerSuite) TestRunPrivilegedAllowedDevices(c *check.C) { testRequires(c, DaemonIsLinux, NotUserNamespace) diff --git a/components/engine/integration-cli/requirements_unix_test.go b/components/engine/integration-cli/requirements_unix_test.go index 7c594f7db4..873c1fbfe2 100644 --- a/components/engine/integration-cli/requirements_unix_test.go +++ b/components/engine/integration-cli/requirements_unix_test.go @@ -37,6 +37,10 @@ func pidsLimit() bool { return SysInfo.PidsLimit } +func filesLimit() bool { + return SysInfo.FilesLimit +} + func kernelMemorySupport() bool { return testEnv.DaemonInfo.KernelMemory } diff --git a/components/engine/pkg/sysinfo/sysinfo.go b/components/engine/pkg/sysinfo/sysinfo.go index 0f327d5068..5d9320218c 100644 --- a/components/engine/pkg/sysinfo/sysinfo.go +++ b/components/engine/pkg/sysinfo/sysinfo.go @@ -15,6 +15,7 @@ type SysInfo struct { cgroupBlkioInfo cgroupCpusetInfo cgroupPids + cgroupFiles // Whether IPv4 forwarding is supported or not, if this was disabled, networking will not work IPv4ForwardingDisabled bool @@ -102,6 +103,11 @@ type cgroupPids struct { PidsLimit bool } +type cgroupFiles struct { + // Whether Files Limit is supported or not + FilesLimit bool +} + // IsCpusetCpusAvailable returns `true` if the provided string set is contained // in cgroup's cpuset.cpus set, `false` otherwise. // If error is not nil a parsing error occurred. diff --git a/components/engine/pkg/sysinfo/sysinfo_linux.go b/components/engine/pkg/sysinfo/sysinfo_linux.go index dde5be19bc..c0bf280412 100644 --- a/components/engine/pkg/sysinfo/sysinfo_linux.go +++ b/components/engine/pkg/sysinfo/sysinfo_linux.go @@ -40,6 +40,7 @@ func New(quiet bool) *SysInfo { sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) sysInfo.cgroupPids = checkCgroupPids(quiet) + sysInfo.cgroupFiles = checkCgroupFiles(quiet) } _, ok := cgMounts["devices"] @@ -240,6 +241,20 @@ func checkCgroupPids(quiet bool) cgroupPids { } } +// checkCgroupPids reads the files information from the pids cgroup mount point. +func checkCgroupFiles(quiet bool) cgroupFiles { + _, err := cgroups.FindCgroupMountpoint("files") + if err != nil { + if !quiet { + logrus.Warn(err) + } + return cgroupFiles{} + } + return cgroupFiles{ + FilesLimit: true, + } +} + func cgroupEnabled(mountPoint, name string) bool { _, err := os.Stat(path.Join(mountPoint, name)) return err == nil diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist b/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist new file mode 100644 index 0000000000..5b7ba2fab9 --- /dev/null +++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist @@ -0,0 +1 @@ +Add struct LinuxFiles to components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go for supporting --files-limit diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go index f32698cab2..46049b3bfa 100644 --- a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go +++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go @@ -314,6 +314,12 @@ type LinuxPids struct { Limit int64 `json:"limit"` } +// Files for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/) +type Files struct { + // Maximum number of open files. Default is "no limit". + Limit *int64 `json:"limit,omitempty"` +} + // LinuxNetwork identification and priority configuration type LinuxNetwork struct { // Set class identifier for container's network packets @@ -340,6 +346,8 @@ type LinuxResources struct { CPU *LinuxCPU `json:"cpu,omitempty"` // Task resource restriction configuration. Pids *LinuxPids `json:"pids,omitempty"` + // Files resource restriction configuration. + Files *Files `json:"files,omitempty"` // BlockIO restriction configuration BlockIO *LinuxBlockIO `json:"blockIO,omitempty"` // Hugetlb limit (in bytes) -- 2.17.1