2017-01-04 16:33:42 +08:00
# runc
[![Build Status ](https://travis-ci.org/opencontainers/runc.svg?branch=master )](https://travis-ci.org/opencontainers/runc)
[![Go Report Card ](https://goreportcard.com/badge/github.com/opencontainers/runc )](https://goreportcard.com/report/github.com/opencontainers/runc)
2017-01-21 21:55:49 +08:00
[![GoDoc ](https://godoc.org/github.com/opencontainers/runc?status.svg )](https://godoc.org/github.com/opencontainers/runc)
2017-01-04 16:33:42 +08:00
## Introduction
2015-06-22 10:31:12 +08:00
2016-04-14 01:38:58 +08:00
`runc` is a CLI tool for spawning and running containers according to the OCI specification.
2015-06-22 10:31:12 +08:00
2016-06-11 07:16:55 +08:00
## Releases
2015-06-27 02:31:00 +08:00
2016-09-01 00:43:24 +08:00
`runc` depends on and tracks the [runtime-spec ](https://github.com/opencontainers/runtime-spec ) repository.
2016-06-11 07:16:55 +08:00
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.
2015-06-27 02:31:00 +08:00
2016-09-06 22:54:25 +08:00
You can find official releases of `runc` on the [release ](https://github.com/opencontainers/runc/releases ) page.
2015-07-03 00:59:30 +08:00
2019-10-18 15:59:14 +08:00
Currently, the following features are not considered to be production-ready:
* Support for cgroup v2
2019-03-04 04:00:09 +08:00
## Security
2016-12-03 15:54:53 +08:00
2020-01-26 22:03:13 +08:00
The reporting process and disclosure communications are outlined [here ](https://github.com/opencontainers/org/blob/master/SECURITY.md ).
2016-12-03 15:54:53 +08:00
2019-12-21 07:53:32 +08:00
### Security Audit
A third party security audit was performed by Cure53, you can see the full report [here ](https://github.com/opencontainers/runc/blob/master/docs/Security-Audit.pdf ).
2016-06-11 07:16:55 +08:00
## Building
2015-07-03 00:59:30 +08:00
2016-12-03 15:54:53 +08:00
`runc` currently supports the Linux platform with various architecture support.
2016-06-11 07:16:55 +08:00
It must be built with Go version 1.6 or higher in order for some features to function properly.
2015-08-27 15:50:46 +08:00
2016-10-31 15:04:51 +08:00
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.
2015-06-22 10:31:12 +08:00
```bash
2015-07-08 19:10:22 +08:00
# create a 'github.com/opencontainers' in your GOPATH/src
2015-06-24 12:25:49 +08:00
cd github.com/opencontainers
git clone https://github.com/opencontainers/runc
cd runc
2016-06-11 07:16:55 +08:00
2015-06-22 10:31:12 +08:00
make
sudo make install
```
2018-02-22 04:54:14 +08:00
You can also use `go get` to install to your `GOPATH` , assuming that you have a `github.com` parent folder already created under `src` :
```bash
go get github.com/opencontainers/runc
cd $GOPATH/src/github.com/opencontainers/runc
make
sudo make install
```
2016-06-11 07:16:55 +08:00
`runc` will be installed to `/usr/local/sbin/runc` on your system.
2018-02-22 04:54:14 +08:00
2015-09-12 03:11:24 +08:00
#### Build Tags
2016-06-11 07:16:55 +08:00
`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.
2015-09-12 03:11:24 +08:00
2016-06-11 07:16:55 +08:00
```bash
make BUILDTAGS='seccomp apparmor'
```
2015-09-12 03:11:24 +08:00
| Build Tag | Feature | Dependency |
|-----------|------------------------------------|-------------|
| seccomp | Syscall filtering | libseccomp |
| selinux | selinux process and mount labeling | < none > |
2017-12-11 18:19:13 +08:00
| apparmor | apparmor profile support | < none > |
2016-11-03 01:47:22 +08:00
| ambient | ambient capability support | kernel 4.3 |
2018-11-02 11:50:19 +08:00
| nokmem | disable kernel memory account | < none > |
2015-09-12 03:11:24 +08:00
2015-09-15 08:30:28 +08:00
2016-06-11 07:16:55 +08:00
### Running the test suite
`runc` currently supports running its test suite via Docker.
To run the suite just type `make test` .
2015-09-15 08:30:28 +08:00
```bash
2016-06-11 07:16:55 +08:00
make test
2015-09-15 08:30:28 +08:00
```
2016-06-11 07:16:55 +08:00
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.
2015-09-15 08:30:28 +08:00
2016-06-11 07:16:55 +08:00
You can run a specific test case by setting the `TESTFLAGS` variable.
2015-09-15 08:30:28 +08:00
```bash
# make test TESTFLAGS="-run=SomeTestFunction"
```
2015-09-12 03:11:24 +08:00
2018-07-31 12:33:42 +08:00
You can run a specific integration test by setting the `TESTPATH` variable.
```bash
# make test TESTPATH="/checkpoint.bats"
```
2020-02-03 14:03:26 +08:00
You can run a test using your container engine's flags by setting `CONTAINER_ENGINE_BUILD_FLAGS` and `CONTAINER_ENGINE_RUN_FLAGS` variables.
2018-07-31 12:17:16 +08:00
```bash
2020-02-03 14:03:26 +08:00
# make test CONTAINER_ENGINE_BUILD_FLAGS="--build-arg http_proxy=http://yourproxy/" CONTAINER_ENGINE_RUN_FLAGS="-e http_proxy=http://yourproxy/"
2018-07-31 12:17:16 +08:00
```
2017-02-23 08:35:56 +08:00
### 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.
2016-06-11 07:16:55 +08:00
## Using runc
### Creating an OCI Bundle
2015-06-22 10:31:12 +08:00
2016-06-11 07:16:55 +08:00
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.
2016-02-09 06:25:03 +08:00
2015-08-18 09:30:17 +08:00
```bash
2016-06-11 07:16:55 +08:00
# 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 -
2015-08-18 09:30:17 +08:00
```
2015-06-22 10:31:12 +08:00
2016-06-11 07:16:55 +08:00
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.
2015-06-22 10:31:12 +08:00
2016-06-11 07:16:55 +08:00
```bash
runc spec
```
2015-10-27 15:34:38 +08:00
2016-06-11 07:16:55 +08:00
### Running Containers
2015-06-22 10:31:12 +08:00
2016-06-11 07:16:55 +08:00
Assuming you have an OCI bundle from the previous step you can execute the container in two different ways.
2015-06-24 12:25:49 +08:00
2016-06-11 07:16:55 +08:00
The first way is to use the convenience command `run` that will handle creating, starting, and deleting the container after it exits.
```bash
2017-04-22 07:43:56 +08:00
# run as root
2016-06-11 07:16:55 +08:00
cd /mycontainer
runc run mycontainerid
2015-06-24 12:25:49 +08:00
```
2016-06-11 07:16:55 +08:00
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.
2016-10-23 01:22:18 +08:00
This gives you more power over how the container is created and managed while it is running.
2016-06-11 07:16:55 +08:00
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": "/",
2017-07-25 19:46:20 +08:00
"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"
]
},
2016-06-11 07:16:55 +08:00
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"noNewPrivileges": true
},
2015-06-24 12:25:49 +08:00
```
2016-06-11 07:16:55 +08:00
2017-07-25 19:46:20 +08:00
Now we can go through the lifecycle operations in your shell.
2016-06-11 07:16:55 +08:00
```bash
2017-04-22 07:43:56 +08:00
# run as root
2016-06-11 07:16:55 +08:00
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
2015-06-24 12:25:49 +08:00
```
2018-03-02 05:12:48 +08:00
This allows higher level systems to augment the containers creation logic with setup of various settings after the container is created and/or before it is deleted. For example, the container's network stack is commonly set up after `create` but before `start` .
2015-06-22 10:31:12 +08:00
2017-04-22 07:43:56 +08:00
#### Rootless containers
2018-11-16 13:37:23 +08:00
`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.
**Note:** In order to use this feature, "User Namespaces" must be compiled and enabled in your kernel. There are various ways to do this depending on your distribution:
- Confirm `CONFIG_USER_NS=y` is set in your kernel configuration (normally found in `/proc/config.gz` )
- Arch/Debian: `echo 1 > /proc/sys/kernel/unprivileged_userns_clone`
- RHEL/CentOS 7: `echo 28633 > /proc/sys/user/max_user_namespaces`
Run the following commands as an ordinary user:
2017-04-22 07:43:56 +08:00
```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
```
2016-06-11 07:16:55 +08:00
#### Supervisors
2015-10-28 16:21:39 +08:00
2016-06-11 07:16:55 +08:00
`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
2015-06-22 10:31:12 +08:00
[Unit]
2016-06-11 07:16:55 +08:00
Description=Start My Container
2015-06-22 10:31:12 +08:00
[Service]
2016-06-11 07:16:55 +08:00
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
2015-06-22 10:31:12 +08:00
[Install]
WantedBy=multi-user.target
```
2018-10-03 23:36:01 +08:00
## License
The code and docs are released under the [Apache 2.0 license ](LICENSE ).