Add capability to specify mount propagation per volume

Allow passing mount propagation option shared, slave, or private as volume
property.

For example.
docker run -ti -v /root/mnt-source:/root/mnt-dest:slave fedora bash

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
This commit is contained in:
Vivek Goyal 2015-10-23 16:57:57 -04:00 committed by Tibor Vass
parent 9339b4abb5
commit b2cbaa03af
6 changed files with 147 additions and 45 deletions

View File

@ -79,12 +79,12 @@ Creates a new container.
-u, --user="" Username or UID -u, --user="" Username or UID
--ulimit=[] Ulimit options --ulimit=[] Ulimit options
--uts="" UTS namespace to use --uts="" UTS namespace to use
-v, --volume=[] Bind mount a volume with: [host-src:]container-dest[:<options>], where -v, --volume=[host-src:]container-dest[:<options>]
options are comma delimited and selected from [rw|ro] and [z|Z]. Bind mount a volume. The comma-delimited
The 'host-src' can either be an absolute path or a name value. `options` are [rw|ro], [z|Z], or
If 'host-src' is missing, then docker creates a new volume. [[r]shared|[r]slave|[r]private]. The
If neither 'rw' or 'ro' is specified then the volume is mounted 'host-src' is an absolute path or a name
in read-write mode. value.
--volume-driver="" Container's volume driver --volume-driver="" Container's volume driver
--volumes-from=[] Mount volumes from the specified container(s) --volumes-from=[] Mount volumes from the specified container(s)
-w, --workdir="" Working directory inside the container -w, --workdir="" Working directory inside the container

View File

@ -80,12 +80,12 @@ parent = "smn_cli"
-u, --user="" Username or UID (format: <name|uid>[:<group|gid>]) -u, --user="" Username or UID (format: <name|uid>[:<group|gid>])
--ulimit=[] Ulimit options --ulimit=[] Ulimit options
--uts="" UTS namespace to use --uts="" UTS namespace to use
-v, --volume=[] Bind mount a volume with: [host-src:]container-dest[:<options>], where -v, --volume=[host-src:]container-dest[:<options>]
options are comma delimited and selected from [rw|ro] and [z|Z]. Bind mount a volume. The comma-delimited
The 'host-src' can either be an absolute path or a name value. `options` are [rw|ro], [z|Z], or
If 'host-src' is missing, then docker creates a new volume. [[r]shared|[r]slave|[r]private]. The
If neither 'rw' or 'ro' is specified then the volume is mounted 'host-src' is an absolute path or a name
in read-write mode. value.
--volume-driver="" Container's volume driver --volume-driver="" Container's volume driver
--volumes-from=[] Mount volumes from the specified container(s) --volumes-from=[] Mount volumes from the specified container(s)
-w, --workdir="" Working directory inside the container -w, --workdir="" Working directory inside the container

View File

@ -1330,11 +1330,14 @@ Similarly the operator can set the **hostname** with `-h`.
### VOLUME (shared filesystems) ### VOLUME (shared filesystems)
-v=[]: Create a bind mount with: [host-src:]container-dest[:<options>], where -v, --volume=[host-src:]container-dest[:<options>]: Bind mount a volume.
options are comma delimited and selected from [rw|ro] and [z|Z]. The comma-delimited `options` are [rw|ro], [z|Z], or
If 'host-src' is missing, then docker creates a new volume. [[r]shared|[r]slave|[r]private]. The 'host-src' is an absolute path or a
If neither 'rw' or 'ro' is specified then the volume is mounted name value.
in read-write mode.
If neither 'rw' or 'ro' is specified then the volume is mounted in
read-write mode.
--volumes-from="": Mount all volumes from the given container(s) --volumes-from="": Mount all volumes from the given container(s)
> **Note**: > **Note**:

View File

