README.md
1Libcontainer provides a native Go implementation for creating containers
2with namespaces, cgroups, capabilities, and filesystem access controls.
3It allows you to manage the lifecycle of the container performing additional operations
4after the container is created.
5
6
7#### Container
8A container is a self contained execution environment that shares the kernel of the
9host system and which is (optionally) isolated from other containers in the system.
10
11#### Using libcontainer
12
13Because containers are spawned in a two step process you will need a binary that
14will be executed as the init process for the container. In libcontainer, we use
15the current binary (/proc/self/exe) to be executed as the init process, and use
16arg "init", we call the first step process "bootstrap", so you always need a "init"
17function as the entry of "bootstrap".
18
19```go
20func init() {
21 if len(os.Args) > 1 && os.Args[1] == "init" {
22 runtime.GOMAXPROCS(1)
23 runtime.LockOSThread()
24 factory, _ := libcontainer.New("")
25 if err := factory.StartInitialization(); err != nil {
26 logrus.Fatal(err)
27 }
28 panic("--this line should have never been executed, congratulations--")
29 }
30}
31```
32
33Then to create a container you first have to initialize an instance of a factory
34that will handle the creation and initialization for a container.
35
36```go
37factory, err := libcontainer.New("/var/lib/container", libcontainer.Cgroupfs, libcontainer.InitArgs(os.Args[0], "init"))
38if err != nil {
39 logrus.Fatal(err)
40 return
41}
42```
43
44Once you have an instance of the factory created we can create a configuration
45struct describing how the container is to be created. A sample would look similar to this:
46
47```go
48defaultMountFlags := syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
49config := &configs.Config{
50 Rootfs: "/your/path/to/rootfs",
51 Capabilities: []string{
52 "CAP_CHOWN",
53 "CAP_DAC_OVERRIDE",
54 "CAP_FSETID",
55 "CAP_FOWNER",
56 "CAP_MKNOD",
57 "CAP_NET_RAW",
58 "CAP_SETGID",
59 "CAP_SETUID",
60 "CAP_SETFCAP",
61 "CAP_SETPCAP",
62 "CAP_NET_BIND_SERVICE",
63 "CAP_SYS_CHROOT",
64 "CAP_KILL",
65 "CAP_AUDIT_WRITE",
66 },
67 Namespaces: configs.Namespaces([]configs.Namespace{
68 {Type: configs.NEWNS},
69 {Type: configs.NEWUTS},
70 {Type: configs.NEWIPC},
71 {Type: configs.NEWPID},
72 {Type: configs.NEWUSER},
73 {Type: configs.NEWNET},
74 }),
75 Cgroups: &configs.Cgroup{
76 Name: "test-container",
77 Parent: "system",
78 Resources: &configs.Resources{
79 MemorySwappiness: nil,
80 AllowAllDevices: false,
81 AllowedDevices: configs.DefaultAllowedDevices,
82 },
83 },
84 MaskPaths: []string{
85 "/proc/kcore",
86 },
87 ReadonlyPaths: []string{
88 "/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
89 },
90 Devices: configs.DefaultAutoCreatedDevices,
91 Hostname: "testing",
92 Mounts: []*configs.Mount{
93 {
94 Source: "proc",
95 Destination: "/proc",
96 Device: "proc",
97 Flags: defaultMountFlags,
98 },
99 {
100 Source: "tmpfs",
101 Destination: "/dev",
102 Device: "tmpfs",
103 Flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME,
104 Data: "mode=755",
105 },
106 {
107 Source: "devpts",
108 Destination: "/dev/pts",
109 Device: "devpts",
110 Flags: syscall.MS_NOSUID | syscall.MS_NOEXEC,
111 Data: "newinstance,ptmxmode=0666,mode=0620,gid=5",
112 },
113 {
114 Device: "tmpfs",
115 Source: "shm",
116 Destination: "/dev/shm",
117 Data: "mode=1777,size=65536k",
118 Flags: defaultMountFlags,
119 },
120 {
121 Source: "mqueue",
122 Destination: "/dev/mqueue",
123 Device: "mqueue",
124 Flags: defaultMountFlags,
125 },
126 {
127 Source: "sysfs",
128 Destination: "/sys",
129 Device: "sysfs",
130 Flags: defaultMountFlags | syscall.MS_RDONLY,
131 },
132 },
133 UidMappings: []configs.IDMap{
134 {
135 ContainerID: 0,
136 HostID: 1000,
137 Size: 65536,
138 },
139 },
140 GidMappings: []configs.IDMap{
141 {
142 ContainerID: 0,
143 HostID: 1000,
144 Size: 65536,
145 },
146 },
147 Networks: []*configs.Network{
148 {
149 Type: "loopback",
150 Address: "127.0.0.1/0",
151 Gateway: "localhost",
152 },
153 },
154 Rlimits: []configs.Rlimit{
155 {
156 Type: syscall.RLIMIT_NOFILE,
157 Hard: uint64(1025),
158 Soft: uint64(1025),
159 },
160 },
161}
162```
163
164Once you have the configuration populated you can create a container:
165
166```go
167container, err := factory.Create("container-id", config)
168if err != nil {
169 logrus.Fatal(err)
170 return
171}
172```
173
174To spawn bash as the initial process inside the container and have the
175processes pid returned in order to wait, signal, or kill the process:
176
177```go
178process := &libcontainer.Process{
179 Args: []string{"/bin/bash"},
180 Env: []string{"PATH=/bin"},
181 User: "daemon",
182 Stdin: os.Stdin,
183 Stdout: os.Stdout,
184 Stderr: os.Stderr,
185}
186
187err := container.Start(process)
188if err != nil {
189 logrus.Fatal(err)
190 container.Destroy()
191 return
192}
193
194// wait for the process to finish.
195_, err := process.Wait()
196if err != nil {
197 logrus.Fatal(err)
198}
199
200// destroy the container.
201container.Destroy()
202```
203
204Additional ways to interact with a running container are:
205
206```go
207// return all the pids for all processes running inside the container.
208processes, err := container.Processes()
209
210// get detailed cpu, memory, io, and network statistics for the container and
211// it's processes.
212stats, err := container.Stats()
213
214// pause all processes inside the container.
215container.Pause()
216
217// resume all paused processes.
218container.Resume()
219
220// send signal to container's init process.
221container.Signal(signal)
222```
223
224
225#### Checkpoint & Restore
226
227libcontainer now integrates [CRIU](http://criu.org/) for checkpointing and restoring containers.
228This let's you save the state of a process running inside a container to disk, and then restore
229that state into a new process, on the same machine or on another machine.
230
231`criu` version 1.5.2 or higher is required to use checkpoint and restore.
232If you don't already have `criu` installed, you can build it from source, following the
233[online instructions](http://criu.org/Installation). `criu` is also installed in the docker image
234generated when building libcontainer with docker.
235
236
237## Copyright and license
238
239Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license.
240Docs released under Creative commons.
241
242