LXCFS
Sep 4, 2019 21:15 · 502 words · 2 minute read
关于 Docker 容器的资源限制,我们做一个实验:
$ docker run --rm -it --memory="512m" ubuntu /bin/bash
root@4d2452c049fd:/# free -h
total used free shared buff/cache available
Mem: 7.6G 551M 6.5G 9.7M 573M 6.9G
Swap: 2.0G 0B 2.0G
root@4d2452c049fd:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 41G 7.0G 34G 18% /
tmpfs 64M 0 64M 0% /dev
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/mapper/cl-root 41G 7.0G 34G 18% /etc/hosts
tmpfs 3.9G 0 3.9G 0% /proc/asound
tmpfs 3.9G 0 3.9G 0% /proc/acpi
tmpfs 3.9G 0 3.9G 0% /proc/scsi
tmpfs 3.9G 0 3.9G 0% /sys/firmware
容器中的 top/free/df 等命令,展示的状态信息是从 /proc 目录中的相关文件里读取出来的,而 /proc 文件系统并不知道用户通过 Cgroups 给容器做了什么样的资源限制。这也是 Cgroups 隔离不彻底最直接的体现之一,应用程序在容器里读取到的 CPU、内存等信息都是宿主机自身的数据。
LXCFS 是一个小型的 FUSE 文件系统,解决了 Linux 内核当前的一些限制,旨在使 Linux 容器更像虚拟机(隔离更彻底)。
我们可以选择自行手工编译:
$ git clone https://github.com/lxc/lxcfs.git
$ cd lxcfs
$ yum install fuse-devel automake libtool -y
$ ./bootstrap.sh
$ ./configure --prefix=/usr
$ make & sudo make install
创建 /var/lib/lxcfs 路径来存放为 Cgroups 提供感知的 /proc 文件:
$ mkdir -p /var/lib/lxcfs
$ lxcfs /var/lib/lxcfs
mount namespace: 5
hierarchies:
0: fd: 6: perf_event
1: fd: 7: hugetlb
2: fd: 8: pids
3: fd: 9: net_prio,net_cls
4: fd: 10: devices
5: fd: 11: cpuset
6: fd: 12: cpuacct,cpu
7: fd: 13: blkio
8: fd: 14: freezer
9: fd: 15: memory
10: fd: 16: name=systemd
lxcfs 需要作为一个常驻服务,可以使用 systemd 来托管:
$ cp config/init/systemd/lxcfs.service /usr/lib/systemd/system/lxcfs.service
$ systemctl daemon-reload
$ systemctl start lxcfs.service
$ systemctl enable lxcfs.service
现在查看容器内读取的资源信息:
$ docker run --rm -it -m 1024m \
-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:18.04 /bin/bash
root@c3ff200e9ed3:/# free -h
total used free shared buff/cache available
Mem: 1.0G 632K 1.0G 0B 0B 1.0G
Swap: 2.0G 0B 2.0G
这时容器已经从 lxcfs 维护的 /proc 文件中读取数据了。