@ -64,7 +64,7 @@ docker-create - Create a new container
[**-u**|**--user**[=*USER*]] [**-u**|**--user**[=*USER*]]
[**--ulimit**[=*[]*]] [**--ulimit**[=*[]*]]
[**--uts**[=*[]*]] [**--uts**[=*[]*]]
[**-v**|**--volume**[=*[]*]] [**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]]
[**--volume-driver**[=*DRIVER*]] [**--volume-driver**[=*DRIVER*]]
[**--volumes-from**[=*[]*]] [**--volumes-from**[=*[]*]]
[**-w**|**--workdir**[=*WORKDIR*]] [**-w**|**--workdir**[=*WORKDIR*]]
@ -311,8 +311,78 @@ any options, the systems uses the following options:
**host**: use the host's UTS namespace inside the container. **host**: use the host's UTS namespace inside the container.
Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure. Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure.
**-v**, **--volume**=[] **-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
Bind mount a volume (e.g., from the host: -v /host:/container, from Docker: -v /container) Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Docker
bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the Docker
container. If 'HOST-DIR' is omitted, Docker automatically creates the new
volume on the host. The `OPTIONS` are a comma delimited list and can be:
* [rw|ro]
* [z|Z]
* [`[r]shared`|`[r]slave`|`[r]private`]
The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The `HOST-DIR`
can be an absolute path or a `name` value. A `name` value must start with an
alphanumeric character, followed by `a-z0-9`, `_` (underscore), `.` (period) or
`-` (hyphen). An absolute path starts with a `/` (forward slash).
If you supply a `HOST-DIR` that is an absolute path, Docker bind-mounts to the
path you specify. If you supply a `name`, Docker creates a named volume by that
`name`. For example, you can specify either `/foo` or `foo` for a `HOST-DIR`
value. If you supply the `/foo` value, Docker creates a bind-mount. If you
supply the `foo` specification, Docker creates a named volume.
You can specify multiple **-v** options to mount one or more mounts to a
container. To use these same mounts in other containers, specify the
**--volumes-from** option also.
You can add `:ro` or `:rw` suffix to a volume to mount it read-only or
read-write mode, respectively. By default, the volumes are mounted read-write.
See examples.
Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a container. Without a label, the security system might
prevent the processes running inside the container from using the content. By
default, Docker does not change the labels set by the OS.
To change a label in the container context, you can add either of two suffixes
`:z` or `:Z` to the volume mount. These suffixes tell Docker to relabel file
objects on the shared volumes. The `z` option tells Docker that two containers
share the volume content. As a result, Docker labels the content with a shared
content label. Shared volume labels allow all containers to read/write content.
The `Z` option tells Docker to label the content with a private unshared label.
Only the current container can use a private volume.
By default bind mounted volumes are `private`. That means any mounts done
inside container will not be visible on host and vice-a-versa. One can change
this behavior by specifying a volume mount propagation property. Making a
volume `shared` mounts done under that volume inside container will be
visible on host and vice-a-versa. Making a volume `slave` enables only one
way mount propagation and that is mounts done on host under that volume
will be visible inside container but not the other way around.
To control mount propagation property of volume one can use `:[r]shared`,
`:[r]slave` or `:[r]private` propagation flag. Propagation property can
be specified only for bind mounted volumes and not for internal volumes or
named volumes. For mount propagation to work source mount point (mount point
where source dir is mounted on) has to have right propagation properties. For
shared volumes, source mount point has to be shared. And for slave volumes,
source mount has to be either shared or slave.
Use `df <source-dir>` to figure out the source mount and then use
`findmnt -o TARGET,PROPAGATION <source-mount-dir>` to figure out propagation
properties of source mount. If `findmnt` utility is not available, then one
can look at mount entry for source mount point in `/proc/self/mountinfo`. Look
at `optional fields` and see if any propagaion properties are specified.
`shared:X` means mount is `shared`, `master:X` means mount is `slave` and if
nothing is there that means mount is `private`.
To change propagation properties of a mount point use `mount` command. For
example, if one wants to bind mount source directory `/foo` one can do
`mount --bind /foo /foo` and `mount --make-private --make-shared /foo`. This
will convert /foo into a `shared` mount point. Alternatively one can directly
change propagation properties of source mount. Say `/` is source mount for
`/foo`, then use `mount --make-shared /` to convert `/` into a `shared` mount.
**--volume-driver**="" **--volume-driver**=""
Container's volume driver. This driver creates volumes specified either from Container's volume driver. This driver creates volumes specified either from

View File

@ -104,6 +104,7 @@ To get information on a container use its ID or instance name:
"Destination": "/data", "Destination": "/data",
"Mode": "ro,Z", "Mode": "ro,Z",
"RW": false "RW": false
"Propagation": ""
} }
], ],
"AppArmorProfile": "", "AppArmorProfile": "",

View File

