[英]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.