skip to Main Content

I have started my container using the --privileged flag, so as far as I know, all disks should be available from inside the container – and that is partly true, but I somehow can’t read the size of them.

lsblk on host (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 in container (Alpine):

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

Both outputs are stripped from loop devices, but as you can see, there are 2 drives recognized in both.

Now, if I run the df command on the host:

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

And inside the container:

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

Somehow, it does not show the correct drives in the second df output. Is there any way to make df show the correct output, even inside the container?

Or is there another way to get the correct disk sizes and usages from the host?

2

Answers


  1. There is no "decent" solution that can accomplish what you want, but let me explain why.

    You talk about "disk usage", but in reality there is no such thing as disk usage. As far as the disk (i.e. the device itself) is concerned, there is no concept of "usage". What you are looking for is rather filesystem disk usage, which is fundamentally different.

    In order to know the "used" and "available" space of a filesystem, you will have to mount it. This allows the kernel to process filesystem metadata that can then be used to determine free and used filesystem blocks. Without mounting the filesystem this information is simply not available to the kernel (and therefore not available to df, for example).

    In order for Docker to work, containers run with a different mount namsepace than the host. The core reason for this is that containers cannot in general safely share mount points with the host. Think for example what would happen if / in the host and / in the container referred to the same mount point: as soon as the container starts, it would likely break your system by touching sensitive files that it is not supposed to. So by default, Docker will "isolate" containers in their own mount namespace, so that they will only see the mount points they need, and there is no option to avoid this because of the above.


    You could be able to get this information by reading raw data from the available block devices (without mounting them) and parsing the filesystem metadata (if any) from userspace within the container using some specialized tool, but this is a finicky solution as it would basically require one tool per possible filesystem type. See also Free space in unmounted partition at Unix & Linux SE.

    You could also use bind mounts allowing the host and the container to share mount points, but this would have to be done on a per-mount basis, for example:

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

    You say that for now you are "passing all mounted volumes manually", so I assume this is not different than whatever you are currently doing. On top of being pretty ugly, this solution would also have the limit of not being able to handle changes in devices or mount points on the host (e.g. if a new device is added and mounted).


    The only "real" solution I can see here would be to run some application on the host, which periodically extracts the needed information and communicates it to the application running inside the container.

    Login or Signup to reply.
  2. Using nsenter, this command should achieve what you wanted :

    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.
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search