Docker basics-use bind mounts to manage application data

Bind mounts have appeared in the early days of Docker. Compared with volumes, bind mount has limited capabilities. When you use bind mount, files or directories on the host will be mounted into the container. The file or directory is referenced by its full or relative path on the host. Conversely, when you use a volume, create a new directory in the storage directory of Docker on the host, and Docker manages the contents of the directory.

The file or directory does not need to already exist on the Docker host. If it does not exist yet, create it on demand. The performance of bind mounts is very good, but they depend on the host's file system, which has a specific usable directory structure. If you are developing a new Docker application, consider using named volumes instead . You cannot use Docker CLI commands to directly manage bind mounts.

docker-types-of-mounts-bind

Select -vor --mountmark

Initially, -vor --volumemarked for separate containers, --mountlabeled for cluster services. However, beginning from Docker 17.06, you can also --mountbe used independently of the container. Usually, the --mountmark expression is more clear and verbose. The biggest difference is the -vsyntax for all combinations of options in a field, and --mountsyntax options separated. The following is a syntax comparison of each tag.

Tip: New users recommend the use of --mountgrammar, experienced users may be more familiar -vor --volumegrammar, but also encourage the use of --mountgrammar, because studies have shown that it is easier to use.

  • -vOr --volume: It consists of three fields, separated by colons (:). The fields must be arranged in the correct order, and the meaning of each field is not intuitive enough.
    • For bind mounts, the first field is the path of the file or directory on the host.
    • The second field is the path where the file or directory in the container is mounted.
    • The third field is optional, is a comma-separated list of options, such as ro, consistent, delegated, cached, zand Z. These options will be discussed below in this article.
  • --mount: A plurality of keys - value pairs, separated by commas, each key - the value of one of the <key>=<value>tuples. --mountSyntax than -vor --volumemore verbose, but the order of the keys is not important, the tag value is also easier to understand.
    • The type of mounting ( type), which can be either bind, volumeor tmpfs. This topic discusses bind mounts, so the type ( type) is always bind mount ( bind).
    • The source of the mount ( source). For bind mounts, this is the path of the file or directory on the Docker daemon host. You may be used sourceor srcspecified.
    • Target ( destination), the path where the file or directory in the container is mounted as its value. It can be used destination, dstor targetspecify.
    • readonlyOption (if present), bind mount will be mounted to the container as read-only .
    • bind-propagationOption (if present), change the binding propagation . Possible values are rprivate, private, rshared, shared, rslaveor slaveone.
    • consistencyOptions (if present), possible values consistent, delegatedor cachedone. This setting only applies to Docker Desktop for Mac and is ignored on other platforms.
    • --mountTag does not support selinux labels used to modify zor Zoptions.

The following example shows as simultaneously as possible --mountand the -vtwo syntaxes, and the first show --mount.

-vAnd --mountthe difference between the behavior

Because -vand -volumemarking Docker has long been a part of, their behavior can not be changed. This means -vand -mountbetween there is a different behavior.

If you use -vor -volumeto bind mounts on Docker host file or directory does not exist, it -vwill create it. It is always created as a directory.

If you are using --mountbind mounts on Docker host file or directory does not exist, Docker does not automatically create it for you, but generates an error.

Start the container with bind mount

Consider a situation: You have a directory source, when you build the source, the workpiece is saved to another directory source/target/in. You want to work in the container /app/directory is available, and each time you want to build the source code on the development host, the container can access the new building. Use the following command to target/catalog bind-mounted to the container /app/. In the sourcerun command directory. On Linux or macOS hosts, the $(pwd)subcommand expands to the current working directory.

Below --mountand -vexamples will produce the same results. Unless removed after running the first sample devtestcontainer, or can not run them at the same time.

--mount

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  nginx:latest

-v

$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app \
  nginx:latest

Use docker inspect devtestverify whether bind mounts are created correctly. View Mountspart:

