Skip to content

Commit 5d2eb18

Browse files
author
Brandon Philips
committed
*: re-org the spec
We had an in-person spec discussion, lets separate the spec into some high-level sections to clarify future discussion. Crosby agreed to let me merge to master :)
1 parent 33bd340 commit 5d2eb18

File tree

5 files changed

+338
-514
lines changed

5 files changed

+338
-514
lines changed

README.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,47 @@
11
# Open Container Specifications
22

33
This project is where the Open Container Project Specifications are written. This is a work in progress. We should have a first draft by end of July 2015.
4-
* [Open Container Runtime](runtime.md)
4+
5+
Table of Contents
6+
7+
- [Filesystem Bundle](bundle.md)
8+
- [Container Configuration](config.md)
9+
- [Linux Specific Configuration](config-linux.md)
10+
- [Runtime and Lifecycle](runtime.md)
11+
12+
# The 5 principles of Standard Containers
13+
14+
Define a unit of software delivery called a Standard Container. The goal of a Standard Container is to encapsulate a software component and all its dependencies in a format that is self-describing and portable, so that any compliant runtime can run it without extra dependencies, regardless of the underlying machine and the contents of the container.
15+
16+
The specification for Standard Containers is straightforward. It mostly defines 1) a file format, 2) a set of standard operations, and 3) an execution environment.
17+
18+
A great analogy for this is the shipping container. Just like how Standard Containers are a fundamental unit of software delivery, shipping containers are a fundamental unit of physical delivery.
19+
20+
## 1. Standard operations
21+
22+
Just like shipping containers, Standard Containers define a set of STANDARD OPERATIONS. Shipping containers can be lifted, stacked, locked, loaded, unloaded and labelled. Similarly, Standard Containers can be started, stopped, copied, snapshotted, downloaded, uploaded and tagged.
23+
24+
## 2. Content-agnostic
25+
26+
Just like shipping containers, Standard Containers are CONTENT-AGNOSTIC: all standard operations have the same effect regardless of the contents. A shipping container will be stacked in exactly the same way whether it contains Vietnamese powder coffee or spare Maserati parts. Similarly, Standard Containers are started or uploaded in the same way whether they contain a postgres database, a php application with its dependencies and application server, or Java build artifacts.
27+
28+
## 3. Infrastructure-agnostic
29+
30+
Both types of containers are INFRASTRUCTURE-AGNOSTIC: they can be transported to thousands of facilities around the world, and manipulated by a wide variety of equipment. A shipping container can be packed in a factory in Ukraine, transported by truck to the nearest
31+
32+
routing center, stacked onto a train, loaded into a German boat by an Australian-built crane, stored in a warehouse at a US facility, etc. Similarly, a standard container can be bundled on my laptop, uploaded to S3, downloaded, run and snapshotted by a build server at Equinix in Virginia, uploaded to 10 staging servers in a home-made Openstack cluster, then sent to 30 production instances across 3 EC2 regions.
33+
34+
## 4. Designed for automation
35+
36+
Because they offer the same standard operations regardless of content and infrastructure, Standard Containers, just like their physical counterparts, are extremely well-suited for automation. In fact, you could say automation is their secret weapon.
37+
38+
Many things that once required time-consuming and error-prone human effort can now be programmed. Before shipping containers, a bag of powder coffee was hauled, dragged, dropped, rolled and stacked by 10 different people in 10 different locations by the time it reached its destination. 1 out of 50 disappeared. 1 out of 20 was damaged. The process was slow, inefficient and cost a fortune - and was entirely different depending on the facility and the type of goods.
39+
40+
Similarly, before Standard Containers, by the time a software component ran in production, it had been individually built, configured, bundled, documented, patched, vendored, templated, tweaked and instrumented by 10 different people on 10 different computers. Builds failed, libraries conflicted, mirrors crashed, post-it notes were lost, logs were misplaced, cluster updates were half-broken. The process was slow, inefficient and cost a fortune - and was entirely different depending on the language and infrastructure provider.
41+
42+
## 5. Industrial-grade delivery
43+
44+
There are 17 million shipping containers in existence, packed with every physical good imaginable. Every single one of them can be loaded onto the same boats, by the same cranes, in the same facilities, and sent anywhere in the World with incredible efficiency. It is embarrassing to think that a 30 ton shipment of coffee can safely travel half-way across the World in *less time* than it takes a software team to deliver its code from one datacenter to another sitting 10 miles away.
45+
46+
With Standard Containers we can put an end to that embarrassment, by making INDUSTRIAL-GRADE DELIVERY of software a reality.
47+

bundle.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Bundle Container Format
2+
3+
This section defines a format for encoding a container as a *bundle* - a directory organized in a certain way, and containing all the necessary data and metadata for any compliant runtime to perform all standard operations against it. See also *[Mac OS application bundle*s](http://en.wikipedia.org/wiki/Bundle_%28OS_X%29) for a similar use of the term *bundle*.
4+
5+
The format does not define distribution. In other words, it only specifies how a container must be stored on a local filesystem, for consumption by a runtime. It does not specify how to transfer a container between computers, how to discover containers, or assign names or versions to them. Any distribution method capable of preserving the original layout of a container, as specified here, is considered compliant.
6+
7+
A standard container bundle is made of the following 4 parts:
8+
9+
- A top-level directory holding everything else
10+
- One or more content directories
11+
- A configuration file
12+
13+
# Directory layout
14+
15+
A Standard Container bundle is a directory containing all the content needed to load and run a container. This includes its configuration file, content directories, and cryptographic signatures. The main property of this directory layout is that it can be moved as a unit to another machine and run the same container.
16+
17+
One or more *content directories* may be adjacent to the configuration file. This at least includes the root filesystem (referenced in the configuration by the *rootfs* field), and any number of and other related content (signatures, other configs, etc.). The interpretation of these resources is specified in the configuration.
18+
19+
```
20+
/
21+
!
22+
-- config.json
23+
!
24+
--- rootfs1
25+
!
26+
--- rootfs2
27+
```
28+
29+
The syntax and semantics for config.json are described in this specification.
30+
31+
One or more content directories can be specified as root file systems for containers. They COULD be called rootfs..10^100 but SHALL be called whatever you want.

config-linux.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Linux
2+
3+
## Linux Namespaces
4+
5+
```
6+
"namespaces": [
7+
"process",
8+
"network",
9+
"mount",
10+
"ipc",
11+
"uts"
12+
],
13+
```
14+
15+
Namespaces for the container are specified as an array of strings under the namespaces key. The list of constants that can be used is portable across operating systems. Here is a table mapping these names to native OS equivalent.
16+
17+
For Linux the mapping is
18+
19+
* process -> pid: the process ID number space is specific to the container, meaning that processes in different PID namespaces can have the same PID
20+
21+
* network -> network: the container will have an isolated network stack
22+
23+
* mount -> mnt container can only access mounts local to itself
24+
25+
* ipc -> ipc processes in the container can only communicate with other processes inside same container
26+
27+
* uts -> uts Hostname and NIS domain name are specific to the container
28+
29+
## Linux Control groups
30+
31+
## Linux Seccomp
32+
33+
## Linux Process Capabilities
34+
35+
```
36+
"capabilities": [
37+
"AUDIT_WRITE",
38+
"KILL",
39+
"NET_BIND_SERVICE"
40+
],
41+
```
42+
43+
capabilities is an array of Linux process capabilities. Valid values are the string after `CAP_` for capabilities defined in http://linux.die.net/man/7/capabilities
44+
45+
## SELinux
46+
47+
## Apparmor
48+
49+

config.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Configuration file
2+
3+
The container’s top-level directory MUST contain a configuration file called config.json. The configuration file MUST comply with the Open Container Configuration JSON Schema attached to this document. For now the schema is defined in [spec.go](https://github.com/opencontainers/runc/blob/master/spec.go) and [spec_linux.go](https://github.com/opencontainers/runc/blob/master/spec_linux.go), this will be moved to a JSON schema overtime.
4+
5+
The configuration file contains metadata necessary to implement standard operations against the container. This includes processes to run, environment variables to inject, sandboxing features to use, etc.
6+
7+
Below is a detailed description of each field defined in the configuration format.
8+
9+
## Manifest version
10+
11+
The `version` element specifies the version of the OCF specification which the container complies with. If the container is compliant with multiple versions, it SHOULD advertise the most recent known version to be supported.
12+
13+
*Linux example*
14+
15+
```
16+
"version": "1",
17+
```
18+
19+
## File system configuration
20+
21+
Each container has exactly one *root filesystem*, and any number of optional *mounted filesystems*. Both need to be declared in the manifest.
22+
23+
The rootfs string element specifies the path to the root file system for the container, relative to the path where the manifest is. A directory MUST exist at the relative path declared by the field.
24+
25+
The readonlyRootfs is an optional boolean element which defaults to false. If it is true, access to the root file system MUST be read-only for all processes running inside it. whether you want the root file system to be readonly or not for the processes running on it.
26+
27+
*Example (Linux)*
28+
29+
```
30+
"rootfs": "rootfs",
31+
"readonlyRootfs": true,
32+
```
33+
34+
*Example (Windows)*
35+
36+
```
37+
"rootfs": "My Fancy Root FS",
38+
"readonlyRootfs": true,
39+
```
40+
41+
Additional file systems can be declared as "mounts", declared by the the array element mounts. The parameters are similar to the ones in Linux mount system call. [http://linux.die.net/man/2/mount](http://linux.die.net/man/2/mount)
42+
43+
type: Linux, *filesystemtype* argument supported by the kernel are listed in */proc/filesystems* (e.g., "minix", "ext2", "ext3", "jfs", "xfs", "reiserfs", "msdos", "proc", "nfs", "iso9660"). Windows: ntfs
44+
45+
source: a device name, but can also be a directory name or a dummy. Windows, the volume name that is the target of the mount point. \\?\Volume\{GUID}\ (on Windows source is called target)
46+
47+
destination: where the file system is mounted in the container.
48+
49+
options: in the fstab format [https://wiki.archlinux.org/index.php/Fstab](https://wiki.archlinux.org/index.php/Fstab).
50+
51+
*Example (Linux)*
52+
53+
```
54+
"mounts": [
55+
{
56+
"type": "proc",
57+
"source": "proc",
58+
"destination": "/proc",
59+
"options": ""
60+
},
61+
{
62+
"type": "tmpfs",
63+
"source": "tmpfs",
64+
"destination": "/dev",
65+
"options": "nosuid,strictatime,mode=755,size=65536k"
66+
},
67+
{
68+
"type": "devpts",
69+
"source": "devpts",
70+
"destination": "/dev/pts",
71+
"options": "nosuid,noexec,newinstance,ptmxmode=0666,mode=0620,gid=5"
72+
},
73+
{
74+
"type": "tmpfs",
75+
"source": "shm",
76+
"destination": "/dev/shm",
77+
"options": "nosuid,noexec,nodev,mode=1777,size=65536k"
78+
},
79+
]
80+
```
81+
82+
*Example (Windows)*
83+
```
84+
"mounts": [
85+
{
86+
"type": "ntfs",
87+
"source": "\\?\Volume\{2eca078d-5cbc-43d3-aff8-7e8511f60d0e}\
88+
89+
",
90+
"destination": "C:\Users\crosbymichael\My Fancy Mount Point\",
91+
"options": ""
92+
}
93+
```
94+
95+
See links for details about mountvol in Windows.
96+
97+
[https://msdn.microsoft.com/en-us/library/windows/desktop/aa365561(v=vs.85).aspx](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365561(v=vs.85).aspx)
98+
99+
[http://ss64.com/nt/mountvol.html](http://ss64.com/nt/mountvol.html)
100+
101+
### Processes configuration
102+
103+
- Command-line arguments
104+
- Terminal allocation
105+
- User ID
106+
- Environment variables
107+
- Working directory
108+
109+
*Example (Linux)*
110+
```
111+
"processes": [
112+
{
113+
"tty": true,
114+
"user": "daemon",
115+
"args": [
116+
"sh"
117+
],
118+
"env": [
119+
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
120+
"TERM=xterm"
121+
],
122+
"cwd": ""
123+
}
124+
],
125+
```
126+
127+
The processes to be created inside the container are specified in a processes array. They are started in order.
128+
129+
```
130+
"processes": [...]
131+
```
132+
133+
The command to start a process is specified in an array of args. It will be run in the working directory specified in the string cwd.
134+
135+
Environment variables are specified is an array called env.
136+
137+
Elements in the array are specified as Strings in the form "KEY=value"
138+
139+
The user inside the container under which the process is running is specified under the user key.
140+
141+
tty is a boolean that lets you specify whether you want a terminal attached to that process. tty cannot be set to true for more than one process in the array, else oc returns the error code THERE_CAN_BE_ONLY_ONE_TTY.
142+
143+
*Example (Windows)*
144+
145+
```
146+
"processes": [
147+
{
148+
"tty": true,
149+
"user": "Contoso\ScottGu",
150+
"args": [
151+
"cmd.exe"
152+
],
153+
"env": [
154+
"PATH=D:\Windows\Microsoft.NET\Framework\v4.0.30319;D:\Program Files (x86)\Git\bin",
155+
"TERM=cygwin"
156+
],
157+
"cwd": ""
158+
}
159+
],
160+
```
161+
162+
hostname is a string specifying the hostname for that container as it is accessible to processes running in it.
163+
164+
### Resource Constraints
165+
166+
*Example*
167+
168+
```
169+
"hostname": "mrsdalloway",
170+
```
171+
172+
The number of CPUs is specified as a positive decimal under the key cpus.
173+
174+
The amount of memory allocated to this container is specified under the memory key, as an integer and is expressed in MBb.
175+
176+
If the cpu or memory requested are too high for the underlying environment capabilities, an error code NOT_ENOUGH_CPU or NOT_ENOUGH_MEM will be returned.
177+
178+
179+
### Access to devices
180+
181+
```
182+
"devices": [
183+
"null",
184+
"random",
185+
"full",
186+
"tty",
187+
"zero",
188+
"urandom"
189+
],
190+
```
191+
192+
Devices is an array specifying the list of devices from the host to make available in the container.
193+
194+
The array contains names: for each name, the device /dev/<name> will be made available inside the container.
195+
196+
## Machine-specific configuration
197+
198+
```
199+
"os": "linux",
200+
"arch": "amd64",
201+
```
202+
203+
os specifies the operating system family this image must run on.
204+
205+
arch specifies the instruction set for which the binaries in the image have been compiled.
206+
207+
values for os and arch must be in the list specified by by the Go Language documentation for $GOOS and $GOARCH https://golang.org/doc/install/source#environment
208+
209+
OS or architecture specific settings can be added in the json file. They will be interpreted by the implementation depending on the os and arch values specified at the top of the manifest.

0 commit comments

Comments
 (0)