繁体   English   中英

如何从 docker 容器内部获取磁盘使用情况

[英]How to get disk usage from inside docker container

我已经使用--privileged标志启动了我的容器,据我所知,所有磁盘都应该在容器内部可用 - 这部分是正确的,但我不知何故无法读取它们的大小。

主机上的lsblk (Ubuntu):

sda                     8:0    1  59,6G  0 disk  
└─sda1                  8:1    1  59,6G  0 part  /media/mauz/ESD-ISO
nvme0n1               259:0    0 953,9G  0 disk  
├─nvme0n1p1           259:1    0   512M  0 part  /boot/efi
├─nvme0n1p2           259:2    0   732M  0 part  /boot
└─nvme0n1p3           259:3    0 952,7G  0 part  
  └─nvme0n1p3_crypt   253:0    0 952,6G  0 crypt 
    ├─vgubuntu-root   253:1    0 930,4G  0 lvm   /
    └─vgubuntu-swap_1 253:2    0   976M  0 lvm   [SWAP]

容器中的lsblk (高山):

sda           8:0    1  59.6G  0 disk 
└─sda1        8:1    1  59.6G  0 part 
nvme0n1     259:0    0 953.9G  0 disk 
├─nvme0n1p1 259:1    0   512M  0 part 
├─nvme0n1p2 259:2    0   732M  0 part 
└─nvme0n1p3 259:3    0 952.7G  0 part

两个输出都从loop设备中剥离,但如您所见,两者都识别出 2 个驱动器。

现在,如果我在主机上运行df命令:

Filesystem                1K-blocks      Used Available Use% Mounted on
tmpfs                       3261580      2564   3259016   1% /run
/dev/mapper/vgubuntu-root 959200352 137078032 773327904  16% /
tmpfs                      16307884    215740  16092144   2% /dev/shm
tmpfs                          5120         4      5116   1% /run/lock
/dev/nvme0n1p2               721392    364788    304140  55% /boot
/dev/nvme0n1p1               523248     76232    447016  15% /boot/efi
tmpfs                       3261576       140   3261436   1% /run/user/1000
/dev/sda1                  62519040  23118848  39400192  37% /media/mauz/ESD-ISO

在容器内:

Filesystem           1K-blocks      Used Available Use% Mounted on
overlay              959200352 137078188 773327748  15% /
tmpfs                    65536         0     65536   0% /dev
shm                      65536         0     65536   0% /dev/shm
/dev/mapper/vgubuntu-root
                     959200352 137078188 773327748  15% /app
/dev/mapper/vgubuntu-root
                     959200352 137078188 773327748  15% /etc/os-release
/dev/mapper/vgubuntu-root
                     959200352 137078188 773327748  15% /etc/resolv.conf
/dev/mapper/vgubuntu-root
                     959200352 137078188 773327748  15% /etc/hostname
/dev/mapper/vgubuntu-root
                     959200352 137078188 773327748  15% /etc/hosts

不知何故,它没有在第二个df输出中显示正确的驱动器。 有没有办法让df显示正确的输出,即使在容器内?

还是有其他方法可以从主机获取正确的磁盘大小和使用情况?

没有“体面”的解决方案可以完成您想要的,但让我解释一下原因。

您谈论“磁盘使用情况”,但实际上没有磁盘使用情况。 就磁盘(即设备本身)而言,没有“使用”的概念。 您正在寻找的是文件系统磁盘使用情况,这是根本不同的。

为了知道文件系统的“已用”和“可用”空间,您必须挂载它。 这允许内核处理文件系统元数据,然后可以使用这些元数据来确定空闲和使用的文件系统块。 如果不挂载文件系统,这些信息对内核根本不可用(例如,因此对df不可用)。

为了让 Docker 工作,容器使用与主机不同的挂载名称空间运行。 其核心原因是容器通常不能安全地与主机共享挂载点。 例如,如果主机中的/和容器中的/引用相同的挂载点会发生什么:一旦容器启动,它可能会通过触摸不应该触摸的敏感文件来破坏您的系统。 所以默认情况下,Docker 会将容器“隔离”在自己的挂载命名空间中,这样它们就只会看到自己需要的挂载点,而由于上述原因,没有办法避免这种情况。


您可以通过从可用块设备读取原始数据(无需挂载它们)并使用某些专用工具从容器内的用户空间解析文件系统元数据(如果有)来获取此信息,但这是一个挑剔的解决方案基本上每种可能的文件系统类型都需要一个工具。 另请参阅 Unix 和 Linux SE的未挂载分区中的可用空间

您还可以使用绑定挂载,允许主机和容器共享挂载点,但这必须在每次挂载的基础上完成,例如:

docker run --mount readonly,type=bind,source=/media/mauz/ESD-ISO,target=/container/path ...
$ df
...
/dev/sda1                  62519040  23118848  39400192  37% /container/path
...

您说现在您正在“手动传递所有已安装的卷” ,所以我认为这与您当前正在做的事情没有什么不同。 除了非常丑陋之外,该解决方案还存在无法处理主机上的设备或挂载点更改的限制(例如,如果添加并挂载了新设备)。


我可以在这里看到的唯一“真正”的解决方案是在主机上运行一些应用程序,它会定期提取所需的信息并将其传达给在容器内运行的应用程序。

使用 nsenter,此命令应该可以实现您想要的:

docker run -it --rm --privileged --pid host ubuntu nsenter -t 1 -m -u -n -i bash

# --privileged : run privileged
# --pid host   : shares host's process id namespace

# nsenter - run program with namespaces of other processes
# -t 1        : Specify process 1 to get contexts from
# -m -u -n -i : Share mount, UTS, network, IPC namespace.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM