目录
1. 先回顾几个开源镜像的启动命令
1.1. GitLab
1.2. MySql
2. Docker 数据存储策略概述
2.1. Volumes
2.2. Bind mounts
2.3. tmpfs mounts
2.4. Tips for using bind mounts or volumes
3. Volumes 使用详解
4. Bind mounts 使用详解
5. tmpfs mounts 使用详解
1. 先回顾几个开源镜像的启动命令
1.1. GitLab
export GITLAB_HOME=/srv/gitlab
sudo docker run --detach \
--hostname gitlab.example.com \
--publish 443:443 --publish 80:80 --publish 22:22 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
This will download and start a GitLab container and publish ports needed to access SSH, HTTP and HTTPS. All GitLab data will be stored as subdirectories of GITLAB_HOME. The container will automatically restart after a system reboot. (译:所有 GitLab 的数据都会被存储到宿主机 GITLAB_HOME 的子目录中)
1.2. MySql
$ docker run --name some-mysql \
-v /my/own/datadir:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-d mysql:tag
The -v /my/own/datadir:/var/lib/mysql part of the command mounts the /my/own/datadir directory from the underlying host system as /var/lib/mysql inside the container, where MySQL by default will write its data files.(译:把宿主机的 /my/own/datadir 目录映射为容器中的 /var/lib/mysql 目录)
可以注意到,
启动 GitLab 和 MySql 镜像时,
都使用 -v(--volume)命令,
使【容器中】产生的数据持久化到【宿主机】中,
可避免因容器被删除导致的数据丢失问题
2. Docker 数据存储策略概述
By default all files created inside a container are stored on a writable container layer. This means that: (译:默认情况下,在容器内创建的文件,都储存在容器中的可写层中,这意味着:)
Docker has two options for containers to store files in the host machine, so that the files are persisted even after the container stops: volumes, and bind mounts. If you’re running Docker on Linux you can also use a tmpfs mount. If you’re running Docker on Windows you can also use a named pipe. (译:Docker 有两种方法可以让容器把文件存储到宿主机上,一种方法是 volumes、另一种方法是 bind mounts。如果你的 Docker 跑在 Linux 上,你还可以用 tmpfs mount;如果是在 Windows 上跑 Docker,还有一个 named pipe 也能用.)
No matter which type of mount you choose to use, the data looks the same from within the container. It is exposed as either a directory or an individual file in the container’s filesystem.(译:当然,不管你选择哪种方法(volumes 还是 bind mounts),从容器角度看数据都是一样的,不是一个独立文件就是一个目录)
An easy way to visualize the difference among volumes, bind mounts, and tmpfs mounts is to think about where the data lives on the Docker host.
2.1. Volumes
Created and managed by Docker. You can create a volume explicitly using the docker volume create command, or Docker can create a volume during container or service creation. (译:Volume 由 Docker 创建也由 Docker 管理。你可以使用命令 docker volume create 手动创建;Docker 也可以在容器、服务创建时创建 Volume )
When you create a volume, it is stored within a directory on the Docker host. When you mount the volume into a container, this directory is what is mounted into the container. This is similar to the way that bind mounts work, except that volumes are managed by Docker and are isolated from the core functionality of the host machine.
A given volume can be mounted into multiple containers simultaneously. When no running container is using a volume, the volume is still available to Docker and is not removed automatically. You can remove unused volumes using docker volume prune.(译:一个特定的 volume 可以同时被挂载进多个容器。即使所有的容器都停了,volume 也不会被自动删除,对 Docker 来说仍然可用 )
When you mount a volume, it may be named or anonymous. Anonymous volumes are not given an explicit name when they are first mounted into a container, so Docker gives them a random name that is guaranteed to be unique within a given Docker host. Besides the name, named and anonymous volumes behave in the same ways. (译:一个 volume,可以是具名的也可以是匿名的。匿名 volume 会在首次挂载进容器时,被随机分配一个 Docker 宿主范围内唯一的名字。 )
Volumes also support the use of volume drivers, which allow you to store your data on remote hosts or cloud providers, among other possibilities.
2.2. Bind mounts
Available since the early days of Docker. Bind mounts have limited functionality compared to volumes. When you use a bind mount, a file or directory on the host machine is mounted into a container. The file or directory is referenced by its full path on the host machine. The file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist. Bind mounts are very performant, but they rely on the host machine’s filesystem having a specific directory structure available. If you are developing new Docker applications, consider using named volumes instead. You can’t use Docker CLI commands to directly manage bind mounts.(译:Bind mounts 在 Docker 早期版本中就已经存在了,但是它跟 volumes 比,能力上少一些。Docker 建议使用 volumes. 当使用一个 bind mount 时,你是把宿主机上的一个文件或目录挂载进容器中。 )
Bind mounts are appropriate for the following types of use case: (译:Bind mounts 适用于以下几种场景:)
2.3. tmpfs mounts
A tmpfs mount is not persisted on disk, either on the Docker host or within a container. tmpfs mounts are best used for cases when you do not want the data to persist either on the host machine or within the container. This may be for security reasons or to protect the performance of the container when your application needs to write a large volume of non-persistent state data.
(译:tmpfs mouts 不会存储到宿主机的磁盘上,也不会存储到容器中的磁盘上。它最适合用在那些你既不想把数据存到容器内磁盘或宿主机磁盘的场景,比如:基于安全性考虑或基于性能考虑。)
2.4. Tips for using bind mounts or volumes
If you mount an empty volume into a directory in the container in which files or directories exist, these files or directories are propagated (copied) into the volume. Similarly, if you start a container and specify a volume which does not already exist, an empty volume is created for you. This is a good way to pre-populate data that another container needs. (译:如果你把空的 volume 挂载到容器中的一个非空目录中,那么容器中非空目录内原来的文件会被复制到这个空的 volume 中。)
If you mount a bind mount or non-empty volume into a directory in the container in which some files or directories exist, these files or directories are obscured by the mount, just as if you saved files into /mnt on a Linux host and then mounted a USB drive into /mnt. The contents of /mnt would be obscured by the contents of the USB drive until the USB drive were unmounted. The obscured files are not removed or altered, but are not accessible while the bind mount or volume is mounted. (译:如果你把一个 bind mount 或 非空的 volume 挂载到容器中的一个非空目录中,那么容器中非空目录内原来的文件将暂时不可见。)
3. Volumes 使用详解
docker volume create webj2eedev-vol
docker volume ls
docker volume inspect webj2eedev-vol
docker volume rm webj2eedev-vol
docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest
docker run -d \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html:ro \
nginx:latest
docker run -v /dbdata --name dbstore ubuntu /bin/bash
docker run --rm \
--volumes-from dbstore \
-v $(pwd):/backup \
ubuntu tar cvf /backup/backup.tar /dbdata
docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
docker volume prune
4. Bind mounts 使用详解
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:ro \
nginx:latest
5. tmpfs mounts 使用详解
docker run -d \
-it \
--name tmptest \
--tmpfs /app \
nginx:latest
参考:
Manage data in Docker: https://docs.docker.com/storage/