Skip to content

Commit 511c7e7

Browse files
committed
implement rootless mode
Please refer to docs/rootless.md Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
1 parent ff49ce8 commit 511c7e7

37 files changed

+4321
-10
lines changed

cmd/buildkitd/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ func main() {
9797
Name: "tlscacert",
9898
Usage: "ca certificate to verify clients",
9999
},
100+
cli.BoolFlag{
101+
Name: "rootless",
102+
Usage: "execute without root privileges",
103+
// TODO(AkihiroSuda): autodetect rootless mode
104+
// TODO(AkihiroSuda): user-friendly help messages
105+
},
100106
}
101107

102108
app.Flags = append(app.Flags, appFlags...)

cmd/buildkitd/main_containerd_worker.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ func containerdWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([
5252
if err != nil {
5353
return nil, err
5454
}
55+
if c.GlobalBool("rootless") {
56+
logrus.Warn("rootless mode is not supported for containerd workers")
57+
}
5558
opt, err := containerd.NewWorkerOpt(common.root, socket, ctd.DefaultSnapshotter, labels)
5659
if err != nil {
5760
return nil, err

cmd/buildkitd/main_oci_worker.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55
import (
66
"os/exec"
77

8+
"github.com/moby/buildkit/executor/runcexecutor"
89
"github.com/moby/buildkit/worker"
910
"github.com/moby/buildkit/worker/base"
1011
"github.com/moby/buildkit/worker/runc"
@@ -27,6 +28,11 @@ func init() {
2728
Name: "oci-worker-labels",
2829
Usage: "user-specific annotation labels (com.example.foo=bar)",
2930
},
31+
cli.BoolTFlag{
32+
Name: "oci-worker-overlayfs",
33+
Usage: "enable overlayfs snapshotter", // and differ when implemented
34+
// TODO(AkihiroSuda): autodetect overlayfs availability?
35+
},
3036
)
3137
// TODO: allow multiple oci runtimes and snapshotters
3238
}
@@ -43,7 +49,10 @@ func ociWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([]worker
4349
if err != nil {
4450
return nil, err
4551
}
46-
opt, err := runc.NewWorkerOpt(common.root, labels)
52+
exeOpt := runcexecutor.Opt{
53+
Rootless: c.GlobalBool("rootless"),
54+
}
55+
opt, err := runc.NewWorkerOpt(common.root, labels, c.GlobalBoolT("oci-worker-overlayfs"), &exeOpt)
4756
if err != nil {
4857
return nil, err
4958
}

docs/rootless.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Rootless mode (Experimental)
2+
3+
Requirements:
4+
- runc with https://github.com/opencontainers/runc/pull/1688
5+
- Some distros such as Arch Linux require `echo 1 > /proc/sys/kernel/unprivileged_ns_clone`
6+
7+
8+
## Terminal 1:
9+
10+
```
11+
$ unshare -U -m
12+
unshared$ echo $$
13+
3539
14+
```
15+
16+
Unsharing mountns (and userns) is required for mounting filesystems without real root privileges.
17+
18+
## Terminal 2:
19+
20+
```
21+
$ id -u
22+
1001
23+
$ grep $(whoami) /etc/subuid
24+
suda:231072:65536
25+
$ grep $(whoami) /etc/subgid
26+
suda:231072:65536
27+
$ newuidmap 3539 0 1001 1 1 231072 65536
28+
$ newgidmap 3539 0 1001 1 1 231072 65536
29+
```
30+
31+
## Terminal 1:
32+
33+
```
34+
unshared# buildkitd --root /home/suda/.local/share/buildkit --addr unix:///run/user/1001/buildkitd.sock --containerd-worker false --oci-worker-overlayfs=false --root
35+
less
36+
```
37+
38+
- On Ubuntu, no need to specify `--oci-worker-overlayfs` to `false`, as unprivileged overlayfs is supported: http://kernel.ubuntu.com/git/ubuntu/ubuntu-artful.git/commit/fs/overlayfs?h=Ubuntu-4.13.0-25.29&id=0a414bdc3d01f3b61ed86cfe3ce8b63a9240eba7
39+
- containerd worker is not supported ( pending PR: https://github.com/containerd/containerd/pull/2006 )
40+
41+
## Terminal 2:
42+
43+
```
44+
$ go run ./examples/buildkit0 | buildctl --addr unix:///run/user/1001/buildkitd.sock build
45+
```
46+
47+
- `apt` is not supported (pending PRs: https://github.com/opencontainers/runc/pull/1693 https://github.com/opencontainers/runc/pull/1692 )

executor/oci/rootless.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package oci
2+
3+
import (
4+
"context"
5+
6+
"github.com/containerd/containerd/containers"
7+
"github.com/containerd/containerd/oci"
8+
"github.com/opencontainers/runc/libcontainer/specconv"
9+
specs "github.com/opencontainers/runtime-spec/specs-go"
10+
)
11+
12+
// WithRootless sets the container to be rootless mode.
13+
// This function will be removed when containerd/containerd#2006 gets merged
14+
func WithRootless(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error {
15+
specconv.ToRootless(s)
16+
// without removing CgroupsPath, runc fails:
17+
// "process_linux.go:279: applying cgroup configuration for process caused \"mkdir /sys/fs/cgroup/cpuset/default: permission denied\""
18+
s.Linux.CgroupsPath = ""
19+
return nil
20+
}

executor/runcexecutor/executor.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@ import (
2121
"github.com/sirupsen/logrus"
2222
)
2323

24+
type Opt struct {
25+
Rootless bool // execute runc without root privileges
26+
}
27+
2428
type runcExecutor struct {
29+
Opt
2530
runc *runc.Runc
2631
root string
2732
}
2833

29-
func New(root string) (executor.Executor, error) {
34+
func New(root string, opt *Opt) (executor.Executor, error) {
3035
if err := exec.Command("runc", "--version").Run(); err != nil {
3136
return nil, errors.Wrap(err, "failed to find runc binary")
3237
}
@@ -48,7 +53,12 @@ func New(root string) (executor.Executor, error) {
4853
Setpgid: true,
4954
}
5055

56+
var xopt Opt
57+
if opt != nil {
58+
xopt = *opt
59+
}
5160
w := &runcExecutor{
61+
Opt: xopt,
5262
runc: runtime,
5363
root: root,
5464
}
@@ -98,7 +108,11 @@ func (w *runcExecutor) Exec(ctx context.Context, meta executor.Meta, root cache.
98108
return err
99109
}
100110
defer f.Close()
101-
spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, resolvConf, hostsFile, containerdoci.WithUIDGID(uid, gid))
111+
specOpts := []containerdoci.SpecOpts{containerdoci.WithUIDGID(uid, gid)}
112+
if w.Opt.Rootless {
113+
specOpts = append(specOpts, oci.WithRootless)
114+
}
115+
spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, resolvConf, hostsFile, specOpts...)
102116
if err != nil {
103117
return err
104118
}

vendor.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
2626
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
2727
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
2828
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
29+
github.com/seccomp/libseccomp-golang 84e90a91acea0f4e51e62bc1a75de18b1fc0790f
2930

3031
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
3132
github.com/docker/go-units v0.3.1

vendor/github.com/opencontainers/runc/libcontainer/configs/blkio_device.go

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_windows.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)