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

Add experimental "rootless" dind variant #174

Merged
merged 2 commits into from
Aug 1, 2019

Conversation

tianon
Copy link
Member

@tianon tianon commented Jul 30, 2019

This is an alternative proposal to #165 + #168.

This should have roughly the same behavior as the dockerd-rootless.sh script but without the extra depdendency (and frankly I'd love to pull some official vpnkit release binaries too instead of pulling the extras bundle, but I couldn't find any official binary releases nor did it look trivial to build from source). This allows us to iterate on this in between Docker releases as well, if necessary (like pulling in a newer rootlesskit release, for example).

I was toying with automatically adding --experimental as well, but wanted to enforce that being opt-in so that users don't switch without realizing what they're doing (since it does require some changes in usage).

Generally everything should "just work" as automatically as possible, but with the appropriate escape hatches for users who need/want to control the underlying knobs more directly.

Update (2021-03-04): as of 20.10.x, --experimental is no longer required (moby/moby#40759)

@AkihiroSuda
Copy link
Contributor

Thanks for working on this, but I think dockerd-rootless.sh should be still kept as a separate script, so that we don't need to maintain the both upstream script and the downstream script in this repo.

Also, it is highly likely that the content of the script will differ in future revisions.


# create a default user preconfigured for running rootless dockerd
RUN set -eux; \
adduser -h /home/rootless -g 'Rootless' -D -u 1000 rootless; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Folks shouldn't have to / shouldn't be rebuilding the image (I think the usability of that is way too low) -- the way it's configured, setting a reasonable value for HOME and setting up /etc/subuid and /etc/subgid should be enough for things to work (although some of the tools in use might also require /etc/passwd to be updated, but these are all pretty normal things for running a container as an "arbitrary user" and avoids requiring users to build their own custom images).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the UID 1000 is likely to overwrap with other users on the host, and it might break the user's env when the daemon got compromised.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the number of subuids should be reconfigurable, as some user might want more than 65536 subuids

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal here is that the user can do something as trivial as the following in order to customize their environment (and thus adjust the numbers to their heart's content):

FROM docker:19.03-dind-rootless
USER root
RUN adduser -h /home/user -D -u 1234 user
RUN echo 'user:101234:65536' >> /etc/subuid
RUN echo 'user:101234:65536' >> /etc/subgid
USER user

(most of this is also easily accomplishable via a docker run line, although a bit more gymnastics are involved)

@tianon
Copy link
Member Author

tianon commented Jul 30, 2019

So, the reason I avoided dockerd-rootless.sh is because the entire script boiled down to setting a couple default values (based on autodetection that we can already assume based on what we include in the image) and doing a couple rm commands after running rootlesskit -- it doesn't seem worth using that script. Do you anticipate more custom setup being required? If so, what kinds of things do you expect and/or why can't dockerd itself perform the necessary setup?

@AkihiroSuda
Copy link
Contributor

Do you anticipate more custom setup being required?

I don't know, but something may change when we get support fo cgroup (v2).
Anyway, we can revisit this when we face some real issue.

*) echo >&2 "error: unsupported architecture ($apkArch)"; exit 1 ;;\
esac; \
\
if ! wget -O rootless.tgz "https://download.docker.com/linux/static/${DOCKER_CHANNEL}/${dockerArch}/docker-rootless-extras-${DOCKER_VERSION}.tgz"; then \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: If you don't like the VPNKit binary footprint, https://github.com/rootless-containers/slirp4netns can be used instead of VPNKit.

slirp4netns is licensed under GPL2 and not included in the docker-rootless-extras.tgz because they didn't want to include GPL2 binary in the same tgz, but probably it doesn't hurt to put slirp4netns in Docker images.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind the footprint (or vpnkit in general -- I understand it's been used in Docker Desktop for a pretty respectable amount of time now, so it's "tested, tried, and true" so to speak) -- the issue I've got is with the need to pull this extra bundle which we then have to wait for a new Docker release to get an update to if there happens to be some issue that's resolved in a newer release of vpnkit, so it'd be really neat to get some official binary releases there, but I think that's a pretty minor issue at this point (vpnkit is pretty provably solid, as noted).

/home/rootless/.local/share/docker \
/home/rootless/certs
ENV DOCKER_TLS_CERTDIR=/home/rootless/certs
VOLUME /home/rootless/.local/share/docker
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer setting ENV XDG_RUNTIME_DIR here so that it is visible to docker exec processes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also DOCKER_HOST for docker exec docker

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expected usage there would be either docker exec -it docker-entrypoint.sh sh or docker exec docker-entrypoint.sh version, etc (using the same functionality as docker run docker ... does to set those same variables automatically/appropriately). Along those lines, I'm also going to update dockerd-entrypoint.sh to pass not only docker ... through to docker-entrypoint.sh, but any command that isn't dockerd (which should help with this as well).

@tianon
Copy link
Member Author

tianon commented Jul 31, 2019

Tested latest push via:

$ docker run -it --rm --name dind --privileged -v omg-certs:/certs/client docker:19.03-dind-rootless --experimental
...

$ docker run -it --rm --link dind:docker -v omg-certs:/certs/client docker:19.03-dind-rootless version
Client: Docker Engine - Community
 Version:           19.03.1
 API version:       1.40
 Go version:        go1.12.5
 Git commit:        74b1e89e8a
 Built:             Thu Jul 25 21:17:37 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.1
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.5
  Git commit:       74b1e89e8a
  Built:            Thu Jul 25 21:27:55 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

@yosifkit yosifkit merged commit 2285205 into docker-library:master Aug 1, 2019
@yosifkit yosifkit deleted the rootless branch August 1, 2019 22:20
docker-library-bot added a commit to docker-library-bot/official-images that referenced this pull request Aug 1, 2019
Changes:

- docker-library/docker@2285205: Merge pull request docker-library/docker#174 from infosiftr/rootless
- docker-library/docker@c01ffa4: Adjust bits per review
- docker-library/docker@7db7ecc: Add experimental "rootless" dind variant
tmaczukin added a commit to tmaczukin/docker that referenced this pull request Aug 2, 2019
docker-library#174 added an experimental
"rootless" variant of the DinD service.

While the change itself is simple and should not affect current usages,
a `DOCKER_HOST` variable was used to define which docker.sock path
should be used depending on the process owner's ID.

Chosing DOCKER_HOST variable for this is unfortunately not the best
option:

1. It's not the best semantic choice - the code that uses it defines a
socket file, not the host. DOCKER_SOCKET just seems to fit better the
purpose.

1. DOCKER_HOST is already a variable, that is used by users to define
where the Docker daemon is listening. In case when it's added to the
DinD container (which is a common situation for example for GitLab CI
jobs that are using DinD as a service), it finally ends with assigning
two times the same port, while once it uses 0.0.0.0 address, and once
some unresolvable domain name (depending on what user defined; most
probably `docker`).

This commit proposes a change of the variable name to DOCKER_SOCKET,
which will better match it purpose and additionally it will stop
breaking configurations of many of docker:dind image users.

Signed-off-by: Tomasz Maczukin <[email protected]>
@anki-code

This comment has been minimized.

@tianon

This comment has been minimized.

@AkihiroSuda

This comment has been minimized.

@anki-code

This comment has been minimized.

@AkihiroSuda

This comment has been minimized.

@anki-code

This comment has been minimized.

@AkihiroSuda

This comment has been minimized.

@AkihiroSuda

This comment has been minimized.

@anki-code

This comment has been minimized.

@tianon tianon mentioned this pull request Aug 2, 2019
thomasleveil added a commit to thomasleveil/docker-jenkins-dsl-ready that referenced this pull request Aug 3, 2019
@tim-gp
Copy link

tim-gp commented Aug 13, 2019

I've tried to spin up without certs per #174 (comment)

$ docker run -it --rm --name dind --privileged docker:19.03.1-dind-rootless --experimental

I get [rootlesskit:child ] error: executing [[ip tuntap add name tap0 mode tap] [ip link set tap0 address <MAC>]]: exit status 1 on Docker Desktop for Mac 2.1.0.0.

@AkihiroSuda
Copy link
Contributor

opened docker/for-mac#3838 for Docker fo Mac issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants