Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow running dockerd as a non-root user (Rootless mode) #38050

Merged
merged 1 commit into from Feb 3, 2019

Conversation

@AkihiroSuda
Copy link
Member

@AkihiroSuda AkihiroSuda commented Oct 16, 2018

- What I did

Allow running dockerd in an unprivileged user namespace (rootless mode).
Close #37375

No SETUID/SETCAP binary is required, except newuidmap and newgidmap.

For Kubernetes integration, please refer to https://github.com/rootless-containers/usernetes .

This PR contains two commits, but the first one is same as #38038 (overlayfs in userns for Ubuntu).
I'll rebase this PR when #38038 gets merged.
(Updated: #38083 is merged now)

- How I did it

By using user_namespaces(7), mount_namespaces(7), network_namespaces(7), and slirp4netns.

Please refer to docs/rootless.md for the details.

- How to verify it

  • Make sure /etc/subuid and /etc/subgid contain the entry for you
$ id -u
1001
$ whoami
penguin
$ grep ^$(whoami): /etc/subuid
penguin:231072:65536
$ grep ^$(whoami): /etc/subgid
penguin:231072:65536
  • Start daemon: dockerd-rootless.sh --experimental
  • Start client: docker -H unix://$XDG_RUNTIME_DIR/docker.sock run ...

Remarks:

  • Some distros such as Debian (excluding Ubuntu) and Arch Linux require sudo sh -c "echo 1 > /proc/sys/kernel/unprivileged_userns_clone".
  • Some distros require sudo modprobe ip_tables iptable_mangle iptable_nat iptable_filter.

Restrictions:

  • Only vfs graphdriver is supported. However, on Ubuntu and a few distros, overlay2 and overlay are also supported. Starting with Linux 4.18, we will be also able to implement FUSE snapshotters.
  • Cgroups (including docker top) and AppArmor are disabled at the moment. In future, Cgroups will be optionally available when delegation permission is confi
    gured on the host.
  • Checkpoint is not supported at the moment.
  • Running rootless dockerd in rootless/rootful dockerd is also possible, but not fully tested.

- Description for the changelog

Allow running dockerd in an unprivileged user namespace (rootless mode)

- A picture of a cute animal (not mandatory but encouraged)

penguin

https://en.wikipedia.org/wiki/Little_penguin#/media/File:Eudyptula_minor_Bruny_1.jpg

Screenshot:

penguin0@suda-ws01:~$ id
uid=1002(penguin0) gid=1006(penguin0) groups=1006(penguin0)
penguin0@suda-ws01:~$ ps u
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
penguin0 122952  0.0  0.0  21484  5156 pts/3    Ss   16:58   0:00 /bin/bash -l
penguin0 123093  0.0  0.0  21484  5200 pts/4    Ss   16:58   0:00 /bin/bash -l
penguin0 123094  0.0  0.0 134792  2860 pts/4    S    16:58   0:00 (sd-pam)
penguin0 123252  0.0  0.0   4628   784 pts/4    S+   16:58   0:00 /bin/sh /usr/local/bin/dockerd-rootless.sh --experimental
penguin0 123253  0.0  0.0 105772  3696 pts/4    Sl+  16:58   0:00 rootlesskit --net=slirp4netns --mtu=65520 --copy-up=/etc --copy-up=/run /usr/local/bin/dockerd-rootless.sh --experimental
penguin0 123257  0.0  0.0 105516  4024 pts/4    Sl+  16:58   0:00 /proc/self/exe --net=slirp4netns --mtu=65520 --copy-up=/etc --copy-up=/run /usr/local/bin/dockerd-rootless.sh --experimental
penguin0 123265  0.0  0.0   2980  1072 pts/4    S+   16:58   0:00 slirp4netns --mtu 65520 123257 tap0
penguin0 123281  0.0  0.0   4628   828 pts/4    S+   16:58   0:00 /bin/sh /usr/local/bin/dockerd-rootless.sh --experimental
penguin0 123283  0.6  0.8 583536 65728 pts/4    Sl+  16:58   0:00 dockerd --experimental
penguin0 125126  0.0  0.0  38372  3688 pts/3    R+   17:00   0:00 ps u
penguin0@suda-ws01:~$ docker -H unix:///run/user/1002/docker.sock run --rm hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
@AkihiroSuda
Copy link
Member Author

@AkihiroSuda AkihiroSuda commented Oct 16, 2018

@AkihiroSuda AkihiroSuda force-pushed the AkihiroSuda:rootless branch 2 times, most recently from 483ab2e to e183cfb Oct 16, 2018
@AkihiroSuda AkihiroSuda force-pushed the AkihiroSuda:rootless branch from e183cfb to 21cc7a8 Oct 16, 2018
@AkihiroSuda AkihiroSuda changed the title Rootless mode Allow running dockerd as a non-root user (Rootless mode) Oct 16, 2018
@AkihiroSuda AkihiroSuda force-pushed the AkihiroSuda:rootless branch 2 times, most recently from abb3322 to 79c8968 Oct 16, 2018
@codecov
Copy link

@codecov codecov bot commented Oct 16, 2018

Codecov Report

No coverage uploaded for pull request base (master@50e63ad). Click here to learn what that means.
The diff coverage is 19.23%.

@@            Coverage Diff            @@
##             master   #38050   +/-   ##
=========================================
  Coverage          ?   36.54%           
=========================================
  Files             ?      610           
  Lines             ?    45368           
  Branches          ?        0           
=========================================
  Hits              ?    16581           
  Misses            ?    26497           
  Partials          ?     2290
@sargun
Copy link
Contributor

@sargun sargun commented Oct 17, 2018

How can you delegate cgroups? A piece of work prior to this might be supporting cgroup namespace?

@AkihiroSuda
Copy link
Member Author

@AkihiroSuda AkihiroSuda commented Oct 17, 2018

How can you delegate cgroups? A piece of work prior to this might be supporting cgroup namespace?

Cgroups delegation is disabled on this PR and it is likely to be a separate PR in future.

Until we can get full cgroups v2 support in runc (blocked due to lack of freezer and device subsystems, see opencontainers/runc#654), we would need to use pam_cgfs, although it is unlikely to be available on Red Hat distros: containers/podman#1429

Copy link
Member

@thaJeztah thaJeztah left a comment

Not too familiar with all the requirements to make this work, but had a quick glance over, and left some comments/suggestions 🤗

Dockerfile Outdated Show resolved Hide resolved
cmd/dockerd/config_common_unix.go Outdated Show resolved Hide resolved
cmd/dockerd/daemon_unix.go Outdated Show resolved Hide resolved
cmd/dockerd/daemon_unix.go Outdated Show resolved Hide resolved
contrib/dockerd-rootless.sh Outdated Show resolved Hide resolved
pkg/archive/archive_linux.go Outdated Show resolved Hide resolved
pkg/archive/archive_linux.go Outdated Show resolved Hide resolved
pkg/archive/archive_linux.go Outdated Show resolved Hide resolved
pkg/archive/archive_linux.go Outdated Show resolved Hide resolved
pkg/archive/archive_linux.go Outdated Show resolved Hide resolved
@thaJeztah thaJeztah added this to backlog in maintainers-session Oct 17, 2018
@AkihiroSuda AkihiroSuda force-pushed the AkihiroSuda:rootless branch from 79c8968 to 76a6d66 Oct 19, 2018
@AkihiroSuda
Copy link
Member Author

@AkihiroSuda AkihiroSuda commented Oct 19, 2018

addressed comments

Copy link
Collaborator

@cpuguy83 cpuguy83 left a comment

LGTM

@cpuguy83
Copy link
Collaborator

@cpuguy83 cpuguy83 commented Feb 1, 2019

@thaJeztah You good?

Copy link
Member

@thaJeztah thaJeztah left a comment

Reviewing from my phone, so just from looking over the changes; left some comments/questions

I'm good to move this forward if those were errors on my side (and this is really cool to see arrive 👌😍🥳)

daemon/config/config_unix.go Outdated Show resolved Hide resolved
cmd/dockerd/daemon.go Show resolved Hide resolved
daemon/daemon_unix.go Show resolved Hide resolved
@thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Feb 3, 2019

@AkihiroSuda are any packaging changes needed for this?

/cc @seemethere

…ode)

Please refer to `docs/rootless.md`.

TLDR:
 * Make sure `/etc/subuid` and `/etc/subgid` contain the entry for you
 * `dockerd-rootless.sh --experimental`
 * `docker -H unix://$XDG_RUNTIME_DIR/docker.sock run ...`

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
@AkihiroSuda AkihiroSuda force-pushed the AkihiroSuda:rootless branch from 54e9c3f to ec87479 Feb 3, 2019
@AkihiroSuda
Copy link
Member Author

@AkihiroSuda AkihiroSuda commented Feb 3, 2019

Updated PR

cc @estesp @icecrime 😃

@AkihiroSuda are any packaging changes needed for this?

I suggest adding dockerd-rootless.sh, rootlesskit and vpnkit to official RPM/DEB and binary tar archive, but not sure how to build VPNKit for non-amd64.
Also, I suggest providing slirp4netns binary as "contrib" pkg.

@thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Feb 3, 2019

I suggest adding dockerd-rootless.sh, rootlesskit and vpnkit to official RPM/DEB and binary tar archive, but not sure how to build VPNKit for non-amd64.
Also, I suggest providing slirp4netns binary as "contrib" pkg.

Makes sense; if you have time; could you try opening a pull request in the https://github.com/docker/docker-ce-packaging repository? Perhaps the packaging team can work on it, but if you can prepare a PR, that may help speeding it up 🤗 (feel free to ping me if you need help/input on that one; I'll be on PTO for the next few days, but will try to catch up on notifications)

Copy link
Member

@thaJeztah thaJeztah left a comment

LGTM! Thanks; this is really cool stuff 🥳

@thaJeztah thaJeztah merged commit 93d994e into moby:master Feb 3, 2019
8 of 9 checks passed
8 of 9 checks passed
codecov/patch 19.23% of diff hit (target 50%)
Details
codecov/project No report found to compare against
Details
dco-signed All commits are signed
experimental Jenkins build Docker-PRs-experimental 43988 has succeeded
Details
janky Jenkins build Docker-PRs 52816 has succeeded
Details
powerpc Jenkins build Docker-PRs-powerpc 13225 has succeeded
Details
windowsRS1 Jenkins build Docker-PRs-WoW-RS1 23966 has succeeded
Details
windowsRS5-process Jenkins build Docker-PRs-WoW-RS5-Process 1366 has succeeded
Details
z Jenkins build Docker-PRs-s390x 13115 has succeeded
Details
@cyphar
Copy link
Contributor

@cyphar cyphar commented Feb 4, 2019

@AkihiroSuda Great work. 🎉

I suggest adding dockerd-rootless.sh, rootlesskit and vpnkit to official RPM/DEB and binary tar archive, but not sure how to build VPNKit for non-amd64.

Can we use slirp4netns instead of VPNKit (asking for openSUSE when we package this).

@thaJeztah
Copy link
Member

@thaJeztah thaJeztah commented Feb 4, 2019

@cyphar I think the license for slirp4netns was the blocker for bundling it, but you can use it

@cyphar
Copy link
Contributor

@cyphar cyphar commented Feb 4, 2019

Right, because we use rootlesskit anyway. Thanks.

@@ -46,5 +49,7 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers")
flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`)
flags.Var(&conf.NetworkConfig.DefaultAddressPools, "default-address-pool", "Default address pools for node specific local networks")

// Mostly users don't need to set this flag explicitly.
flags.BoolVar(&conf.Rootless, "rootless", rootless.RunningWithNonRootUsername(), "Enable rootless mode (experimental)")

This comment has been minimized.

@tianon

tianon Apr 6, 2019
Member

For anyone looking to thread the needle, this line appears to be the cause of #39009. 👍 ❤️

@andrew-aladev

This comment has been minimized.

Copy link

@andrew-aladev andrew-aladev commented on pkg/homedir/homedir_linux.go in ec87479 Mar 17, 2020

You know? For desktop and systemd only!

This comment has been minimized.

Copy link
Member Author

@AkihiroSuda AkihiroSuda replied Mar 17, 2020

@andrew-aladev

This comment has been minimized.

Copy link

@andrew-aladev andrew-aladev commented on cmd/dockerd/daemon.go in ec87479 Mar 18, 2020

It is not possible to protect XDG_* directories with sticky bit. Re-mount hammer don't care about sticky bits. It just re-mounts and that's it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment