Find a file
Jess Frazelle 61704ab871 Merge branch 'thaJeztah-fixus-typos2'
* thaJeztah-fixus-typos2:
  Fix typoe
2016-04-16 16:09:15 -07:00
vendor debugging 2016-04-16 16:05:09 -07:00
.gitignore updates 2016-04-15 21:53:49 -07:00
circle.yml init commit 2016-04-14 23:42:40 -07:00
generate.go updates 2016-04-15 21:53:49 -07:00
LICENSE init commit 2016-04-14 23:42:40 -07:00
main.go debugging 2016-04-16 16:05:09 -07:00
main_unix.go updates 2016-04-15 21:53:49 -07:00
Makefile debugging 2016-04-16 16:05:09 -07:00
nginx.png debugging 2016-04-16 16:05:09 -07:00
README.md Merge branch 'fixus-typos2' of github.com:thaJeztah/binctr into thaJeztah-fixus-typos2 2016-04-16 16:08:55 -07:00
rlimit_linux.go init commit 2016-04-14 23:42:40 -07:00
rootfs_ops.go updates 2016-04-15 21:53:49 -07:00
seccomp.go init commit 2016-04-14 23:42:40 -07:00
seccomp.json init commit 2016-04-14 23:42:40 -07:00
signals.go updates 2016-04-15 21:53:49 -07:00
spec.go updates 2016-04-15 21:53:49 -07:00
tty.go updates 2016-04-15 21:53:49 -07:00
utils.go updates 2016-04-15 21:53:49 -07:00
VERSION init commit 2016-04-14 23:42:40 -07:00

binctr

Create fully static, including rootfs embedded, binaries that pop you directly into a container. Can be run by an unprivileged user.

This is based off a crazy idea from @crosbymichael who first embedded an image in a binary :D

NOTE

You may have noticed you can't file an issue. That's because this is using a crazy person's (aka my) fork of libcontainer and until I get the patches into upstream there's no way in hell I'm fielding issues from whoever is crazy enough to try this.

Nginx running with my user "jessie".

nginx.png

Building

This uses the new Golang vendoring so you need go 1.6 or GO15VENDOREXPERIMENT=1 in your env.

You will also need libapparmor-dev and libseccomp-dev.

Most importantly you need userns in your kernel (CONFIG_USER_NS=y) or else this won't even work.

$ make static
Static container created at: ./bin/alpine
Run with ./bin/alpine

# building a different base image
$ make static IMAGE=busybox
Static container created at: ./bin/busybox
Run with ./bin/busybox

Running

$ ./alpine
$ ./busybox --read-only

Running with custom commands & args

# let's make an nginx binary
$ make static IMAGE=nginx
Static container created at: ./bin/nginx
Run with ./bin/nginx

$ ./bin/nginx nginx -g "daemon off;"

# But we have no networking! Don't worry we can fix this
# Let's install my super cool binary for setting up networking in a container
$ go get github.com/jfrazelle/netns

# now we can add this as a prestart hook
$ ./bin/nginx --hook prestart:netns nginx -g "daemon off;"

# let's get the ip file
$ cat .ip
172.19.0.10

Success!

Usage

$ ./bin/alpine -h
 _     _            _
| |__ (_)_ __   ___| |_ _ __
| '_ \| | '_ \ / __| __| '__|
| |_) | | | | | (__| |_| |
|_.__/|_|_| |_|\___|\__|_|

 Fully static, self-contained container including the rootfs
 that can be run by an unprivileged user.

 Embedded Image: alpine - sha256:70c557e50ed630deed07cbb0dc4d28aa0f2a485cf7af124cc48f06bce83f784b
 Version: 0.1.0
 GitCommit: 13fcd27-dirty

  -D	run in debug mode
  -console string
    	the pty slave path for use with the container
  -d	detach from the container's process
  -hook value
    	Hooks to prefill into spec file. (ex. --hook prestart:netns) (default [])
  -id string
    	container ID (default "nginx")
  -pid-file string
    	specify the file to write the process id to
  -read-only
    	make container filesystem readonly
  -root string
    	root directory of container state, should be tmpfs (default "/run/binctr")
  -t	allocate a tty for the container (default true)
  -v	print version and exit (shorthand)
  -version
    	print version and exit

Cool things

The binary spawned does NOT need to oversee the container process if you run in detached mode with a PID file. You can have it watched by the user mode systemd so that this binary is really just the launcher :)

Caveats

Caps the binary needs to unpack and set the right perms on the rootfs for the userns user

  • CAP_CHOWN: chown the rootfs to the userns user
  • CAP_FOWNER: chmod rootfs
  • CAP_DAC_OVERRIDE: symlinks

These can be dropped after the rootfs is unpacked and chowned.


Caps for libcontainer