LXCFS

Sep 4, 2019 21:15 · 502 words · 2 minute read Docker Linux

关于 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 文件中读取数据了。