@ -67,7 +67,7 @@ docker-run - Run a command in a new container
[**-u**|**--user**[=*USER*]] [**-u**|**--user**[=*USER*]]
[**--ulimit**[=*[]*]] [**--ulimit**[=*[]*]]
[**--uts**[=*[]*]] [**--uts**[=*[]*]]
[**-v**|**--volume**[=*[]*]] [**-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]]
[**--volume-driver**[=*DRIVER*]] [**--volume-driver**[=*DRIVER*]]
[**--volumes-from**[=*[]*]] [**--volumes-from**[=*[]*]]
[**-w**|**--workdir**[=*WORKDIR*]] [**-w**|**--workdir**[=*WORKDIR*]]
@ -476,24 +476,34 @@ any options, the systems uses the following options:
**--ulimit**=[] **--ulimit**=[]
Ulimit options Ulimit options
**-v**, **--volume**=[] Create a bind mount **-v**|**--volume**[=*[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
(format: `[host-dir:]container-dir[:<suffix options>]`, where suffix options Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Docker
are comma delimited and selected from [rw|ro] and [z|Z].) bind mounts `/HOST-DIR` in the host to `/CONTAINER-DIR` in the Docker
container. If 'HOST-DIR' is omitted, Docker automatically creates the new
volume on the host. The `OPTIONS` are a comma delimited list and can be:
(e.g., using -v /host-dir:/container-dir, bind mounts /host-dir in the * [rw|ro]
host to /container-dir in the Docker container) * [z|Z]
* [`[r]shared`|`[r]slave`|`[r]private`]
If 'host-dir' is missing, then docker automatically creates the new volume The `CONTAINER-DIR` must be an absolute path such as `/src/docs`. The `HOST-DIR`
on the host. **This auto-creation of the host path has been deprecated in can be an absolute path or a `name` value. A `name` value must start with an
Release: v1.9.** alphanumeric character, followed by `a-z0-9`, `_` (underscore), `.` (period) or
`-` (hyphen). An absolute path starts with a `/` (forward slash).
The **-v** option can be used one or If you supply a `HOST-DIR` that is an absolute path, Docker bind-mounts to the
more times to add one or more mounts to a container. These mounts can then be path you specify. If you supply a `name`, Docker creates a named volume by that
used in other containers using the **--volumes-from** option. `name`. For example, you can specify either `/foo` or `foo` for a `HOST-DIR`
value. If you supply the `/foo` value, Docker creates a bind-mount. If you
supply the `foo` specification, Docker creates a named volume.
The volume may be optionally suffixed with :ro or :rw to mount the volumes in You can specify multiple **-v** options to mount one or more mounts to a
read-only or read-write mode, respectively. By default, the volumes are mounted container. To use these same mounts in other containers, specify the
read-write. See examples. **--volumes-from** option also.
You can add `:ro` or `:rw` suffix to a volume to mount it read-only or
read-write mode, respectively. By default, the volumes are mounted read-write.
See examples.
Labeling systems like SELinux require that proper labels are placed on volume Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a container. Without a label, the security system might content mounted into a container. Without a label, the security system might
@ -508,18 +518,36 @@ content label. Shared volume labels allow all containers to read/write content.
The `Z` option tells Docker to label the content with a private unshared label. The `Z` option tells Docker to label the content with a private unshared label.
Only the current container can use a private volume. Only the current container can use a private volume.
The `container-dir` must always be an absolute path such as `/src/docs`. By default bind mounted volumes are `private`. That means any mounts done
The `host-dir` can either be an absolute path or a `name` value. If you inside container will not be visible on host and vice-a-versa. One can change
supply an absolute path for the `host-dir`, Docker bind-mounts to the path this behavior by specifying a volume mount propagation property. Making a
you specify. If you supply a `name`, Docker creates a named volume by that `name`. volume `shared` mounts done under that volume inside container will be
visible on host and vice-a-versa. Making a volume `slave` enables only one
way mount propagation and that is mounts done on host under that volume
will be visible inside container but not the other way around.
A `name` value must start with start with an alphanumeric character, To control mount propagation property of volume one can use `:[r]shared`,
followed by `a-z0-9`, `_` (underscore), `.` (period) or `-` (hyphen). `:[r]slave` or `:[r]private` propagation flag. Propagation property can
An absolute path starts with a `/` (forward slash). be specified only for bind mounted volumes and not for internal volumes or
named volumes. For mount propagation to work source mount point (mount point
where source dir is mounted on) has to have right propagation properties. For
shared volumes, source mount point has to be shared. And for slave volumes,
source mount has to be either shared or slave.
For example, you can specify either `/foo` or `foo` for a `host-dir` value. Use `df <source-dir>` to figure out the source mount and then use
If you supply the `/foo` value, Docker creates a bind-mount. If you supply `findmnt -o TARGET,PROPAGATION <source-mount-dir>` to figure out propagation
the `foo` specification, Docker creates a named volume. properties of source mount. If `findmnt` utility is not available, then one
can look at mount entry for source mount point in `/proc/self/mountinfo`. Look
at `optional fields` and see if any propagaion properties are specified.
`shared:X` means mount is `shared`, `master:X` means mount is `slave` and if
nothing is there that means mount is `private`.
To change propagation properties of a mount point use `mount` command. For
example, if one wants to bind mount source directory `/foo` one can do
`mount --bind /foo /foo` and `mount --make-private --make-shared /foo`. This
will convert /foo into a `shared` mount point. Alternatively one can directly
change propagation properties of source mount. Say `/` is source mount for
`/foo`, then use `mount --make-shared /` to convert `/` into a `shared` mount.
**--volume-driver**="" **--volume-driver**=""
Container's volume driver. This driver creates volumes specified either from Container's volume driver. This driver creates volumes specified either from