目录
Docker for Mac和Docker for Windows
Docker存储驱动所支持的底层文件系统 编辑 选择存储驱动需考虑的其他事项
默认在容器中创建的所有文件保存在可写的容器层中,这类存储的问题如下:
一、Docker存储驱动
联合文件系统(UnionFS)是一种为Linux、FreeBSD和NetBSD操作系统设计的,将其他文件系统合并到一个联合挂载点的文件系统
Docker引擎可以使用联合文件系统的多种变体
AUFS
OverlayFS
Btrfs
BFS
DeviceMapper
联合文件系统实际上是由存储驱动实现的,相应的存储驱动有aufs、overlay、overlay2、devicemapper、btrfs、zfs、vfs等
1、选择Docker存储驱动的总体原则
在最常用的场合使用具有最佳整体性能和稳定性的存储驱动
如果内核支持多个存储驱动,则Docker会提供要使用的存储驱动的优先级列表
优先使用Linux发行版默认的存储驱动
一些存储驱动要求使用特定格式的底层文件系统,这可能会限制选择
选择存储驱动还要取决于工作负载的特征和所需的稳定性级别
2、Docker版本所支持的存储驱动
Docker引擎企业版和Docker EE
对于Docker引擎企业版和Docker EE来说,支持存储驱动的决定性资源是产品兼容性矩阵。建议用户迁移到overlay2存储驱动
Docker CE
对于Docker CE来说,只有部分配置被测试过,并且操作系统的内核不可能支持每个存储驱动
最佳配置是使用带有支持overlay2存储驱动的内核的现代Linux发行版,并且对于大量的工作负载要使用Docker卷写入,而不是将数据写入容器的可写层
Docker for Mac和Docker for Windows
这两个版本的Docker仅用于开发,而不能用于生产环境,不支持定义存储驱动
Docker存储驱动所支持的底层文件系统
选择存储驱动需考虑的其他事项
适合工作负载
aufs、overlay和overlay2存储驱动的所有操作都在文件级而不是块级,能更有效地使用内存,但容器的可写层可能在写入繁重的工作负载中变得相当大
块级存储驱动(如devicemapper、btrfs和zfs存储驱动)在写入繁重的工作负载时表现得更好
写入大量的小数据,或有很多层的容器,或深层文件系统,overlay存储驱动比overlay2存储驱动性能更好
btrfs和zfs存储驱动需要更多内存
zfs存储驱动是高密度工作负载(如PaaS)的理想选择
共享存储系统
多数情况下Docker可以在SAN、NAS、硬件RAID或其他共享存储系统上工作,但Docker并没有与它们紧密集成
每个Docker存储驱动都基于Linux文件系统或卷管理器。
稳定性
overlay2、aufs、overlay和devicemapper存储驱动的稳定性更高
测试工作负载
在不同的存储驱动上运行工作负载时,可以测试Docker的性能
检查当前的存储驱动
使用docker info命令查看Docker当前使用的存储驱动,从输出的结果中查找“Storage Driver”部分:
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
可以根据需要更改现有的存储驱动
建议在改变存储驱动之前使用docker save命令导出已创建的镜像,或将它们推送到Docker Hub或其他镜像注册中心,以免今后重建它们
更改存储驱动会使得现有的容器和镜像不可访问
二、Docker存储的挂载类型
1、Docker卷与存储驱动
默认在容器中创建的所有文件保存在可写的容器层中,这类存储的问题如下:
此类存储只在容器的生命周期内存在,会随着容器的删除而被删除
如果主机上的其他进程需要访问容器中的数据,则很难从容器中获取数据
容器的可写层与运行容器的主机紧密耦合,无法轻松地将数据转移到其他地方
写入容器的可写层需要Docker存储驱动来管理文件系统
卷有助于解决这些问题:
卷本质上是Docker主机文件系统中的目录或文件,能够直接被挂载到容器的文件系统中
对卷的读写操作会绕过存储驱动,并以本地主机的速度运行。
Docker卷和存储驱动的关系
选择合适的挂载类型
卷
卷存储在主机文件系统中,在Linux主机上默认就是/var/lib/docker/volumes目录
可以以命名或匿名方式挂载卷
卷由Docker创建并管理
作为Docker容器或服务中持久化数据的首选方式,卷适合以下应用场合:
在多个正在运行的容器之间共享数据
当Docker主机不能保证具有特定的目录结构时,卷有助于将Docker主机的配置与容器运行时解耦
当需要将容器的数据存储到远程主机或云时
当需要在两个Docker主机之间备份、恢复或迁移数据时,卷是更好的选择
绑定挂载
绑定挂载可以存储到主机系统的任意位置
与卷相比,绑定挂载功能要受限
绑定挂载性能高,但它们依赖于具有特定目录结构的主机文件系统
绑定挂载适合下面的应用场合:
在主机和容器之间共享配置文件
在Docker主机上的开发环境和容器之间共享源代码或构建工件(Artifacts)
当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时
三、使用Docker卷
1、卷的优势
卷是对由Docker容器产生和使用的数据进行持久化的首选方法
与绑定挂载相比,卷具有以下优势:
卷比绑定挂载更容易备份和迁移
可以通过Docker命令行或Docker API对卷进行管理
卷在Linux容器和Windows容器中都可以工作
在多个容器之间共享时,卷更为安全
卷驱动支持在远程主机或云端存储卷,加密卷内容,以及增加其他功能
新卷的内容可以由容器预填充
2、选择-v或--mount选项
-v选项
-v选项的语法:
-v [host-src:]container-dest[:<options>]
对于命名卷,第1个字段是卷的名称,并且在指定主机上是唯一的
对于匿名卷,第1个字段被省略
第2个字段container-dest是容器中被挂载的文件或目录的路径,必须采用绝对路径的形式
第3个字段是可选的,是一个逗号分隔的选项列表
--mount选项
--mount选项的语法:
--mount <key>=<value>,<key>=<value>,……
--mount选项的语法比-v的更冗长,但键的顺序并不重要,并且键值更易于理解
type:要挂载的类型,值可以是bind、volume或tmpfs
source(或src):要挂载的源,对于命名卷,这里是卷的名字。匿名卷忽略该字段
destination(或dst、target):要挂载的目的地,必须采用绝对路径的形式
readonly:只读选项,表示卷以只读方式挂载到容器中
volume-opt:卷选项,可以被多次指定,由包含选项名和值的键值对组成
创建和管理卷
可以通过docker volume命令在任何容器之外单独创建和管理卷
示例:
创建卷: docker volume create my-vol
列出当前的卷(列出卷驱动和卷名称) docker volume ls
查看卷的详细信息 docker volume inspect my-vol
删除卷 docker volume rm my-vol
启动带有卷的容器
启动带有卷的容器时,如果卷不存在,则Docker会自动创建这个卷;如果卷已存在,则容器可以直接使用卷中的数据
示例:
将卷myvol2挂载到容器中的/app目录
使用--mount选项的实现:
docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
改用-v选项的实现:
docker run -d --name devtest -v myvol2:/app nginx:latest
停止容器并删除卷:
docker container stop devtest
docker container rm devtest
docker volume rm myvol2
使用容器填充卷
启动一个创建新卷或带有空白卷的容器,而容器在要被挂载的目录中已有文件或目录,则该目录的内容会被复制到卷中
容器挂载并使用该卷,而使用该卷的其他容器也可以访问其中预先填充的内容
示例:
启动一个nginx容器,并使用容器的/usr/share/nginx/html目录的内容填充新卷nginx-vol:
docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html nginx:latest
查看主机上该卷所在目录的内容,可以发现容器填充了卷:
# ls /var/lib/docker/volumes/nginx-vol/_data 50x.html index.html
使用只读卷
设置只读权限后,在容器中是无法对卷进行修改的,只有Docker主机有权修改数据
示例:
通过在容器中挂载点后面的选项列表(默认为空)中添加只读参数来将该目录挂载为只读卷
使用--mount选项的实现:
docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly nginx:latest
可改用-v选项产生相同的结果:
docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html:ro nginx:latest
通过docker inspect nginxtest命令验证绑定挂载是否创建正确
停止并删除nginxtest容器,然后删除nginx-vol卷
删除卷
删除命名卷
通过docker volume rm命令来删除卷:
docker volume rm [OPTIONS] VOLUME [VOLUME...]
参数VOLUME表示要删除卷的名称,可以使用卷名列表来删除多个卷
选项-f(--force)表示强制删除卷,包括正在使用的卷
删除匿名卷
匿名卷没有卷名称,不能使用docker volume rm命令删除
要自动删除匿名卷,应在创建容器时使用--rm选项
删除所有卷
docker volume prune