| # runc |
| |
| [](https://travis-ci.org/opencontainers/runc) |
| [](https://goreportcard.com/report/github.com/opencontainers/runc) |
| [](https://godoc.org/github.com/opencontainers/runc) |
| |
| ## Introduction |
| |
| `runc` is a CLI tool for spawning and running containers according to the OCI specification. |
| |
| ## Releases |
| |
| `runc` depends on and tracks the [runtime-spec](https://github.com/opencontainers/runtime-spec) repository. |
| We will try to make sure that `runc` and the OCI specification major versions stay in lockstep. |
| This means that `runc` 1.0.0 should implement the 1.0 version of the specification. |
| |
| You can find official releases of `runc` on the [release](https://github.com/opencontainers/runc/releases) page. |
| |
| ### Security |
| |
| If you wish to report a security issue, please disclose the issue responsibly |
| to security@opencontainers.org. |
| |
| ## Building |
| |
| `runc` currently supports the Linux platform with various architecture support. |
| It must be built with Go version 1.6 or higher in order for some features to function properly. |
| |
| In order to enable seccomp support you will need to install `libseccomp` on your platform. |
| > e.g. `libseccomp-devel` for CentOS, or `libseccomp-dev` for Ubuntu |
| |
| Otherwise, if you do not want to build `runc` with seccomp support you can add `BUILDTAGS=""` when running make. |
| |
| ```bash |
| # create a 'github.com/opencontainers' in your GOPATH/src |
| cd github.com/opencontainers |
| git clone https://github.com/opencontainers/runc |
| cd runc |
| |
| make |
| sudo make install |
| ``` |
| |
| `runc` will be installed to `/usr/local/sbin/runc` on your system. |
| |
| #### Build Tags |
| |
| `runc` supports optional build tags for compiling support of various features. |
| To add build tags to the make option the `BUILDTAGS` variable must be set. |
| |
| ```bash |
| make BUILDTAGS='seccomp apparmor' |
| ``` |
| |
| | Build Tag | Feature | Dependency | |
| |-----------|------------------------------------|-------------| |
| | seccomp | Syscall filtering | libseccomp | |
| | selinux | selinux process and mount labeling | <none> | |
| | apparmor | apparmor profile support | libapparmor | |
| | ambient | ambient capability support | kernel 4.3 | |
| |
| |
| ### Running the test suite |
| |
| `runc` currently supports running its test suite via Docker. |
| To run the suite just type `make test`. |
| |
| ```bash |
| make test |
| ``` |
| |
| There are additional make targets for running the tests outside of a container but this is not recommended as the tests are written with the expectation that they can write and remove anywhere. |
| |
| You can run a specific test case by setting the `TESTFLAGS` variable. |
| |
| ```bash |
| # make test TESTFLAGS="-run=SomeTestFunction" |
| ``` |
| |
| ### Dependencies Management |
| |
| `runc` uses [vndr](https://github.com/LK4D4/vndr) for dependencies management. |
| Please refer to [vndr](https://github.com/LK4D4/vndr) for how to add or update |
| new dependencies. |
| |
| ## Using runc |
| |
| ### Creating an OCI Bundle |
| |
| In order to use runc you must have your container in the format of an OCI bundle. |
| If you have Docker installed you can use its `export` method to acquire a root filesystem from an existing Docker container. |
| |
| ```bash |
| # create the top most bundle directory |
| mkdir /mycontainer |
| cd /mycontainer |
| |
| # create the rootfs directory |
| mkdir rootfs |
| |
| # export busybox via Docker into the rootfs directory |
| docker export $(docker create busybox) | tar -C rootfs -xvf - |
| ``` |
| |
| After a root filesystem is populated you just generate a spec in the format of a `config.json` file inside your bundle. |
| `runc` provides a `spec` command to generate a base template spec that you are then able to edit. |
| To find features and documentation for fields in the spec please refer to the [specs](https://github.com/opencontainers/runtime-spec) repository. |
| |
| ```bash |
| runc spec |
| ``` |
| |
| ### Running Containers |
| |
| Assuming you have an OCI bundle from the previous step you can execute the container in two different ways. |
| |
| The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits. |
| |
| ```bash |
| # run as root |
| cd /mycontainer |
| runc run mycontainerid |
| ``` |
| |
| If you used the unmodified `runc spec` template this should give you a `sh` session inside the container. |
| |
| The second way to start a container is using the specs lifecycle operations. |
| This gives you more power over how the container is created and managed while it is running. |
| This will also launch the container in the background so you will have to edit the `config.json` to remove the `terminal` setting for the simple examples here. |
| Your process field in the `config.json` should look like this below with `"terminal": false` and `"args": ["sleep", "5"]`. |
| |
| |
| ```json |
| "process": { |
| "terminal": false, |
| "user": { |
| "uid": 0, |
| "gid": 0 |
| }, |
| "args": [ |
| "sleep", "5" |
| ], |
| "env": [ |
| "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| "TERM=xterm" |
| ], |
| "cwd": "/", |
| "capabilities": { |
| "bounding": [ |
| "CAP_AUDIT_WRITE", |
| "CAP_KILL", |
| "CAP_NET_BIND_SERVICE" |
| ], |
| "effective": [ |
| "CAP_AUDIT_WRITE", |
| "CAP_KILL", |
| "CAP_NET_BIND_SERVICE" |
| ], |
| "inheritable": [ |
| "CAP_AUDIT_WRITE", |
| "CAP_KILL", |
| "CAP_NET_BIND_SERVICE" |
| ], |
| "permitted": [ |
| "CAP_AUDIT_WRITE", |
| "CAP_KILL", |
| "CAP_NET_BIND_SERVICE" |
| ], |
| "ambient": [ |
| "CAP_AUDIT_WRITE", |
| "CAP_KILL", |
| "CAP_NET_BIND_SERVICE" |
| ] |
| }, |
| "rlimits": [ |
| { |
| "type": "RLIMIT_NOFILE", |
| "hard": 1024, |
| "soft": 1024 |
| } |
| ], |
| "noNewPrivileges": true |
| }, |
| ``` |
| |
| Now we can go through the lifecycle operations in your shell. |
| |
| |
| ```bash |
| # run as root |
| cd /mycontainer |
| runc create mycontainerid |
| |
| # view the container is created and in the "created" state |
| runc list |
| |
| # start the process inside the container |
| runc start mycontainerid |
| |
| # after 5 seconds view that the container has exited and is now in the stopped state |
| runc list |
| |
| # now delete the container |
| runc delete mycontainerid |
| ``` |
| |
| This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted. |
| This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running. |
| |
| #### Rootless containers |
| `runc` has the ability to run containers without root privileges. This is called `rootless`. You need to pass some parameters to `runc` in order to run rootless containers. See below and compare with the previous version. Run the following commands as an ordinary user: |
| ```bash |
| # Same as the first example |
| mkdir ~/mycontainer |
| cd ~/mycontainer |
| mkdir rootfs |
| docker export $(docker create busybox) | tar -C rootfs -xvf - |
| |
| # The --rootless parameter instructs runc spec to generate a configuration for a rootless container, which will allow you to run the container as a non-root user. |
| runc spec --rootless |
| |
| # The --root parameter tells runc where to store the container state. It must be writable by the user. |
| runc --root /tmp/runc run mycontainerid |
| ``` |
| |
| #### Supervisors |
| |
| `runc` can be used with process supervisors and init systems to ensure that containers are restarted when they exit. |
| An example systemd unit file looks something like this. |
| |
| ```systemd |
| [Unit] |
| Description=Start My Container |
| |
| [Service] |
| Type=forking |
| ExecStart=/usr/local/sbin/runc run -d --pid-file /run/mycontainerid.pid mycontainerid |
| ExecStopPost=/usr/local/sbin/runc delete mycontainerid |
| WorkingDirectory=/mycontainer |
| PIDFile=/run/mycontainerid.pid |
| |
| [Install] |
| WantedBy=multi-user.target |
| ``` |