docker进阶教程二:cgroup之资源限制

在之前的 docker run 介绍过程中,并没有对使用的资源做任何的限制,这是有风险的。docker本身就提供了一些参数进行对资源的限制,其原理是通过cgroups来做限制的。Linux Cgroups的全称是Linux Control Group。它最主要的作⽤,就是限制⼀个进程组能够使⽤的资源上限,包括CPU、内存、磁盘、⽹络带宽等等。Linux Cgroups就是Linux内核中⽤来为进程设置资源限制的⼀个重要功能。

CPU

前戏

在Linux中,Cgroups给⽤户暴露出来的操作接⼝是⽂件系统,即它以⽂件和⽬录的⽅式组织在操作系统的/sys/fs/cgroup路径下

1
2
3
4
5
6
7
8
9
10
11
12
[root@master ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)

在/sys/fs/cgroup下⾯有很多诸如cpuset、cpu、 memory这样的⼦⽬录,也叫⼦系统。这些都是可以被Cgroups进⾏限制的资源种类。⽽在⼦系统对应的资源种类下,你就可以看到该类资源具体可以被限制的⽅法。

如果熟悉Linux CPU管理的话,你就会在它的输出⾥注意到cfs_period和cfs_quota这样的关键词。这两个参数需要组合使⽤,可以⽤来限制进程在⻓度为cfs_period的⼀段时间内,只能被分配到总量为cfs_quota的CPU时间

我们现在进⼊/sys/fs/cgroup/cpu⽬录下,mkdir container目录之后,⾃动⽣成该⼦系统对应的资源限制⽂件。

1
2
3
4
5
6
[root@master cpu]# cd /sys/fs/cgroup/cpu
[root@master cpu]# mkdir container
[root@master cpu]# cd container
[root@master test]# ls
cgroup.clone_children cpuacct.stat cpuacct.usage_percpu cpu.cfs_quota_us cpu.rt_runtime_us cpu.stat tasks
cgroup.procs cpuacct.usage cpu.cfs_period_us cpu.rt_period_us cpu.shares notify_on_release

然后while : ; do : ; done &运行这个死循环脚本。可以把计算机的CPU吃到100%。如下CPU的占用:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master test]# while : ; do : ; done &
[1] 19729
[root@master test]#
[root@master test]# top -p 19729 -b -n 1
top - 22:26:03 up 108 days, 23:16, 3 users, load average: 0.82, 1.21, 1.18
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4045948 total, 238804 free, 2777664 used, 1029480 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 832176 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND
19729 root 20 0 116640 2940 1280 R 100.0 0.1 0:44.68 1 bash

向container组⾥的cfs_quota⽂件写⼊50 ms(50000 us)echo 50000 >/sys/fs/cgroup/cpu/container/cpu.cfs_quota_us,它意味着在每100 ms的时间⾥,被该控制组限制的进程只能使⽤20 ms的CPU时间,也就是说这个进程只能使⽤到50%的CPU带宽。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master container]# echo 100000 >cpu.cfs_period_us
[root@master container]# echo 50000 >cpu.cfs_quota_us
[root@master container]# echo 19729 >tasks
[root@master container]# top -p 19729 -b -n 1
top - 22:31:14 up 108 days, 23:21, 4 users, load average: 0.61, 0.95, 1.08
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu0 : 37.5 us, 0.0 sy, 6.2 ni, 56.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 6.7 sy, 0.0 ni, 93.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4045948 total, 229300 free, 2782916 used, 1033732 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 826860 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND
19729 root 20 0 116640 2940 1280 R 40.0 0.1 4:53.65 0 bash

把被限制的进程的PID写⼊container组⾥的tasks⽂件/sys/fs/cgroup/cpu/container/tasks,上⾯的设置就会对该进程⽣效了。可以看到 %CPU 被限制在40%。

限制可用的 CPU 个数

以上使用 cpu.cfs_period_us cpu.cfs_quota_us 来设置比较麻烦,在 docker 1.13 及更高的版本上,能够很容易的限制容器可以使用的主机 CPU 个数。只需要通过 --cpus 选项指定容器可以使用的 CPU 个数就可以了,并且还可以指定如 1.5 之类的小数。运行 docker run -it --cpus=1 --name stress --rm progrium/stress --cpu 2 表示限制容器最多使用1个CPU资源,但使用stress压测时使用2个CPU进行压测。