"Mounts": [
    {
    
    
        "Type": "bind",
        "Source": "/tmp/source/target",
        "Destination": "/app",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],

This indicates that the mount is a bindmount, which shows the correct source and destination, is also shown mounted readable and writable, and is set to spread rprivate.

Stop the container:

$ docker container stop devtest

$ docker container rm devtest

Non-empty directory mounted on the container

If you bind-mount it to a non-empty directory on the container, the existing contents of the directory will be overwritten by the bind-mount. This may be beneficial, for example when you want to test a new version of the application without building a new image. However, it may also be surprising that this behavior is different from docker volumes .

This example is designed to be extreme, the host using only the /tmp/refill container directory /usr/content directory. In most cases, this will cause the container to not work properly.

--mountAnd -vexamples of the same results.

--mount

$ docker run -d \
  -it \
  --name broken-container \
  --mount type=bind,source=/tmp,target=/usr \
  nginx:latest

docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".

-v

$ docker run -d \
  -it \
  --name broken-container \
  -v /tmp:/usr \
  nginx:latest

docker: Error response from daemon: oci runtime error: container_linux.go:262:
starting container process caused "exec: \"nginx\": executable file not found in $PATH".

The container was created but not started. Delete it:

$ docker container rm broken-container

Use read-only bind mount

For some development applications, the container needs to write to bind mounts, so the changes will be propagated back to the Docker host. At other times, the container only needs read access.

This example modifies the above example, but mounts rothe directory as a read-only bind mount by adding it to the option list (empty by default) after the mount point in the container . When there are multiple options, separate them with commas.

--mountAnd -vexamples of the same results.

--mount

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app,readonly \
  nginx:latest

-v

$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:ro \
  nginx:latest

Use docker inspect devtestverify whether bind mounts are created correctly. View Mountspart:

"Mounts": [
    {
    
    
        "Type": "bind",
        "Source": "/tmp/source/target",
        "Destination": "/app",
        "Mode": "ro",
        "RW": false,
        "Propagation": "rprivate"
    }
],

Stop the container:

$ docker container stop devtest

$ docker container rm devtest

Configure binding propagation

For bind mounts and volumes, bind propagation defaults to both rprivate. It can only be configured for bind mount, and it can only be configured on a Linux host. Binding propagation is an advanced topic, and many users never need to configure it.

Binding propagation refers to whether a mount created in a given bind mount or named volume can be propagated to a copy of that mount. Consider a mount point /mnt, mount it /tmpon. Propagation control is provided /tmp/amounted on whether to permit the /mnt/ause on. Each propagation setting has a recursive counterpart. In the case of recursion, consider /tmp/aalso be mounted as /foo. Propagation control setting /mnt/aand / or /tmp/athe presence or absence.

Dissemination settings description
shared The submounts of the original mount are exposed to the replica mount, and the submounts of the replica mount are also propagated to the original mount.
slave Similar to shared mounting, but only in one direction. If the original mount exposes the submount, the replica mount can see it. However, if the copy mounts a public submount, the original mount cannot see it.
private The mount is private. The submounts of the original mount are not exposed to the replica mount, and the submounts of the replica mount are not exposed to the original mount.
rshared Same as shared, but propagation also extends to mount points nested in any original or duplicate mount points.
rslave Same as slave, but propagation also extends to mount points nested in any original or replica mount points.
rprivate Defaults. Same as private, this means that mount points anywhere in the original or duplicate mount points will not propagate in any direction.

Before you set up binding propagation on the mount point, the host file system needs to support binding propagation.

For more information about binding propagation, see the Linux kernel shared subtree documentation .

The following example twice target/directory is mounted to the vessel, the second set loading rooptions and rslavebinding options propagation.

--mountAnd -vexamples of the same results.

--mount

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app \
  --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \
  nginx:latest

-v

$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app \
  -v "$(pwd)"/target:/app2:ro,rslave \
  nginx:latest

Now, if you create it /app/foo/, /app2/foo/it also exists.

Configure selinux tags

If you are using selinux, you can add zor Zoptions to modify the selinux mount to label containers of host file or directory. This will affect files or directories on the host, and will have consequences beyond the scope of Docker.

  • z The option indicates that the bind mount content is shared among multiple containers.
  • Z The option indicates that the bind mount content is private and non-shared.

Be extra careful when using these options . Use ZOptions bind-mounted system directory (such as /homeor /usr) cause your host not working, you may need to manually re-mark the hosts file.

IMPORTANT: When using bind mounts for service, selinux labels ( :Zand :Z) and :rowill be ignored. See moby/moby #32579 for details .

This example sets the zoption to specify multiple containers can share content bindings mounted:

You can not use the --mounttag to modify selinux label.

$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:z \
  nginx:latest

Configure mount consistency for macOS

Docker Desktop for Mac use osxfsfrom macOS shared directories and files spread to the Linux VM. This spread makes these directories and files available to Docker containers running on Docker Desktop for Mac.

By default, these shares are completely consistent, which means that every time a write operation occurs on the macOS host or through a mount in the container, the changes are flushed to the disk so that all participants in the share have complete consistency View. In some cases, complete consistency can severely affect performance. Docker 17.05 and later versions introduce some options to adjust consistency settings on a per-mount and per-container basis. The following options are available:

  • consistentOr default: The default setting for full consistency, as described above.
  • delegated: The mount view of the container runtime is authoritative. Updates made in the container may be delayed before they are visible on the host.
  • cached: The mount view of the macOS host is authoritative. Updates made on the host may be delayed before they are visible in the container.

These options are completely ignored on all host operating systems except macOS.

--mountAnd -vexamples of the same results.

--mount

$ docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,destination=/app,consistency=cached \
  nginx:latest

-v

$ docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:cached \
  nginx:latest

Author: Docker's official website
translator: Technical Zemin
Publisher: Technical Verses
links: English text

Guess you like

Origin blog.csdn.net/weixin_47498376/article/details/107603369