前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Docker】:Docker 数据管理 - Volumes & Bind Mounts

【Docker】:Docker 数据管理 - Volumes & Bind Mounts

作者头像
WEBJ2EE
发布2022-01-04 13:49:20
1.4K0
发布2022-01-04 13:49:20
举报
文章被收录于专栏:WebJ2EEWebJ2EE
代码语言:javascript
复制
目录
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

代码语言:javascript
复制
export GITLAB_HOME=/srv/gitlab
代码语言:javascript
复制
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

代码语言:javascript
复制
$ 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: (译:默认情况下,在容器内创建的文件,都储存在容器中的可写层中,这意味着:)

  • The data doesn’t persist when that container no longer exists, and it can be difficult to get the data out of the container if another process needs it.(译:容器不存在了(指容器被删除),容器中的文件也就不存在了)
  • A container’s writable layer is tightly coupled to the host machine where the container is running. You can’t easily move the data somewhere else.(译:容器可写层,并不是你想动就能动的,它是跟运行中的容器紧耦合的)
  • Writing into a container’s writable layer requires a storage driver to manage the filesystem. The storage driver provides a union filesystem, using the Linux kernel. This extra abstraction reduces performance as compared to using data volumes, which write directly to the host filesystem.(译:向容器的可写层中写东西,需要用到一个存储驱动来管理文件系统,这个存储驱动使用 linux 内核提供了一个统一的文件系统,然而跟直接向宿主文件系统写文件比,这一层抽象降低了一些性能)

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.

  • Volumes are stored in a part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux). Non-Docker processes should not modify this part of the filesystem. Volumes are the best way to persist data in Docker. (译:Volumes 的数据存储在宿主机的特定区域中(Linux:/var/lib/docker/volumes/),由 Docker 管理,其他软件是不能乱改的。)
  • Bind mounts may be stored anywhere on the host system. They may even be important system files or directories. Non-Docker processes on the Docker host or a Docker container can modify them at any time.(译:Bind mouts 的数据可以存储在宿主机的任何位置上,Docker和其他软件都可以对它进行修改。)
  • tmpfs mounts are stored in the host system’s memory only, and are never written to the host system’s filesystem.(译:tmpfs mouts 的数据只会存储在宿主机的内存中,不会存储到宿主机的文件系统中。)

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 适用于以下几种场景:)

  • Sharing configuration files from the host machine to containers. This is how Docker provides DNS resolution to containers by default, by mounting /etc/resolv.conf from the host machine into each container. (译:一种场景是,把宿主机中的文件共享进容器里。Docker 的 DNS 解析特性就是靠 bind mount 实现的,它把宿主机的 /etc/resolv.conf 挂载到了容器中 )
  • Sharing source code or build artifacts between a development environment on the Docker host and a container. For instance, you may mount a Maven target/ directory into a container, and each time you build the Maven project on the Docker host, the container gets access to the rebuilt artifacts.

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 使用详解

  • create a volume
代码语言:javascript
复制
docker volume create webj2eedev-vol
  • list volumes
代码语言:javascript
复制
docker volume ls
  • inspect a volume
代码语言:javascript
复制
docker volume inspect webj2eedev-vol
  • remove a volume
代码语言:javascript
复制
docker volume rm webj2eedev-vol
  • Start a container with a volume
代码语言:javascript
复制
docker run -d \
  --name devtest \
  -v myvol2:/app \
  nginx:latest
  • Use a read-only volume
代码语言:javascript
复制
docker run -d \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html:ro \
  nginx:latest
  • Back up a volume
    • For example, create a new container named dbstore:
代码语言:javascript
复制
docker run -v /dbdata --name dbstore ubuntu /bin/bash
代码语言:javascript
复制
 docker run --rm \
   --volumes-from dbstore \
   -v $(pwd):/backup \
   ubuntu tar cvf /backup/backup.tar /dbdata
  • Restore volume from backup
    • With the backup just created, you can restore it to the same container, or another that you made elsewhere.
    • For example, create a new container named dbstore2:
代码语言:javascript
复制
 docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
代码语言:javascript
复制
 docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
  • To remove all unused volumes and free up space
代码语言:javascript
复制
docker volume prune

4. Bind mounts 使用详解

  • Start a container with a bind mount
代码语言:javascript
复制
docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app \
  nginx:latest
  • Use a read-only bind mount
代码语言:javascript
复制
docker run -d \
  -it \
  --name devtest \
  -v "$(pwd)"/target:/app:ro \
  nginx:latest

5. tmpfs mounts 使用详解

  • 限制条件
    • Unlike volumes and bind mounts, you can’t share tmpfs mounts between containers. (译:tmpfs mounts 不能在容器间共享。)
    • This functionality is only available if you’re running Docker on Linux. (译:tmpfs mounts 只能用在 Linux 上。)
  • Use a tmpfs mount in a container
代码语言:javascript
复制
docker run -d \
  -it \
  --name tmptest \
  --tmpfs /app \
  nginx:latest

参考:

Manage data in Docker: https://docs.docker.com/storage/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档