使用 docker stats 是可以看到CPU占用100%,但是使用top去查看的话,会发现会均分在2个CPU核上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master ~]# docker stats stress
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
2178465e8b5d stress 100.35% 168KiB / 3.859GiB 0.00% 648B / 0B 1.55MB / 0B 3

[root@master ~]# top
top - 22:35:50 up 108 days, 23:26, 4 users, load average: 1.96, 0.94, 0.99
Tasks: 167 total, 3 running, 164 sleeping, 0 stopped, 0 zombie
%Cpu0 : 53.0 us, 0.3 sy, 0.3 ni, 44.4 id, 0.0 wa, 0.0 hi, 0.0 si, 2.0 st
%Cpu1 : 49.2 us, 0.6 sy, 0.3 ni, 46.0 id, 0.0 wa, 0.0 hi, 0.0 si, 3.9 st
KiB Mem : 4045948 total, 192024 free, 2805372 used, 1048552 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 804304 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND
20341 root 20 0 7316 96 0 R 51.7 0.0 0:30.36 0 /usr/bin/stress --verbose --cpu 2
20340 root 20 0 7316 96 0 R 48.7 0.0 0:31.15 1 /usr/bin/stress --verbose --cpu 2

所以这个参数是限制不了的,还是会多使用CPU核数的。

固定使用CPU核数

使用 --cpuset-cpus 是可以固定将容器运行在哪个CPU上面。所以此方法非常实用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 在第一个shell窗口上运行以下命令:
[root@master ~]# docker run -it --cpuset-cpus 0 --name stress --rm progrium/stress --cpu 2
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [6] forked
stress: dbug: [1] using backoff sleep of 3000us

#在第二个shell窗口上运行以下命令:
Tasks: 167 total, 4 running, 163 sleeping, 0 stopped, 0 zombie
%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 5.6 us, 11.1 sy, 0.0 ni, 83.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 4045948 total, 185128 free, 2810132 used, 1050688 buff/cache
KiB Swap: 4194300 total, 4194300 free, 0 used. 799600 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND
21302 root 20 0 7316 100 0 R 47.1 0.0 0:35.80 0 stress
21303 root 20 0 7316 100 0 R 47.1 0.0 0:35.80 0 stress

可以看到2个stress进程都被控制到CPU 0上面了。

设置CPU权重

所谓CPU权重,指的是在CPU出现资源紧张的情况下,设置CPU权重让不同的容器获取到不同的CPU使用率。--cpu-shares 选项用来设置 CPU 权重,它的默认值为 1024。我们可以把它设置为 2 表示很低的权重,但是设置为 0 表示使用默认值 1024。值越小权重越小

启动2个容器,stress01绑定到CPU1上,权重为10;stress02也绑定到CPU1上,权重为100,这样出现竞争时,stress02占用了90%的CPU,而stress01占用了10%的CPU,合情合理。

