首页 > 云计算 > 虚拟化 > 【实战】Docker容器资源管理
注意:我们假设你在一个systemd可用的系统上运行了 Docker。如果你是使用RHEL/CentOS 7+或Fedora 19+,systemd肯定可用,但是请注意在不同的systemd版本之间可能配置选项会有变化。有疑问时,使用你所工作的系统的systemd的帮助说明。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
$ systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
├─machine.slice
│ └─machine-qemu\x2drhel7.scope
│ └─29898 /usr/bin/qemu-system-x86_64 -machine accel=kvm -name rhel7 -S -machine pc-i440fx-1.6,accel=kvm,usb=off -cpu SandyBridge -m 2048
├─system.slice
│ ├─avahi-daemon.service
│ │ ├─ 905 avahi-daemon: running [mistress.local
│ │ └─1055 avahi-daemon: chroot helpe
│ ├─dbus.service
│ │ └─890 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
│ ├─firewalld.service
│ │ └─887 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
│ ├─lvm2-lvmetad.service
│ │ └─512 /usr/sbin/lvmetad -f
│ ├─abrtd.service
│ │ └─909 /usr/sbin/abrtd -d -s
│ ├─wpa_supplicant.service
│ │ └─1289 /usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf -u -f /var/log/wpa_supplica
│ ├─systemd-machined.service
│ │ └─29899 /usr/lib/systemd/systemd-machined
[SNIP]
|
注意:如果你想知道更多关于systemd的知识,我强烈推荐RHEL 7的 Resource Management and Linux Containers Guide(资源管理与Linux容器指南)。
|
1
2
3
|
FROM fedora:latest
RUN yum -y install stress && yum clean all
ENTRYPOINT ["stress"]
|
|
1
2
3
4
5
6
7
8
9
10
|
$ systemd-cgtop
Path Tasks %CPU Memory Input/s Output/s
/ 226 13.0 6.7G - -
/system.slice 47 2.2 16.0M - -
/system.slice/gdm.service 2 2.1 - - -
/system.slice/rngd.service 1 0.0 - - -
/system.slice/NetworkManager.service 2 - - - -
[SNIP]
|
|
1
2
|
$ docker run -it --rm stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
|
|
1
2
|
$ docker run -it --rm -c 512 stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
|
注意:丢失的约10%CPU被GNOME、Chrome和我的音乐播放器使用了。
|
1
|
docker run -it --rm --cpuset=0 stress --cpu 1
|
|
1
|
docker run -it --rm --cpuset=0,1 stress --cpu 2
|
注意:Share enforcement仅仅发生在当进程运行在相同的核上的时候。这意味着如果你把一个容器固定在第一个核,而把另外一个容器固定在另外一个核,两个都将 使用各自核的 100%,即使它们有不同的CPU配额设置(再次声明,我假设仅仅有两个容器运行在主机上)。
|
1
|
$ sudo systemctl set-property docker-4be96b853089bc6044b29cb873cac460b429cfcbdd0e877c0868eb2a901dbf80.scope CPUShares=512
|
注意:添加--runtime暂时地改变设置。否则,当主机重启后,这个设置会被记住。把默认值从1024变更到512。你可以看到下面的结果。这一变化发生在记录中。请注意CPU使用率。在systemd-cgtop中100%意味着满额使用了一核,并且这是正确的,因为我绑定了两个容器在相同的核上。
注意:为了显示所有的属性,你可以使用systemctl show docker-4be96b853089bc6044b29cb873cac460b429cfcbdd0e877c0868eb2a901dbf80.scope命令。想要列出所有可用的属性,请查看man systemd.resource-control。
|
1
2
3
4
5
|
$ ls /sys/fs/cgroup/cpu/system.slice/docker-6935854d444d78abe52d629cb9d680334751a0cda82e11d2610e041d77a62b3f.scope/
cgroup.clone_children cpuacct.usage_percpu cpu.rt_runtime_us tasks
cgroup.procs cpu.cfs_period_us cpu.shares
cpuacct.stat cpu.cfs_quota_us cpu.stat
cpuacct.usage cpu.rt_period_us notify_on_release
|
注意:关于这些文件的更多信息,请移步 RHEL Resource Management Guide查看。
|
1
|
$ docker run -it --rm -m 128m fedora bash
|
|
1
2
|
$ docker run -it --rm -m 128m stress --vm 1 --vm-bytes 128M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
|
|
1
2
|
$ docker run -it --rm -m 128m stress --vm 1 --vm-bytes 200M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
|
|
1
2
3
4
5
6
|
$ docker run -it --rm -m 128m stress --vm 1 --vm-bytes 260M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [1] (415) <-- worker 6 got signal 9
stress: WARN: [1] (417) now reaping child worker processes
stress: FAIL: [1] (421) kill error: No such process
stress: FAIL: [1] (451) failed run completed in 5s
|
警告:如果你不通过-m开关限制内存,swap也被不会被限制。(这在技术上是不正确的; 这有限度, 但是它设置的值在我们当前运行的系统是不可达的。 例如在我的笔记本上 16GB 的内存值是 18446744073709551615,这是 ~18.5 exabytes…)不限制内存将导致一个容器可以很容易使得整个系统不稳定的问题。因此请记住要一直使用-m参数。( 或者是使用MemoryLimit属性。)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ ls /sys/fs/cgroup/memory/system.slice/docker-48db72d492307799d8b3e37a48627af464d19895601f18a82702116b097e8396.scope/
cgroup.clone_children memory.memsw.failcnt
cgroup.event_control memory.memsw.limit_in_bytes
cgroup.procs memory.memsw.max_usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes
memory.force_empty memory.move_charge_at_immigrate
memory.kmem.failcnt memory.numa_stat
memory.kmem.limit_in_bytes memory.oom_control
memory.kmem.max_usage_in_bytes memory.pressure_level
memory.kmem.slabinfo memory.soft_limit_in_bytes
memory.kmem.tcp.failcnt memory.stat
memory.kmem.tcp.limit_in_bytes memory.swappiness
memory.kmem.tcp.max_usage_in_bytes memory.usage_in_bytes
memory.kmem.tcp.usage_in_bytes memory.use_hierarchy
memory.kmem.usage_in_bytes notify_on_release
memory.limit_in_bytes tasks
memory.max_usage_in_bytes
|
注意:想了解关于这些文件的更多信息,请移步到 RHEL资源管理指南,内存篇。
注意:我假设你正在使用 devicemapper storage作为Docker的后端。使用其他后端,任何事情都将不是确定的。
|
1
2
3
4
5
6
7
8
9
|
$ docker run -it --rm --name block-device-test fedora bash
bash-4.2# time $(dd if=/dev/zero of=testfile0 bs=1000 count=100000 && sync)
100000+0 records in
100000+0 records out
100000000 bytes (100 MB) copied, 0.202718 s, 493 MB/s
real 0m3.838s
user 0m0.018s
sys 0m0.213s
|
|
1
2
3
4
5
6
|
$ mount
/dev/mapper/docker-253:0-3408580-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88 on / type ext4 (rw,relatime,context="system_u:object_r:svirt_sandbox_file_t:s0:c447,c990",discard,stripe=16,data=ordered)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,context="system_u:object_r:svirt_sandbox_file_t:s0:c447,c990",mode=755)
[SNIP]
|
|
1
2
|
$ sudo /usr/bin/nsenter --target $(docker inspect -f '{{ .State.Pid }}' $CONTAINER_ID) --mount --uts --ipc --net --pid mount | head -1 | awk '{ print $1 }'
/dev/mapper/docker-253:0-3408580-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88
|
|
1
|
$ sudo systemctl set-property --runtime docker-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88.scope "BlockIOWriteBandwidth=/dev/mapper/docker-253:0-3408580-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88 10M"
|
|
1
2
3
4
5
6
7
8
|
bash-4.2# time $(dd if=/dev/zero of=testfile0 bs=1000 count=100000 && sync)
100000+0 records in
100000+0 records out
100000000 bytes (100 MB) copied, 0.229776 s, 435 MB/s
real 0m10.428s
user 0m0.012s
sys 0m0.276s
|
注意:你可以使用BlockIOReadBandwidth属性同样的限制你的读速率
|
1
|
docker -d --storage-opt dm.basesize=5G
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ ls /sys/fs/cgroup/blkio/system.slice/docker-48db72d492307799d8b3e37a48627af464d19895601f18a82702116b097e8396.scope/
blkio.io_merged blkio.sectors_recursive
blkio.io_merged_recursive blkio.throttle.io_service_bytes
blkio.io_queued blkio.throttle.io_serviced
blkio.io_queued_recursive blkio.throttle.read_bps_device
blkio.io_service_bytes blkio.throttle.read_iops_device
blkio.io_service_bytes_recursive blkio.throttle.write_bps_device
blkio.io_serviced blkio.throttle.write_iops_device
blkio.io_serviced_recursive blkio.time
blkio.io_service_time blkio.time_recursive
blkio.io_service_time_recursive blkio.weight
blkio.io_wait_time blkio.weight_device
blkio.io_wait_time_recursive cgroup.clone_children
blkio.leaf_weight cgroup.procs
blkio.leaf_weight_device notify_on_release
blkio.reset_stats tasks
blkio.sectors
|
注意:想了解关于这些文件的更多信息,请移步到 RHEL Resource Management Guide, blkio section。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/18796236/viewspace-1841968/ ,如需转载,请注明出处,否则将追究法律责任。