- 一、 Docker 的四大组成对象
- 二、搭建运行 Docker 环境
- 三、在 Windows 和 Mac 中使用 Docker
- 四、使用容器:镜像与容器
- 五、使用容器:从镜像仓库获得镜像
- 六、使用容器:运行和管理容器
- 七、为容器配置网络
- 八、管理和存储数据
- 九、操作镜像:保存和共享镜像
- 十、操作镜像:通过 Dockerfile 创建镜像
- 十一、常见 Dockerfile 使用技巧
- 十二、使用 Docker Hub 中的镜像
- 十三、组合操作:使用 Docker Compose 管理容器
- 十四、组合操作:常用的 Docker Compose 配置项
- 十五、组合操作:编写 Docker Compose 项目
- 十六、组合操作:应用于服务化开发
八、管理和存储数据
8.1 数据管理实现方式
Docker 容器中的文件系统于我们这些开发使用者来说,虽然有很多优势,但也有很多弊端,其中显著的两点就是
- 沙盒文件系统是跟随容器生命周期所创建和移除的,数据无法直接被持久化存储。
- 由于容器隔离,我们很难从容器外部获得或操作容器内部文件中的数据
当然, Docker
很好的解决了这些问题,这主要还是归功于 Docker
容器文件系统是基于 UnionFS
。由于 UnionFS
支持挂载不同类型的文件系统到统一的目录结构中,所以我们只需要将宿主操作系统中,文件系统里的文件或目录挂载到容器中,便能够让容器内外共享这个文件。
- 由于通过这种方式可以互通容器内外的文件,那么文件数据持久化和操作容器内文件的问题就自然而然的解决了。
- 同时,
UnionFS
带来的读写性能损失是可以忽略不计的,所以这种实现可以说是相当优秀的…
8.2 挂载方式
基于底层存储实现, Docker
提供了三种适用于不同场景的文件系统挂载方式:Bind Mount
、 Volume
和 Tmpfs Mount
Bind Mount
能够直接将宿主操作系统中的目录和文件挂载到容器内的文件系统中,通过指定容器外的路径和容器内的路径,就可以形成挂载映射关系,在容器内外对文件的读写,都是相互可见的。Volume
也是从宿主操作系统中挂载目录到容器内,只不过这个挂载的目录由 Docker 进行管理,我们只需要指定容器内的目录,不需要关心具体挂载到了宿主操作系统中的哪里。Tmpfs Mount
支持挂载系统内存中的一部分到容器的文件系统里,不过由于内存和容器的特征,它的存储并不是持久的,其中的内容会随着容器的停止而消失…
8.3 挂载文件到容器
要将宿主操作系统中的目录挂载到容器之后,我们可以在容器创建的时候通过传递 -v 或 –volume 选项来指定内外挂载的对应目录或文件
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12
- 使用
-v
或--volume
来挂载宿主操作系统目录的形式是-v <host-path>:<container-path>
或--volume <host-path>:<container-path>
,其中host-path
和container-path
分别代表宿主操作系统中的目录和容器中的目录。这里需要注意的是,为了避免混淆,Docker
这里强制定义目录时必须使用绝对路径,不能使用相对路径。 - 我们能够指定目录进行挂载,也能够指定具体的文件来挂载,具体选择何种形式来挂载,大家可以根据具体的情况来选择。
- 当挂载了目录的容器启动后,我们可以看到我们在宿主操作系统中的文件已经出现在容器中了…
$ sudo docker exec nginx ls /usr/share/nginx/html
index.html
在 docker inspect
的结果里,我们可以看到有关容器数据挂载相关的信息
$ sudo docker inspect nginx
[
{
## ......
"Mounts": [
{
"Type": "bind",
"Source": "/webapp/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
## ......
}
]...
在关于挂载的信息中我们可以看到一个 RW
字段,这表示挂载目录或文件的读写性 ( Read and Write
)。实际操作中, Docker
还支持以只读的方式挂载,通过只读方式挂载的目录和文件,只能被容器中的程序读取,但不接受容器中程序修改它们的请求。在挂载选项 -v
后再接上 :ro
就可以只读挂载了…
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12
8.4 挂载临时文件目录
Tmpfs Mount
是一种特殊的挂载方式,它主要利用内存来存储数据。由于内存不是持久性存储设备,所以其带给Tmpfs Mount
的特征就是临时性挂载。- 与挂载宿主操作系统目录或文件不同,挂载临时文件目录要通过
--tmpfs
这个选项来完成。由于内存的具体位置不需要我们来指定,这个选项里我们只需要传递挂载到容器内的目录即可。…
$ sudo docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
容器已挂载的临时文件目录我们也可以通过 docker inspect
命令查看。
$ sudo docker inspect webapp
[
{
## ......
"Tmpfs": {
"/webapp/cache": ""
},
## ......
}
]...
- 挂载临时文件首先要注意它不是持久存储这一特性,在此基础上,它有几种常见的适应场景。
- 应用中使用到,但不需要进行持久保存的敏感数据,可以借助内存的非持久性和程序隔离性进行一定的安全保障。
- 读写速度要求较高,数据变化量大,但不需要持久保存的数据,可以借助内存的高读写速度减少操作的时间…
8.5 使用数据卷
- 除了与其他虚拟机工具近似的宿主操作系统目录挂载的功能外,
Docker
还创造了数据卷 (Volume
) 这个概念。数据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在Docker
内部,接受Docker
的管理。 - 在使用数据卷进行挂载时,我们不需要知道数据具体存储在了宿主操作系统的何处,只需要给定容器中的哪个目录会被挂载即可。
- 我们依然可以使用
-v
或--volume
选项来定义数据卷的挂载。…
$ sudo docker run -d --name webapp -v /webapp/storage webapp:latest
数据卷挂载到容器后,我们可以通过 docker inspect
看到容器中数据卷挂载的信息。
$ sudo docker inspect webapp
[
{
## ......
"Mounts": [
{
"Type": "volume",
"Name": "2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336",
"Source": "/var/lib/docker/volumes/2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336/_data",
"Destination": "/webapp/storage",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
## ......
}
]...
- 这里我们所得到的信息与绑定挂载有所区别,除了
Type
中的类型不一样之外,在数据卷挂载中,我们还要关注一下Name
和Source
这两个信息。 - 其中
Source
是Docker
为我们分配用于挂载的宿主机目录,其位于Docker
的资源区域 ( 这里是默认的/var/lib/docker
) 内。当然,我们并不需要关心这个目录,一切对它的管理都已经在Docker
内实现了。 - 为了方便识别数据卷,我们可以像命名容器一样为数据卷命名,这里的
Name
就是数据卷的命名。在我们未给出数据卷命名的时候,Docker
会采用数据卷的ID
命名数据卷。我们也可以通过-v <name>:<container-path>
这种形式来命名数据卷…
$ sudo docker run -d --name webapp -v appdata:/webapp/storage webapp:latest
由于 -v
选项既承载了 Bind Mount
的定义,又参与了 Volume
的定义,所以其传参方式需要特别留意。前面提到了 ,-v
在定义绑定挂载时必须使用绝对路径,其目的主要是为了避免与数据卷挂载中命名这种形式的冲突。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论