[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#985481: debootstrap: Detection of docker container is broken with cgroup v2



Hello Tianon,

On 4/20/21 2:39 AM, Tianon Gravi wrote:
Hey Arnaud, thanks for the CC (and sorry for the delay).

On Mon, 12 Apr 2021 at 20:48, Arnaud Rebillout <arnaudr@kali.org> wrote:
  > Originally, ".dockerenv" was for transmitting the environment
  > variables of the container across the container boundary -- I would
  > not recommend relying on its existence either (IIRC, that code
  > you've linked to is the only reason it still exists). There's
  > likely something incriminatory inside /sys/fs/cgroup, but I haven't
  > checked recently.
  > https://github.com/moby/moby/issues/18355#issuecomment-220484748
  >
  > This makes it sounds like ".dockerenv" may be deprecated and later
  > removed.

That's a good point, but it's also a 5 years old comment, and the
.dockerenv file is still present these days.

I would think that if Docker plans to remove it, they will issue a more
formal deprecation warning that will give us enough time to fix things
on our side. Also the fact that systemd checks for this file gives me
more confidence that it's not just me doing something fancy here: it
seems that this is the "de facto" solution to detect docker containers.

FWIW, it's also the most common solution on Q&A sites like
stackoverflow. Other people do that, because there is no better solution
provided apparently. Unless I missed it.

  > Cgroup v2 is also mounted at /sys/fs/cgroup, so I wonder if the original
  > check should be rewritten to check for something under this path instead
  > of mountinfo?  Also, using this /sys/fs/cgroup method, I'm not sure if
  > it's better debootstrap style to express the OR logical operator in the
  > regex or a shell "||" (ie: seems to be needed because the tree under
  > /sys/fs/cgroup is different between v1 and v2).

I just had a quick look in /sys/fs/cgroup from within a container.
Nothing obvious stands out, there's no file named docker, and nothing in
the content of those files mentions docker. I'll attach the output below.

I will CC Tianon, as he was the author of the comment mentioned above,
and he might know better, 5 years after :)

In short, Tianon, if you're reading those lines, our question is: what
would be the right way to detect that we're running from within a docker
container, apart from checking for the existence of the file
`/.dockerenv` ???
Heh, I looked into the Docker code, and the only two places it's
currently used by Docker itself are in the line that creates it (as a
simple empty file in the container's init r/w layer) and some code in
libnetwork that uses it to detect that it's running inside a
container, of all things, which is both hilarious and depressing.  A
container can also happily remove it during runtime without any ill
effects (as far as I can see), but the systemd code does include a
caveat that it's not a fully surefire detection method given that it
will often end up in non-Docker rootfses or filesystem images due to
them being created in/by/from Docker environments. :D

Oh, this last point is interesting, I didn't realize this caveat.


All that being said, I'm honestly a bit confused by debootstrap having
any kind of "detect Docker" code -- I run debootstrap inside Docker
containers a lot, and frankly expect it to run there exactly like it
does on my host (and I supply it with SYS_ADMIN appropriately as a
result, so it can properly mount things like /proc, /sys, and /dev).


So I just run a series of test, what I see is that:

- running debootstrap on host (debian sid) and in a --privileged docker container (debian sid) produces exactly the same logs. - running debootstrap in a UNprivileged containers (debian sid of course) gives me additional warnings:

    W: Failure trying to run: chroot "/home/me/tmp/debootstrap/sid-chroot-dock" mount -t proc proc /proc     W: See /home/me/tmp/debootstrap/sid-chroot-dock/debootstrap/debootstrap.log for details     W: Failure trying to run: chroot "/home/me/tmp/debootstrap/sid-chroot-dock" mount -t sysfs sysfs /sys     W: See /home/me/tmp/debootstrap/sid-chroot-dock/debootstrap/debootstrap.log for details

This warnings seem to be harmless, as debootstrap completes successfully anyway.

Then I applied the patch to improve docker detection based on .dockerenv, as discussed here. It removes those warnings.

It's not so easy to understand *why* it removes the warning, as the debootstrap code is a bit of maze. But in short, here's what changes when CONTAINER=docker:


1) setup_proc_symlink() is run, meaning that debootstrap won't attempt to mount /proc

    debootstrap/functions:
    ----
    setup_proc_symlink () {
        rm -rf "$TARGET/proc"
        ln -s /proc "$TARGET"
    }

    debootstrap/scripts/debian-common:
    ----
    if doing_variant fakechroot || [ "$CONTAINER" = "docker" ]; then
        setup_proc_symlink
    fi


2) setup_proc() doesn't try to mount /sys

    debootstrap/functions:
    ----
    if [ -n "$(ls -A "$TARGET/sys")" ] && \
        grep -qs '[[:space:]]sysfs' "$TARGET/proc/filesystems" || \
        [ "$CONTAINER" = "docker" ]; then
                umount_on_exit /sys
                umount "$TARGET/sys" 2>/dev/null || true
else
        # second-stage in docker, we cannot detect it is
        # inside docker... just ignore warning
        in_target mount -t sysfs sysfs /sys || true
        umount_on_exit /sys
fi

At this point, it seems to me that applying this patch would not change things dramatically.

There would be a cosmetics improvements, by removing the warnings for those who run debootstrap in an unprivileged container.

Also the function detect_container() for docker is clearly broken, so it's always nice to try to fix something broken, but due to the caveat that Tianon mentions, it could also lead to false positives (debootstrap would wrongly assume that it runs in docker, while in fact it does not).

As for the other bugs reported against debootstrap handling of /proc (#921815 #968927 #953637), I can't reproduce any, so I really can't say about those.

I wonder if the debootstrap code doesn't need more serious maintenance regarding how it tries to handle /proc and /sys, but that's out of scope of this bug.

Cheers,

--
Arnaud Rebillout


Reply to: