Improve nsinit usage instructions

nsinit must be run as root.

Tidy up the README somewhat to clarify the distinction between
libcontainer and the nsinit CLI.

Fix some typos in other files.

Docker-DCO-1.1-Signed-off-by: Glyn Normington <gnormington@gopivotal.com> (github: glyn)
This commit is contained in:
Glyn Normington 2014-06-24 13:30:27 +01:00
parent ce034dff2e
commit 29adc8c29f
3 changed files with 30 additions and 24 deletions

View File

@ -6,37 +6,43 @@ Please bear with us while we work on making the libcontainer API stable and some
#### Background #### Background
libcontainer specifies configuration options for what a container is. It provides a native Go implementation libcontainer specifies configuration options for what a container is. It provides a native Go implementation for using Linux namespaces with no external dependencies. libcontainer provides many convenience functions for working with namespaces, networking, and management.
for using Linux namespaces with no external dependencies. libcontainer provides many convenience functions for working with namespaces, networking, and management.
#### Container #### Container
A container is a self contained directory that is able to run one or more processes without 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.
affecting the host system. The directory is usually a full system tree. Inside the directory
a `container.json` file is placed with the runtime configuration for how the processes
should be contained and run. Environment, networking, and different capabilities for the
process 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. libcontainer may be used to execute a process in a container. If a user tries to run a new process inside an existing container, the new process is added to the processes executing in the container.
Using this configuration and the current directory holding the rootfs for a process, one can use libcontainer to exec the container. During the life of the container, a `state.json` file
is written to the current directory with the pid and start time of the container's PID1. A client can use this pid to wait, kill, or perform other operation with the container. If a user tries to run a new process inside an existing container with a live namespace, the namespace will be joined by the new process.
You may also specify an alternate root place where the `container.json` file is read and where the `state.json` file will be saved. #### Root file system
A container runs with a directory known as its *root file system*, or *rootfs*, mounted as the file system root. The rootfs is usually a full system tree.
#### Configuration
A container is initially configured by supplying configuration data when the container is created.
#### nsinit #### nsinit
`nsinit` is a cli application used as the reference implementation of libcontainer. It is able to `nsinit` is a cli application which demonstrates the use of libcontainer. It is able to spawn new containers or join existing containers, based on the current directory.
spawn or join new containers giving the current directory. To use `nsinit` cd into a Linux
rootfs and copy a `container.json` file into the directory with your specified configuration.
To execute `/bin/bash` in the current directory as a container just run: 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 ```bash
nsinit exec /bin/bash nsinit exec /bin/bash
``` ```
If you wish to spawn another process inside the container while your current bash session is 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.
running just run the exact same command again to get another bash shell or change the command. If the original process dies, PID 1, all other processes spawned inside the container will also be killed and the namespace will be removed.
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 the `container.json` file is read and where the `state.json` file will be saved.
#### Future #### Future
See the [roadmap](ROADMAP.md). See the [roadmap](ROADMAP.md).

View File

@ -25,8 +25,8 @@ type mount struct {
data string data string
} }
// InitializeMountNamespace setups up the devices, mount points, and filesystems for use inside a // InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a
// new mount namepsace // new mount namespace.
func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) error { func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig) error {
var ( var (
err error err error

View File

@ -17,7 +17,7 @@ import (
// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. // TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
// Move this to libcontainer package. // Move this to libcontainer package.
// Exec performes setup outside of a namespace so that a container can be // Exec performs setup outside of a namespace so that a container can be
// executed. Exec is a high level function for working with container namespaces. // executed. Exec is a high level function for working with container namespaces.
func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) { func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
var ( var (
@ -107,10 +107,10 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
// args provided // args provided
// //
// console: the /dev/console to setup inside the container // console: the /dev/console to setup inside the container
// init: the progam executed inside the namespaces // init: the program executed inside the namespaces
// root: the path to the container json file and information // root: the path to the container json file and information
// pipe: sync pipe to syncronize the parent and child processes // pipe: sync pipe to synchronize the parent and child processes
// args: the arguemnts to pass to the container to run as the user's program // args: the arguments to pass to the container to run as the user's program
func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd { func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd {
// get our binary name from arg0 so we can always reexec ourself // get our binary name from arg0 so we can always reexec ourself
env := []string{ env := []string{
@ -141,7 +141,7 @@ func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataP
return command return command
} }
// SetupCgroups applies the cgroup restrictions to the process running in the contaienr based // SetupCgroups applies the cgroup restrictions to the process running in the container based
// on the container's configuration // on the container's configuration
func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgroup, error) { func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgroup, error) {
if container.Cgroups != nil { if container.Cgroups != nil {