Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

WIP: Add Checkpoint and Restore support to libcontainer #479

Merged
merged 51 commits into from
May 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
6fec592
Add Checkpoint and Restore methods to Container
crosbymichael Mar 6, 2015
da009f5
Add nsinit support for checkpoint and restore
crosbymichael Mar 6, 2015
f15aba6
Update criu support with restored processes
crosbymichael Mar 13, 2015
406f32a
Set default criu binary
crosbymichael Mar 13, 2015
9212f68
Some C/R bug fixes and changes in the new libcontainer and nsinit.
Mar 19, 2015
f705221
go: fmt
avagin Mar 25, 2015
b28fbb2
cr: don't umount rootfs which was not mounted by us
avagin Mar 25, 2015
e75d022
cr: wait the criu process properly
avagin Mar 25, 2015
0eea415
ct: execute CRIU restore with the --restore-detached option
avagin Mar 26, 2015
c0640ae
vendor: add protobuf
avagin Mar 30, 2015
c920f5f
cr: add criu_rpc.proto
avagin Mar 27, 2015
b836046
cr: use the RPC protocol for communication with criu
avagin Mar 26, 2015
e0f87e2
cr: check criu version
avagin Apr 1, 2015
5df3a07
cr: split work and image directories
avagin Apr 2, 2015
5231fbf
Dockerfile: don't call go get
avagin Apr 6, 2015
f5fad10
protobuf: workaround a go vet error
avagin Apr 10, 2015
5fb0019
Add the Checkpointed state
avagin Apr 10, 2015
522f7b3
cr: Add an ability to specify path for images
avagin Apr 10, 2015
65f9b1b
cr: handle criu notifications in a separate function
avagin Apr 10, 2015
6f1d940
cr: split the Restore function
avagin Apr 10, 2015
3979542
cr: user criu swrk to dump CT
avagin Apr 10, 2015
553b8be
cr: prepare a container root
avagin Apr 16, 2015
328786f
cr: don't remove images after restore
avagin Apr 17, 2015
032aca3
Exclude the root path from mount point paths.
boucher Apr 19, 2015
eaa35f5
cr: add network support
avagin Apr 20, 2015
cbe747d
cr: add a comment about bind-mounting root in a tmp dir
avagin Apr 22, 2015
a8d5fdf
Add support for providing options to CRIU.
boucher Apr 19, 2015
4fc7543
Don't write a "checkpoint" file if the process is left running.
boucher Apr 20, 2015
7a012fe
Allow dumped image to be transferred to a criu page server
Apr 23, 2015
d278b83
Change criu command line format for page server
Apr 24, 2015
67636f1
Change --page-server to --PageServer
Apr 24, 2015
1d89a25
Fix a nil pointer bug when doing local checkpoint
Apr 24, 2015
46dd56b
Change back to --page-server, PageServer should be in CriOpts struct
Apr 24, 2015
129280a
Write the fd info to the image directory during a checkpoint,
boucher Apr 28, 2015
38635c5
Move the std_fds into initProcess, and expose them in container's State
boucher Apr 28, 2015
3d59a7f
Refactor saving fds slightly, set the restored process fds correctly.
boucher Apr 28, 2015
6ecf32c
Restore StdFds from the state file
avagin Apr 29, 2015
655f1ce
Rename StdFds into ExternalDescriptors
avagin Apr 29, 2015
8f0cad5
Don't fix the size of the ExternalDescriptors array
avagin Apr 29, 2015
78a21b7
Fix formatting issues, and missing test methods.
boucher Apr 29, 2015
7d32656
cr: handle all external descriptros in ct.Restore()
avagin Apr 29, 2015
7c138eb
Reformat some error handling code and declare descriptor filename as …
boucher May 4, 2015
420180a
Require criu 1.5.2 rather than 1.5.1
boucher May 4, 2015
a16d7f1
container: don't use c.initProcess before it's set
avagin May 14, 2015
bfb093a
Allow restore to actually exec/create the libcontainer, rather than r…
boucher May 14, 2015
b3ec1fc
Add steps to install criu to the Dockerfile
boucher May 15, 2015
206b5e6
First attempt at an integration test for checkpoint/restore.
boucher May 18, 2015
5f6ea0e
cr: fix parsing of criu version
avagin May 19, 2015
e754214
Remove logging for checkpoint code
crosbymichael May 20, 2015
fee819c
README example for using checkpoint/restore.
boucher May 21, 2015
703d9a1
Merge pull request #600 from boucher/criu-readme
crosbymichael May 21, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM golang:1.4

