如何限制Docker总资源?

如何限制Docker总资源?

我试图限制可从 docker 访问的总资源(例如仅 90% 的 RAM 和 1500% 的 CPU)。当我启动容器时,我无法使用 CPU 和 RAM 限制,这就是为什么我需要限制 docker 容器可用的总资源。

我有大约 20 个容器,它们可以消耗最大的 CPU 和内存,但不能同时使用,所以我无法设置 CPU 和 RAM 限制,这就是为什么我需要限制 docker 使用的总资源

首先,我创建了一个切片:我尝试了上面的指令,但无法同时限制 RAM 和 CPU 使用率

# /etc/systemd/system/docker_limit.slice
[Unit]
Description=Slice that limits docker resources
Before=slices.target

[Slice]
CPUAccounting=true
CPUQuota=700%
#Memory Management
MemoryAccounting=true
MemoryHigh=20G
MemoryMax=25G
MemoryMaxSwap=10G

还有我的 daemon.json

{
  "insecure-registries" : [ "url1", "url2"],
  "cgroup-parent": "docker_limit.slice"
}

但是当我从容器中尝试时:

stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

我可以从 docker stats 看到它正在使用 111Go 的 Ram(我的服务器的全部容量)

stress --cpu 16

我可以从 docker stats 看到它的使用率接近 1600%(我的服务器的全部容量)

我想我错过了一些东西,但我不知道是什么

答案1

对于其他需要这个问题完整答案的人,我正在做一个完整的回顾:

首先,我创建了一个名为 docker_limit 的切片:

  1. 创建一个文件以/etc/systemd/system/docker_limit.slice

    [Unit]
    Description=Slice that limits docker resources
    Before=slices.target
    
    [Slice]
    CPUAccounting=true
    CPUQuota=700%
    #Memory Management
    MemoryAccounting=true
    MemoryLimit=25G
    
  2. 启动单位:systemctl start docker_limit.slice

  3. 编辑/etc/docker/daemon.json

    {
      "cgroup-parent": "docker_limit.slice"
    }
    
  4. 重新启动 Docker 守护进程:systemctl restart docker

为了验证所有工作是否按预期进行:systemd-cgtop,您应该看到 下列出的进程docker_limit.slice。例如: 在此输入图像描述

归功于@rwos

答案2

cgroup_parent在 in/etc/docker/daemon.json前面加上 a前缀/,因此 cgroup 名称是绝对的。否则,docker 会将容器放入守护进程 cgroup 的子 cgroup 中:

{
    "cgroup-parent": "/docker_limit.slice"
}

如果没有/,根据您的系统,容器可能最终会出现在/system.slice/containerd.service/docker_limit.slice或类似的情况下。

systemd-cgtop或者systemd-cgls可以用来检查事情最终运行的位置。

答案3

我有一个具有 1 个 CPU 和 2GB RAM(禁用交换)的虚拟机。
因此,我使用以下参数创建了切片:

# cat /etc/systemd/system/docker_limit.slice
[Unit]
Description=Slice that limits docker resources
Before=slices.target

[Slice]
CPUAccounting=true
CPUQuota=90%
MemoryAccounting=true
MemoryHigh=1G
MemoryMax=1.2G

我做了和你一样的事情,除了守护进程中的本机 cgroupdriver:

# cat /etc/docker/daemon.json 
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "cgroup-parent": "docker_limit.slice"
}

然后我运行 docker 容器:

docker run --name stress-test -d ubuntu:18.04 sleep 10000

并在 2 个窗口中打开我的虚拟机。在第一个窗口中,我跑了stress。在第二个窗口中,我运行了docker stats command. CPU 约为 90%+-(htop 确认了这一点,我看到一些峰值高达 91%),当 RAM 接近 1.2G 时,该进程退出并显示以下消息:

# stress --cpu 1 --vm 1 --vm-bytes 1300M
stress: info: [334] dispatching hogs: 1 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [334] (415) <-- worker 336 got signal 9
stress: WARN: [334] (417) now reaping child worker processes
stress: FAIL: [334] (451) failed run completed in 4s

答案4

rwos 提出的上述建议(不幸的是我无法直接评论该帖子)对我不起作用。

在 /etc/docker/daemon.json 中的 cgroup_parent 前面加上 / 前缀,因此 cgroup 名称是绝对名称。

我收到此错误:

来自守护程序的错误响应:无法为容器创建任务:无法创建 shim 任务:OCI 运行时创建失败:runc 创建失败:切片名称无效:/docker_limit.slice:未知

如果没有“/”前缀,我的 docker 容器就会启动。有了它,他们就不会了。

相关内容