目錄
- 前言
- 命令用法
- –volume(-v)
- –mount
- 差異總結
- 官方文檔
前言
用戶可以通過docker run的–volume/-v或–mount選項來創建帶有數據卷的容器,但這兩個選項有些微妙的差異,在這里總結梳理一下。
命令用法
–volume(-v)
參數–volume(或簡寫為-v)只能創建bind mount。示例:
docker run --name $CONTAINER_NAME -it \ -v $PWD/$CONTAINER_NAME/app:/app:rw \ -v $PWD/$CONTAINER_NAME/data:/data:ro \ avocado-cloud:latest /bin/bash
注釋:
- 命令格式:[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]
- 如果指定HOST-DIR則必須是絕對路徑,如果路徑不存在則會自動創建
- 實例中的rw為讀寫,ro為只讀
–mount
參數–mount默認情況下用來掛載volume,但也可以用來創建bind mount和tmpfs。如果不指定type選項,則默認為掛載volume,volume是一種更為靈活的數據管理方式,volume可以通過docker volume命令集被管理。示例:
docker run --name $CONTAINER_NAME -it \ --mount type=bind,source=$PWD/$CONTAINER_NAME/app,destination=/app \ --mount source=${CONTAINER_NAME}-data,destination=/data,readonly \ avocado-cloud:latest /bin/bash
注釋:
- 掛載volume命令格式:[type=volume,]source=my-volume,destination=/path/in/container[,…]
- 創建bind mount命令格式:type=bind,source=/path/on/host,destination=/path/in/container[,…]
- 如果創建bind mount并指定source則必須是絕對路徑,且路徑必須已經存在
- 示例中readonly表示只讀
差異總結
創建bind mount和掛載volume的比較
對比項 | bind mount | volume |
---|---|---|
Source位置 | 用戶指定 | /var/lib/docker/volumes/ |
Source為空 | 覆蓋dest為空 | 保留dest內容 |
Source非空 | 覆蓋dest內容 | 覆蓋dest內容 |
Source種類 | 文件或目錄 | 只能是目錄 |
可移植性 | 一般(自行維護) | 強(docker托管) |
宿主直接訪問 | 容易(僅需chown) | 受限(需登陸root用戶)* |
*注釋:Docker無法簡單地通過sudo chown someuser: -R /var/lib/docker/volumes/somevolume來將volume的內容開放給主機上的普通用戶訪問,如果開放更多權限則有安全風險。而這點上Podman的設計就要理想得多,volume存放在$HOME/.local/share/containers/storage/volumes/路徑下,即提供了便捷性,又保障了安全性。無需root權限即可運行容器,這正是Podman的優勢之一,實際使用過程中的確受益良多。
創建bind mount時使用–volume和–mount的比較
對比項 | --volume 或 -v |
--mount type=bind |
---|---|---|
如果主機路徑不存在 | 自動創建 | 命令報錯 |
官方文檔
DOCKER(1) ? ? ? ? ? ? ? ? ? ? ? ? ?JUNE 2014 ? ? ? ? ? ? ? ? ? ? ? ? DOCKER(1) NAME ? ? ? ?docker-run - Run a command in a new container SYNOPSIS ? ? ? ?docker run ? ? ? ?[--mount[=[MOUNT]]] ? ? ? ?[-v|--volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]] ? ? ? ?IMAGE OPTIONS ? ? ? ?--mount type=TYPE,TYPE-SPECIFIC-OPTION[,...] ? ? ? ? ? Attach a filesystem mount to the container ? ? ? ?Current supported mount TYPES are bind, volume, and tmpfs. ? ? ? ?e.g. ? ? ? ?type=bind,source=/path/on/host,destination=/path/in/container ? ? ? ?type=volume,source=my-volume,destination=/path/in/container,volume-label="color=red",volume-label="shape=round" ? ? ? ?type=tmpfs,tmpfs-size=512M,destination=/path/in/container ? ? ? ?Common Options: ? ? ? ? ? ? ? · src, source: mount source spec for bind and volume. Mandatory ? ? ? ? ? ? ? ? for bind. ? ? ? ? ? ? ? · dst, destination, target: mount destination spec. ? ? ? ? ? ? ? · ro, readonly: true or false (default). ? ? ? ?Note: setting readonly for a bind mount does not make its submounts ? ? ? ? ? read-only on the current Linux implementation. See also ? ? ? ?bind-nonrecursive. ? ? ? ?Options specific to bind: ? ? ? ? ? ? ? · bind-propagation: shared, slave, private, rshared, rslave, or ? ? ? ? ? ? ? ? rprivate(default). See also mount(2). ? ? ? ? ? ? ? · consistency: consistent(default), cached, or delegated. ? ? ? ? ? ? ? ? Currently, only effective for Docker for Mac. ? ? ? ? ? ? ? · bind-nonrecursive: true or false (default). If set to true, ? ? ? ? ? ? ? ? submounts are not recursively bind-mounted. This option is ? ? ? ? ? ? ? ? useful for readonly bind mount. ? ? ? ?Options specific to volume: ? ? ? ? ? ? ? · volume-driver: Name of the volume-driver plugin. ? ? ? ? ? ? ? · volume-label: Custom metadata. ? ? ? ? ? ? ? · volume-nocopy: true(default) or false. If set to false, the ? ? ? ? ? ? ? ? Engine copies existing files and directories under the ? ? ? ? ? ? ? ? mount-path into the volume, allowing the host to access them. ? ? ? ? ? ? ? · volume-opt: specific to a given volume driver. ? ? ? ? ? ? ?? ? ? ? ?Options specific to tmpfs: ? ? ? ? ? ? ? · tmpfs-size: Size of the tmpfs mount in bytes. Unlimited by ? ? ? ? ? ? ? ? default in Linux. ? ? ? ? ? ? ? · tmpfs-mode: File mode of the tmpfs in octal. (e.g. 700 or ? ? ? ? ? ? ? ? 0700.) Defaults to 1777 in Linux. ? ? ? ?-v|--volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]] ? ? ? ? ? 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] ? ? ? ? ? ? ? · [delegated|cached|consistent] ? ? ? ? ? ? ? · [nocopy] ? ? ? ?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 supply additional options for each bind mount following an ? ? ? ?additional colon. ?A :ro or :rw suffix mounts a volume in read-only or ? ? ? ?read-write mode, respectively. By default, volumes are mounted in ? ? ? ?read-write mode. ?You can also specify the consistency requirement for ? ? ? ?the mount, either :consistent (the default), :cached, or :delegated. ? ? ? ?Multiple options are separated by commas, e.g. :ro,cached. ? ? ? ?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 ? ? ? ?propagation 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. ? ? ? ? ? ? ? Note: When using systemd to manage the Docker daemon's start and ? ? ? ? ? ? ? stop, in the systemd unit file there is an option to control ? ? ? ? ? ? ? mount propagation for the Docker daemon itself, called ? ? ? ? ? ? ? MountFlags. The value of this setting may cause Docker to not ? ? ? ? ? ? ? see mount propagation changes made on the mount point. For ? ? ? ? ? ? ? example, if this value is slave, you may not be able to use the ? ? ? ? ? ? ? shared or rshared propagation on a volume. ? ? ? ?To disable automatic copying of data from the container path to the ? ? ? ?volume, use the nocopy flag. The nocopy flag can be set on bind mounts ? ? ? ?and named volumes. ? ? ? ?See also --mount, which is the successor of --tmpfs and --volume. ?Even ? ? ? ?though there is no plan to deprecate --volume, usage of --mount is ? ? ? ?recommended. Docker Community ? ? ? ? ? ? ?Docker User Manuals ? ? ? ? ? ? ? ? ? ?DOCKER(1)