From 18ac6e2d9adeb9fe5fbc74b06c3263acb4e8f942 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Mon, 4 Jun 2018 20:00:07 +0900 Subject: [PATCH] test.Dockerfile: new target: "rootless" Signed-off-by: Akihiro Suda --- docs/rootless.md | 37 ++++++++++++++++++++++++++++---- examples/buildkit0/buildkit.go | 2 +- examples/buildkit1/buildkit.go | 2 +- examples/buildkit2/buildkit.go | 2 +- examples/buildkit3/buildkit.go | 2 +- hack/dockerfiles/test.Dockerfile | 30 +++++++++++++++++++++++++- 6 files changed, 66 insertions(+), 9 deletions(-) diff --git a/docs/rootless.md b/docs/rootless.md index 3f5420db..4910e9a6 100644 --- a/docs/rootless.md +++ b/docs/rootless.md @@ -7,9 +7,12 @@ Requirements: - `/etc/subuid` and `/etc/subgid` should contain >= 65536 sub-IDs. e.g. `penguin:231072:65536`. - To run in a Docker container with non-root `USER`, `docker run --privileged` is still required. See also Jessie's blog: https://blog.jessfraz.com/post/building-container-images-securely-on-kubernetes/ + +## Set up + Setting up rootless mode also requires some bothersome steps as follows, but you can also use [`rootlesskit`](https://github.com/AkihiroSuda/rootlesskit) for automating these steps. -## Terminal 1: +### Terminal 1: ``` $ unshare -U -m @@ -18,7 +21,7 @@ unshared$ echo $$ > /tmp/pid Unsharing mountns (and userns) is required for mounting filesystems without real root privileges. -## Terminal 2: +### Terminal 2: ``` $ id -u @@ -31,7 +34,7 @@ $ newuidmap $(cat /tmp/pid) 0 1001 1 1 231072 65536 $ newgidmap $(cat /tmp/pid) 0 1001 1 1 231072 65536 ``` -## Terminal 1: +### Terminal 1: ``` unshared# buildkitd @@ -43,9 +46,35 @@ unshared# buildkitd * containerd worker is not supported ( pending PR: https://github.com/containerd/containerd/pull/2006 ) * Network namespace is not used at the moment. -## Terminal 2: +### Terminal 2: ``` $ go get ./examples/build-using-dockerfile $ build-using-dockerfile --buildkit-addr unix:///run/user/1001/buildkit/buildkitd.sock -t foo /path/to/somewhere ``` + +## Set up (using a container) + +``` +$ docker build -t buildkit-rootless --target rootless -f hack/dockerfiles/test.Dockerfile . +$ docker run --name buildkitd -d --privileged -p 1234:1234 buildkit-rootless --addr tcp://0.0.0.0:1234 +``` + +`docker run` requires `--privileged` but the BuildKit daemon is executed as a normal user. +See [`moby/moby#36597`](https://github.com/moby/moby/issues/36597, [`kubernetes/community#1934`](https://github.com/kubernetes/community/pull/1934) and [Jess's blog](https://blog.jessfraz.com/post/building-container-images-securely-on-kubernetes/) for the ongoing work to remove this requirement + +``` +$ docker exec buildkitd id +uid=1000(user) gid=1000(user) +$ docker exec buildkitd ps aux +PID USER TIME COMMAND + 1 user 0:00 rootlesskit buildkitd --addr tcp://0.0.0.0:1234 + 13 user 0:00 /proc/self/exe buildkitd --addr tcp://0.0.0.0:1234 + 21 user 0:00 buildkitd --addr tcp://0.0.0.0:1234 + 29 user 0:00 ps aux +``` + +``` +$ go get ./examples/build-using-dockerfile +$ build-using-dockerfile --buildkit-addr tcp://127.0.0.1:1234 -t foo /path/to/somewhere +``` diff --git a/examples/buildkit0/buildkit.go b/examples/buildkit0/buildkit.go index 59adfe87..2f4e0175 100644 --- a/examples/buildkit0/buildkit.go +++ b/examples/buildkit0/buildkit.go @@ -18,7 +18,7 @@ func main() { var opt buildOpt flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker") flag.StringVar(&opt.containerd, "containerd", "v1.1.0", "containerd version") - flag.StringVar(&opt.runc, "runc", "69663f0bd4b60df09991c08812a60108003fa340", "runc version") + flag.StringVar(&opt.runc, "runc", "dd56ece8236d6d9e5bed4ea0c31fe53c7b873ff4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit1/buildkit.go b/examples/buildkit1/buildkit.go index 5dc8b1bd..1b529efd 100644 --- a/examples/buildkit1/buildkit.go +++ b/examples/buildkit1/buildkit.go @@ -18,7 +18,7 @@ func main() { var opt buildOpt flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker") flag.StringVar(&opt.containerd, "containerd", "v1.1.0", "containerd version") - flag.StringVar(&opt.runc, "runc", "69663f0bd4b60df09991c08812a60108003fa340", "runc version") + flag.StringVar(&opt.runc, "runc", "dd56ece8236d6d9e5bed4ea0c31fe53c7b873ff4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit2/buildkit.go b/examples/buildkit2/buildkit.go index fc30ad88..44e423a6 100644 --- a/examples/buildkit2/buildkit.go +++ b/examples/buildkit2/buildkit.go @@ -18,7 +18,7 @@ func main() { var opt buildOpt flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker") flag.StringVar(&opt.containerd, "containerd", "v1.1.0", "containerd version") - flag.StringVar(&opt.runc, "runc", "69663f0bd4b60df09991c08812a60108003fa340", "runc version") + flag.StringVar(&opt.runc, "runc", "dd56ece8236d6d9e5bed4ea0c31fe53c7b873ff4", "runc version") flag.Parse() bk := buildkit(opt) diff --git a/examples/buildkit3/buildkit.go b/examples/buildkit3/buildkit.go index 347b3e3f..150d0790 100644 --- a/examples/buildkit3/buildkit.go +++ b/examples/buildkit3/buildkit.go @@ -19,7 +19,7 @@ func main() { var opt buildOpt flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker") flag.StringVar(&opt.containerd, "containerd", "v1.1.0", "containerd version") - flag.StringVar(&opt.runc, "runc", "69663f0bd4b60df09991c08812a60108003fa340", "runc version") + flag.StringVar(&opt.runc, "runc", "dd56ece8236d6d9e5bed4ea0c31fe53c7b873ff4", "runc version") flag.StringVar(&opt.buildkit, "buildkit", "master", "buildkit version") flag.Parse() diff --git a/hack/dockerfiles/test.Dockerfile b/hack/dockerfiles/test.Dockerfile index 9a076692..025b7e3e 100644 --- a/hack/dockerfiles/test.Dockerfile +++ b/hack/dockerfiles/test.Dockerfile @@ -1,10 +1,11 @@ -ARG RUNC_VERSION=69663f0bd4b60df09991c08812a60108003fa340 +ARG RUNC_VERSION=dd56ece8236d6d9e5bed4ea0c31fe53c7b873ff4 ARG CONTAINERD_VERSION=v1.1.0 # containerd v1.0 for integration tests ARG CONTAINERD10_VERSION=v1.0.3 # available targets: buildkitd, buildkitd.oci_only, buildkitd.containerd_only ARG BUILDKIT_TARGET=buildkitd ARG REGISTRY_VERSION=2.6 +ARG ROOTLESSKIT_VERSION=1e79dc31d71ea8c1a27f15086be2be2b1d99acaa # The `buildkitd` stage and the `buildctl` stage are placed here # so that they can be built quickly with legacy DAG-unaware `docker build --target=...` @@ -122,6 +123,33 @@ VOLUME /var/lib/containerd VOLUME /run/containerd ENTRYPOINT ["containerd"] +FROM gobuild-base AS rootlesskit-base +RUN git clone https://github.com/AkihiroSuda/rootlesskit.git /go/src/github.com/AkihiroSuda/rootlesskit +WORKDIR /go/src/github.com/AkihiroSuda/rootlesskit + +FROM rootlesskit-base as rootlesskit +ARG ROOTLESSKIT_VERSION +RUN git checkout -q "$ROOTLESSKIT_VERSION" \ + && go build -o /rootlesskit ./cmd/rootlesskit + +# Rootless mode. +# Still requires `--privileged`. +FROM buildkit-buildkitd AS rootless +RUN apk add --no-cache shadow shadow-uidmap \ + && useradd --create-home --home-dir /home/user --uid 1000 user \ + && mkdir -p /home/user/.local/run /home/user/.local/tmp /home/user/.local/share/buildkit \ + && chown -R user /home/user +COPY --from=rootlesskit /rootlesskit /usr/bin/ +USER user +ENV HOME /home/user +ENV USER user +# WORKAROUND: this should be typically /run/user/1000, +# but mkdir under /run is not captured when built using BuildKit. (#429) +ENV XDG_RUNTIME_DIR=/home/user/.local/run +ENV TMPDIR=/home/user/.local/tmp +VOLUME /home/user/.local/share/buildkit +ENTRYPOINT ["rootlesskit", "buildkitd"] + FROM buildkit-${BUILDKIT_TARGET}