1
2
3
4
5
6
7
8
9
[root@master ~]# docker run -itd --cpuset-cpus 1 --name stress01 --cpu-shares 10 progrium/stress --cpu 1
67ffb0fbef2ac92c85a6717553cb2969dea7b8f0c8fac3f604dd1875cc35a776
[root@master ~]#
[root@master ~]# docker run -itd --cpuset-cpus 1 --name stress02 --cpu-shares 100 progrium/stress --cpu 1
95f4a8a197758202fdc64df41097a01db4b93f03eae53712acc2cd4ec475e831
[root@master ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
95f4a8a19775 stress02 90.74% 140KiB / 3.859GiB 0.00% 648B / 0B 0B / 0B 2
67ffb0fbef2a stress01 8.89% 132KiB / 3.859GiB 0.00% 648B / 0B 0B / 0B 2

内存

默认情况下,docker 并没有对容器内存进行限制,也就是说容器可以使用主机提供的所有内存。这当然是非常危险的事情,如果某个容器运行了恶意的内存消耗软件,或者代码有内存泄露,很可能会导致主机内存耗尽,因此导致服务不可用。对于这种情况,docker 会设置 docker daemon 的 OOM(out of memory) 值,使其在内存不足的时候被杀死的优先级降低。另外,就是你可以为每个容器设置内存使用的上限,一旦超过这个上限,容器会被杀死,而不是耗尽主机的内存。

内存相关参数

在 docker 启动参数中,和内存限制有关的包括(参数的值一般是内存大小,也就是一个正数,后面跟着内存单位 bkmg,分别对应 bytes、KB、MB、和 GB):

  • -m --memory:容器能使用的最大内存大小,最小值为 4m
  • --memory-swap:容器能够使用的 swap 大小
  • --memory-swappiness:默认情况下,主机可以把容器使用的匿名页(anonymous page)swap 出来,你可以设置一个 0-100 之间的值,代表允许 swap 出来的比例
  • --memory-reservation:设置一个内存使用的 soft limit,如果 docker 发现主机内存不足,会执行 OOM 操作。这个值必须小于 --memory 设置的值
  • --kernel-memory:容器能够使用的 kernel memory 大小,最小值为 4m。
  • --oom-kill-disable:是否运行 OOM 的时候杀死容器。只有设置了 -m,才可以把这个选项设置为 false,否则容器会耗尽主机内存,而且导致主机应用被杀死

关于 --memory-swap 的设置必须解释一下,--memory-swap 必须在 --memory 也配置的情况下才能有用。

  • 如果 --memory-swap 的值大于 --memory,那么容器能使用的总内存(内存 + swap)为 --memory-swap 的值。能使用的 swap 值为 --memory-swap 减去 --memory 的值
  • 如果 --memory-swap 为 0,那么容器能使用两倍于内存的 swap 大小,如果 --memory 对应的值是 200M,那么容器可以使用 400M swap
  • 如果 --memory-swap 的值为 -1,那么不限制 swap 的使用,也就是说主机有多少 swap,容器都可以使用

内存实验测试

测试一:不限制swap内存

思路是使用stress工具来做测试,直接运行以下命令:

1
2
3
[fdm@localhost ~]$ docker run -it -m 300M --memory-swap -1 --name stress --rm --entrypoint /bin/bash progrium/stress
root@5f8b1f3fa36b:/# stress --vm 1 --vm-bytes 500M
stress: info: [8] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

上面的 docker run 命令中通过 -m 选项限制容器使用的内存上限为 300M。同时设置 memory-swap 值为 -1,表示可以使用的 swap 空间使用不受限制(宿主机有多少 swap 容器就可以使用多少)。

stress --vm 1 --vm-bytes 500M 表示运行运行一个进程,申请500M的内存。

我们有2种方法进行内存的查看。一是使用docker stats 查看:

1
2
3
4
[fdm@localhost ~]$ docker stats stress

CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
bcc0e6f8bb4e stress 20.64% 299.9MiB / 300MiB 99.98% 656B / 0B 746MB / 932MB 3

可以看到内存成功限制在300M了。

另外还可以在宿主机上面查看。先查出stress运行的PID,再使用top查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
[fdm@localhost ~]$ ps auxwf |grep stress |grep -v grep
fdm 30640 0.0 0.8 441252 53272 pts/1 Sl+ 06:24 0:00 | \_ docker run -it -m 300M --memory-swap -1 --name stress --rm --entrypoint /bin/bash progrium/stress
root 82418 0.0 0.0 7304 340 pts/0 S+ 07:05 0:00 \_ stress --vm 1 --vm-bytes 500M
root 82419 19.5 3.9 519308 253456 pts/0 D+ 07:05 0:27 \_ stress --vm 1 --vm-bytes 500M
[fdm@localhost ~]$ top -b -p 82419 -n 1
top - 07:08:50 up 6 days, 3:54, 2 users, load average: 1.81, 1.19, 0.82
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 6.7 us, 13.3 sy, 0.0 ni, 0.0 id, 80.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 6428736 total, 3616312 free, 1331768 used, 1480656 buff/cache
KiB Swap: 2097148 total, 1735420 free, 361728 used. 4988140 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
82419 root 20 0 519308 267844 188 D 13.3 4.2 0:38.00 stress

由top的输出可以看到,VIRT是500M,就是虚拟内存申请了500M,但实际分配了300M左右的内存。

测试二:swap设置为0

由上参数介绍所知,--memory-swap 0表示2倍的memory大小,即申请300M内存,合计不能超过600M,如下实验,申请了600M内存,直接被系统内核OOM kill了。

1
2
3
4
5
6
7
8
9
10
[fdm@localhost ~]$ docker run -it -m 300M --memory-swap 0 --name stress --rm --entrypoint /bin/bash progrium/stress
root@0152a556c163:/# stress --vm 1 --vm-bytes 590M
stress: info: [8] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
^C
root@0152a556c163:/# stress --vm 1 --vm-bytes 600M
stress: info: [10] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [10] (416) <-- worker 11 got signal 9
stress: WARN: [10] (418) now reaping child worker processes
stress: FAIL: [10] (452) failed run completed in 1s
root@0152a556c163:/#

messages日志就记录了oom_kill_process:

1
2
3
4
[root@localhost ~]# cat /var/log/messages |grep kill
Oct 11 07:32:08 localhost kernel: stress invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=0
Oct 11 07:32:08 localhost kernel: [<ffffffff9a3bfd74>] oom_kill_process+0x254/0x3e0
Oct 11 07:32:08 localhost kernel: Task in /docker/0152a556c163078ff48679a75c2224dda0a1ab2e96de573325ef879d3ed61adf killed as a result of limit of /docker/0152a556c163078ff48679a75c2224dda0a1ab2e96de573325ef879d3ed61adf

测试三:限制swap内存

--memory-swap 有值时,其内存总量不能超过这个值,所以就是说使用swap的总量是 memory-swap - memory 的值。如果是设置了 -m 300M --memory-swap 300M ,这样内存总量就是300M,超过这个值就会被直接OOM了。

1
2
3
4
5
6
7
8
9
10
11
[fdm@localhost ~]$ docker run -it -m 300M --memory-swap 300M --name stress --rm --entrypoint /bin/bash progrium/stress
root@1be3f1d8e63b:/#
root@1be3f1d8e63b:/# stress --vm 1 --vm-bytes 300M
stress: info: [10] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [10] (416) <-- worker 11 got signal 9
stress: WARN: [10] (418) now reaping child worker processes
stress: FAIL: [10] (452) failed run completed in 0s
root@1be3f1d8e63b:/#
root@1be3f1d8e63b:/# stress --vm 1 --vm-bytes 290M
stress: info: [12] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
^C

内存信息的cgroups文件

对于 docker 来说,它的内存限制是存放在 cgroups 文件系统的。对于某个容器,你可以在 sys/fs/cgroup/memory/docker/<container_id> 目录下看到容器内存相关的文件。

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# ls /sys/fs/cgroup/memory/docker/0251c0db55f692c0bdb6de92eacedd57678cf7ba06d5fde6abf9874d34bbdeb5/
memory.failcnt memory.kmem.tcp.limit_in_bytes memory.memsw.limit_in_bytes memory.soft_limit_in_bytes
memory.force_empty memory.kmem.tcp.max_usage_in_bytes memory.memsw.max_usage_in_bytes memory.stat
memory.kmem.failcnt memory.kmem.tcp.usage_in_bytes memory.memsw.usage_in_bytes memory.swappiness
memory.kmem.limit_in_bytes memory.kmem.usage_in_bytes memory.move_charge_at_immigrate memory.usage_in_bytes
memory.kmem.max_usage_in_bytes memory.limit_in_bytes memory.numa_stat memory.use_hierarchy
memory.kmem.slabinfo memory.max_usage_in_bytes memory.oom_control
memory.kmem.tcp.failcnt memory.memsw.failcnt memory.pressure_level
[root@localhost ~]# cat /sys/fs/cgroup/memory/docker/0251c0db55f692c0bdb6de92eacedd57678cf7ba06d5fde6abf9874d34bbdeb5/memory.limit_in_bytes
314572800

硬盘

对于磁盘来说,考量的参数是容量和读写速度,因此对容器的磁盘限制也应该从这两个维度出发。目前 docker 支持对磁盘的读写速度进行限制,但是并没有方法能限制容器能使用的磁盘容量。

block IO 权重

默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。--blkio-weight--cpu-shares 类似,设置的是相对权重值,默认为 500。

限制读写速度

除了权重之外,docker 还允许你直接限制磁盘的读写速率,对应的参数有:

  • --device-read-bps:磁盘每秒最多可以读多少比特(bytes)
  • --device-write-bps:磁盘每秒最多可以写多少比特(bytes)

上面两个参数的值都是磁盘以及对应的速率,格式为 <device-path>:<limit>[unit]device-path表示磁盘所在的位置,限制 limit 为正整数,单位可以是 kbmbgb

另外两个参数可以限制磁盘读写频率(每秒能执行多少次读写操作):

  • --device-read-iops:磁盘每秒最多可以执行多少 IO 读操作
  • --device-write-iops:磁盘每秒最多可以执行多少 IO 写操作

上面两个参数的值都是磁盘以及对应的 IO 上限,格式为 <device-path>:<limit>,limit 为正整数,表示磁盘 IO 上限数。

如下测试,限制读的速度不能超过1MB。

1
2
3
4
5
[root@master ~]# docker run -it --rm --device /dev/sda:/dev/sda --device-read-bps /dev/sda:1MB ubuntu bash
root@e1c19a3a53ab:/# dd iflag=direct,nonblock if=/dev/sda of=/dev/null bs=5M count=10
10+0 records in
10+0 records out
52428800 bytes (52 MB, 50 MiB) copied, 76.1513 s, 688 kB/s

使用iops也是类似,不过bs要设置小块,才能看出效果出来。

1
2
3
4
5
[root@master ~]# docker run -it --rm --device /dev/sda:/dev/sda --device-read-iops /dev/sda:100 ubuntu bash
root@51d31e99f683:/# dd iflag=direct,nonblock if=/dev/sda of=/dev/null bs=1k count=1000
1000+0 records in
1000+0 records out
1024000 bytes (1.0 MB, 1000 KiB) copied, 9.94581 s, 103 kB/s

这是docker原理之一,使用cgroup进行资源隔离。

lxcfs

简介

虽然docker使用了namespace以及cgroup来限制与隔离资源使用情况,但是容器中的top/free/df等命令,展示的状态信息是从/proc目录中的相关文件里读取出来的:

1
2
3
4
5
6
7
/proc/cpuinfo
/proc/diskstats
/proc/meminfo
/proc/stat
/proc/swaps
/proc/uptime
/sys/devices/system/cpu/online

就是说在容器内部proc文件系统中可以看到Host宿主机上的proc信息(如:meminfo, cpuinfo,stat, uptime等)。而LXCFS,FUSE filesystem for LXC是一个常驻服务,它启动以后会在指定目录中自行维护与上面列出的/proc目录中的文件同名的文件,容器从lxcfs维护的/proc文件中读取数据时,得到的是容器的状态数据,而不是整个宿主机的状态。

安装方法

有2种方法,一是通过官方 https://github.com/lxc/lxcfs/releases 编译安装,编译前需要安装 fuse-devel

二是通过rpm包的方法运行安装,目前(20191019)的最新版本为3.1.2,下载之:

1
2
3
wget https://copr-be.cloud.fedoraproject.org/results/ganto/lxc3/epel-7-x86_64/01041891-lxcfs/lxcfs-3.1.2-0.2.el7.x86_64.rpm
yum install lxcfs-3.1.2-0.2.el7.x86_64.rpm
systemctl start lxcfs

运行lxcfs之后,会在 /var/lib/lxcfs 目录下生成一些系统文件

/var/lib/lxcfs
1
2
3
drwxr-xr-x. 2 root root 0 Oct 19 10:18 cgroup
dr-xr-xr-x. 2 root root 0 Oct 19 10:18 proc
dr-xr-xr-x. 2 root root 0 Oct 19 10:18 sys

使用方法

启动一个容器,用lxcfs维护的/proc文件替换容器中的/proc文件,容器内存设置为256M:

1
2
3
4
5
6
7
8
docker run -it -m 256m \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
ubuntu:latest /bin/bash

再查看一个内存,已经被限制到256M了。

1
2
3
4
root@169717adb127:/# free -m
total used free shared buff/cache available
Mem: 256 0 255 0 0 255
Swap: 512 0 512

参考资料

https://docs.docker.com/config/containers/resource_constraints/

使用 docker 对容器资源进行限制

Docker: 限制容器可用的 CPU

Lxcfs是什么? 怎样通过lxcfs在容器内显示容器的CPU、内存状态

  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/k8s/docker-cgroup-limit.html
  • 本文主题: docker进阶教程二:cgroup之资源限制
  • 版权声明: 本博客所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%