RUN echo "deb http://ftp.us.debian.org/debian testing main contrib" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y iptables criu=1.5.2-1 && rm -rf /var/lib/apt/lists/*

RUN go get golang.org/x/tools/cmd/cover

ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
Expand All @@ -16,7 +19,6 @@ COPY . /go/src/github.com/docker/libcontainer
WORKDIR /go/src/github.com/docker/libcontainer
RUN cp sample_configs/minimal.json /busybox/container.json

RUN go get -d -v ./...
RUN make direct-install

ENTRYPOINT ["/dind"]
Expand Down
70 changes: 51 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
## libcontainer - reference implementation for containers [![Build Status](https://jenkins.dockerproject.com/buildStatus/icon?job=Libcontainer Master)](https://jenkins.dockerproject.com/job/Libcontainer%20Master/)
## libcontainer - reference implementation for containers [![Build Status](https://jenkins.dockerproject.com/buildStatus/icon?job=Libcontainer Master)](https://jenkins.dockerproject.com/job/Libcontainer%20Master/)

Libcontainer provides a native Go implementation for creating containers
Libcontainer provides a native Go implementation for creating containers
with namespaces, cgroups, capabilities, and filesystem access controls.
It allows you to manage the lifecycle of the container performing additional operations
after the container is created.


#### Container
A container is a self contained execution environment that shares the kernel of the
A container is a self contained execution environment that shares the kernel of the
host system and which is (optionally) isolated from other containers in the system.

#### Using libcontainer
Expand All @@ -27,7 +27,7 @@ if err != nil {
}
```

Once you have an instance of the factory created we can create a configuration
Once you have an instance of the factory created we can create a configuration
struct describing how the container is to be created. A sample would look similar to this:

```go
Expand Down Expand Up @@ -120,9 +120,9 @@ Additional ways to interact with a running container are:

```go
// return all the pids for all processes running inside the container.
processes, err := container.Processes()
processes, err := container.Processes()

// get detailed cpu, memory, io, and network statistics for the container and
// get detailed cpu, memory, io, and network statistics for the container and
// it's processes.
stats, err := container.Stats()

Expand All @@ -137,37 +137,69 @@ container.Resume()

#### nsinit

`nsinit` is a cli application which demonstrates the use of libcontainer.
`nsinit` is a cli application which demonstrates the use of libcontainer.
It is able to spawn new containers or join existing containers. A root
filesystem must be provided for use along with a container configuration file.

To build `nsinit`, run `make binary`. It will save the binary into
`bundles/nsinit`.

To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into
the directory with your specified configuration. Environment, networking,
and different capabilities for the container are specified in this file.
To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into
the directory with your specified configuration. Environment, networking,
and different capabilities for the container are specified in this file.
The configuration is used for each process executed inside the container.

See the `sample_configs` folder for examples of what the container configuration should look like.

To execute `/bin/bash` in the current directory as a container just run the following **as root**:
```bash
nsinit exec --tty /bin/bash
```

If you wish to spawn another process inside the container while your
current bash session is running, run the same command again to
get another bash shell (or change the command). If the original
process (PID 1) dies, all other processes spawned inside the container
will be killed and the namespace will be removed.
If you wish to spawn another process inside the container while your
current bash session is running, run the same command again to
get another bash shell (or change the command). If the original
process (PID 1) dies, all other processes spawned inside the container
will be killed and the namespace will be removed.

You can identify if a process is running in a container by
You can identify if a process is running in a container by
looking to see if `state.json` is in the root of the directory.
You may also specify an alternate root place where

You may also specify an alternate root place where
the `container.json` file is read and where the `state.json` file will be saved.


#### Checkpoint & Restore

libcontainer now integrates [CRIU](http://criu.org/) for checkpointing and restoring containers.
This let's you save the state of a process running inside a container to disk, and then restore
that state into a new process, on the same machine or on another machine.

`criu` version 1.5.2 or higher is required to use checkpoint and restore.
If you don't already have `criu` installed, you can build it from source, following the
[online instructions](http://criu.org/Installation). `criu` is also installed in the docker image
generated when building libcontainer with docker.

To try an example with `nsinit`, open two terminals to the same busybox directory.
In the first terminal, run a command like this one:
```bash
nsinit exec -- sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
```

You should see logs printing to the terminal every second. Now, in the second terminal, run:
```bash
nsinit checkpoint --image-path=/tmp/criu
```

The logs in your first terminal will stop and the process will exit. Finally, in the second
terminal, run the restore command:
```bash
nsinit restore --image-path=/tmp/criu
```

The process will resume counting where it left off and printing to the new terminal window.


#### Future
See the [roadmap](ROADMAP.md).

Expand Down
18 changes: 18 additions & 0 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const (
// The container exists, but all its processes are paused.
Paused

// The container exists, but its state is saved on disk
Checkpointed

// The container does not exist.
Destroyed
)
Expand All @@ -46,6 +49,9 @@ type State struct {

// Config is the container's configuration.
Config configs.Config `json:"config"`

// Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore
ExternalDescriptors []string `json:"external_descriptors,omitempty"`
}

// A libcontainer container object.
Expand Down Expand Up @@ -108,6 +114,18 @@ type Container interface {
// Systemerror - System error.
Start(process *Process) (err error)

// Checkpoint checkpoints the running container's state to disk using the criu(8) utility.
//
// errors:
// Systemerror - System error.
Checkpoint(criuOpts *CriuOpts) error

// Restore restores the checkpointed container to a running state using the criu(8) utiity.
//
// errors:
// Systemerror - System error.
Restore(process *Process, criuOpts *CriuOpts) error

// Destroys the container after killing all running processes.
//
// Any event registrations are removed before the container is destroyed.
Expand Down
Loading