|
1 | 1 | ## 数据卷
|
| 2 | + |
2 | 3 | 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
|
| 4 | + |
3 | 5 | * 数据卷可以在容器之间共享和重用
|
| 6 | + |
4 | 7 | * 对数据卷的修改会立马生效
|
| 8 | + |
5 | 9 | * 对数据卷的更新,不会影响镜像
|
6 |
| -* 数据卷默认会一直存在,即使容器被删除 |
7 | 10 |
|
| 11 | +* 数据卷默认会一直存在,即使容器被删除 |
8 | 12 |
|
9 | 13 | *注意*:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。
|
10 | 14 |
|
| 15 | +### 选择 -v 还是 -–mount 参数 |
| 16 | + |
| 17 | +Docker 新用户应该选择 `--mount` 参数,经验丰富的 Dcoker 使用者对 `-v` 或者 `--volume` 已经很熟悉了,但是推荐你们使用 `--volume` 参数。 |
11 | 18 |
|
12 | 19 | ### 创建一个数据卷
|
13 |
| -在用 `docker run` 命令的时候,使用 `-v` 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。 |
14 | 20 |
|
15 |
| -下面创建一个名为 web 的容器,并加载一个数据卷到容器的 `/webapp` 目录。 |
16 | 21 | ```bash
|
17 |
| -$ docker run -d -P --name web -v /webapp training/webapp python app.py |
| 22 | +$ docker volume create my-vol |
18 | 23 | ```
|
19 |
| -*注意*:也可以在 Dockerfile 中使用 `VOLUME` 来添加一个或者多个新的卷到由该镜像创建的任意容器。 |
20 | 24 |
|
21 |
| -### 删除数据卷 |
22 |
| -数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 `docker rm -v` 这个命令。无主的数据卷可能会占据很多空间,要清理会很麻烦。Docker官方正在试图解决这个问题,相关工作的进度可以查看这个[PR](https://github.com/docker/docker/pull/8484)。 |
| 25 | +查看所有的数据卷 |
23 | 26 |
|
24 |
| -### 挂载一个主机目录作为数据卷 |
25 |
| -使用 `-v` 标记也可以指定挂载一个本地主机的目录到容器中去。 |
26 | 27 | ```bash
|
27 |
| -$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py |
| 28 | +$ docker volume ls |
| 29 | + |
| 30 | +local my-vol |
28 | 31 | ```
|
29 |
| -上面的命令加载主机的 `/src/webapp` 目录到容器的 `/opt/webapp` |
30 |
| -目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。 |
31 | 32 |
|
32 |
| -*注意*:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。 |
| 33 | +在主机里使用以下命令可以查看指定数据卷的信息 |
33 | 34 |
|
34 |
| -Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。 |
35 | 35 | ```bash
|
36 |
| -$ docker run -d -P --name web -v /src/webapp:/opt/webapp:ro |
37 |
| -training/webapp python app.py |
| 36 | +$ docker volume inspect my-vol |
| 37 | +[ |
| 38 | + { |
| 39 | + "Driver": "local", |
| 40 | + "Labels": {}, |
| 41 | + "Mountpoint": "/var/lib/docker/volumes/my-vol/_data", |
| 42 | + "Name": "my-vol", |
| 43 | + "Options": {}, |
| 44 | + "Scope": "local" |
| 45 | + } |
| 46 | +] |
| 47 | +``` |
| 48 | + |
| 49 | +### 启动一个挂载数据卷的容器 |
| 50 | + |
| 51 | +在用 `docker run` 命令的时候,使用 `--mount` 标记来将数据卷挂载到容器里。在一次 `docker run` 中可以挂载多个数据卷。 |
| 52 | + |
| 53 | +下面创建一个名为 `web` 的容器,并加载一个数据卷到容器的 `/webapp` 目录。 |
| 54 | + |
| 55 | +```bash |
| 56 | +$ docker run -d -P \ |
| 57 | + --name web \ |
| 58 | + --mount source=my-vol,target=/webapp \ |
| 59 | + training/webapp \ |
| 60 | + python app.py |
38 | 61 | ```
|
39 |
| -加了 `:ro` 之后,就挂载为只读了。 |
40 | 62 |
|
41 | 63 | ### 查看数据卷的具体信息
|
42 | 64 |
|
43 |
| -在主机里使用以下命令可以查看指定容器的信息 |
| 65 | +在主机里使用以下命令可以查看 `web` 容器的信息 |
| 66 | + |
44 | 67 | ```bash
|
45 | 68 | $ docker inspect web
|
46 |
| -... |
47 | 69 | ```
|
48 | 70 |
|
49 |
| -在输出的内容中找到其中和数据卷相关的部分,可以看到所有的数据卷都是创建在主机的`/var/lib/docker/volumes/`下面的 |
50 |
| -```json |
51 |
| -"Volumes": { |
52 |
| - "/webapp": "/var/lib/docker/volumes/fac362...80535" |
53 |
| -}, |
54 |
| -"VolumesRW": { |
55 |
| - "/webapp": true |
56 |
| -} |
57 |
| -... |
58 |
| -``` |
59 |
| -注:从Docker 1.8.0起,数据卷配置在"Mounts"Key下面,可以看到所有的数据卷都是创建在主机的`/mnt/sda1/var/lib/docker/volumes/....`下面了。 |
| 71 | +`数据卷` 信息在 "Mounts" Key 下面 |
| 72 | + |
60 | 73 | ```json
|
61 | 74 | "Mounts": [
|
62 |
| - { |
63 |
| - "Name": "b53ebd40054dae599faf7c9666acfe205c3e922fc3e8bc3f2fd178ed788f1c29", |
64 |
| - "Source": "/mnt/sda1/var/lib/docker/volumes/b53ebd40054dae599faf7c9666acfe205c3e922fc3e8bc3f2fd178ed788f1c29/_data", |
65 |
| - "Destination": "/webapp", |
66 |
| - "Driver": "local", |
67 |
| - "Mode": "", |
68 |
| - "RW": true, |
69 |
| - "Propagation": "" |
70 |
| - } |
71 |
| - ] |
72 |
| -... |
| 75 | + { |
| 76 | + "Type": "volume", |
| 77 | + "Name": "my-vol", |
| 78 | + "Source": "/var/lib/docker/volumes/my-vol/_data", |
| 79 | + "Destination": "/app", |
| 80 | + "Driver": "local", |
| 81 | + "Mode": "", |
| 82 | + "RW": true, |
| 83 | + "Propagation": "" |
| 84 | + } |
| 85 | +], |
73 | 86 | ```
|
74 | 87 |
|
75 |
| -### 挂载一个本地主机文件作为数据卷 |
76 |
| -`-v` 标记也可以从主机挂载单个文件到容器中 |
| 88 | +### 删除数据卷 |
| 89 | + |
77 | 90 | ```bash
|
78 |
| -$ docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash |
| 91 | +$ docker volume rm my-vol |
79 | 92 | ```
|
80 |
| -这样就可以记录在容器输入过的命令了。 |
81 | 93 |
|
82 |
| -*注意*:如果直接挂载一个文件,很多文件编辑工具,包括 `vi` 或者 `sed --in-place`,可能会造成文件 inode 的改变,从 Docker 1.1 |
83 |
| -.0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。 |
| 94 | +数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 `docker rm -v` 这个命令。 |
| 95 | + |
| 96 | +无主的数据卷可能会占据很多空间,要清理请使用以下命令 |
| 97 | + |
| 98 | +```bash |
| 99 | +$ docker volume prune |
| 100 | +``` |
0 commit comments