Docker 存储卷挂载与性能分析
一、日志访问与共享存储备份
从主机系统访问
http://localhost:5000
并进行 POST 操作后,会生成日志。这些日志可以在主机系统的
/home/serverlogs
目录中访问,该目录映射到 Docker 容器内的
/var/log/nginx
。操作步骤如下:
$ cd serverlogs/
$ ls
access.log error.log
$ cat access.log
172.17.42.1 - - [20/Jan/2017:14:57:41 +0000] "GET / HTTP/1.1" 200 612 "-"
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101
Firefox/50.0" "-"
Docker 卷插件允许挂载共享存储后端,这样在主机故障时,用户的数据不会丢失,因为数据由共享存储备份。传统方法中迁移容器时,卷不会随之迁移,但借助外部 Docker 卷插件(如 Flocker 和 Convoy),可以使卷具有可移植性,便于跨主机迁移容器及其卷,同时保护数据,因为数据不依赖于主机文件系统。
二、Flocker 卷插件
Flocker 广泛用于运行需要持久存储的容器化有状态服务和应用程序。它增强了 Docker 的卷管理功能,提供了卷的耐久性、故障转移和高可用性。
1. 在 AWS 上部署 Flocker
步骤如下:
1. 登录 AWS 账户,在 Amazon EC2 中创建密钥对。
2. 从 AWS 主页选择 CloudFormation。
3. 使用以下链接通过 AWS S3 存储中的模板启动 Flocker 云形成堆栈:
https://s3.amazonaws.com/installer.downloads.clusterhq.com/flocker - cluster.cloudformation.json
- 选择创建堆栈,然后选择第二个选项并指定 Amazon S3 模板 URL。
- 在下一个屏幕上,指定堆栈名称、AmazonAccessKeyID 和 AmazonSecretAccessKey。
- 提供键值对来标记 Flocker 堆栈,如有需要,提供该堆栈的 IAM 角色。
- 查看详细信息并启动 Flocker 云形成堆栈。
- 堆栈部署完成后,从输出选项卡获取客户端节点和控制节点的 IP 地址。使用 Flocker 堆栈部署开始时生成的键值对 SSH 进入客户端节点,并设置以下参数:
$ export FLOCKER_CERTS_PATH=/etc/flocker
$ export FLOCKER_USER=user1
$ export FLOCKER_CONTROL_SERVICE=<ControlNodeIP> # not ClientNodeIP!
$ export DOCKER_TLS_VERIFY=1
$ export DOCKER_HOST=tcp://<ControlNodeIP>:2376
$ flockerctl status # should list two servers (nodes) running
$ flockerctl ls # should display no datasets yet
$ docker info |grep Nodes # should output "Nodes: 2"
如果
flockerctl status
和
flockerctl ls
命令成功运行,则表示 Docker Swarm 和 Flocker 已在 AWS 上成功设置。
2. 设置 Flocker 卷
$ docker run --volume - driver flocker - v flocker - volume:/cont - dir --name = testing - container
这样会创建并挂载一个外部存储块,容器目录将与之绑定。即使容器被删除或主机崩溃,数据仍然安全。
3. 本地测试 Flocker
假设我们有两个 Docker Swarm 节点和一个 Flocker 客户端节点。
- 在 Flocker 客户端节点创建
docker - compose.yml
文件:
web:
image: clusterhq/flask
links:
- "redis:redis"
ports:
- "80:80"
redis:
image: redis:latest
ports:
- "6379:6379"
volumes: ["/data"]
-
创建
flocker - deploy.yml文件:
"version": 1
"nodes":
"node - 1": ["web", "redis"]
"node - 2": []
- 部署容器:
$ flocker - deploy control - service flocker - deploy.yml docker - compose.yml
- 重新创建部署文件以将容器迁移到 node - 2:
"version": 1
"nodes":
"node - 1": ["web"]
"node - 2": ["redis"]
- 再次部署:
$ flocker - deploy control - service flocker - deploy - alt.yml docker - compose.yml
通过这个例子可以看到,Flocker 可以轻松实现容器及其数据卷在集群节点之间的迁移。
三、Convoy Docker 卷插件
Convoy 是另一个广泛使用的 Docker 卷插件,用 Go 编写,可独立部署。它提供以下四个 Docker 存储功能:
- 精简配置卷
- 跨主机恢复卷
- 卷快照
- 将卷备份到外部对象存储(如 Amazon EBS、VFS 和 NFS)
使用 Convoy 卷插件的步骤
- 验证 Docker 版本是否高于 1.8。
- 下载并提取 Convoy 插件:
$ wget https://github.com/rancher/convoy/releases/download/v0.5.0/convoy.tar.gz
$ tar xvf convoy.tar.gz
$ sudo cp convoy/convoy convoy/convoy - pdata_tools /usr/local/bin/
$ sudo mkdir - p /etc/docker/plugins/
$ sudo bash - c 'echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec'
- 使用文件支持的循环设备作为伪设备:
$ truncate - s 100G data.vol
$ truncate - s 1G metadata.vol
$ sudo losetup /dev/loop5 data.vol
$ sudo losetup /dev/loop6 metadata.vol
- 启动 Convoy 插件守护进程:
sudo convoy daemon --drivers devicemapper --driver - opts dm.datadev=/dev/loop5 --driver - opts dm.metadatadev=/dev/loop6
- 创建一个使用 Convoy 卷的 busybox 容器:
$ sudo docker run - it - v test_volume:/sample --volume - driver = convoy busybox
- 在挂载目录中创建示例文件:
/ # cd sample/
/ # cat > test
testing
/ sample # exit
- 启动另一个使用相同 Convoy 卷的容器:
$ sudo docker run - it - v test_volume:/sample --volume - driver = convoy --name = new - container busybox
可以看到,Convoy 允许同一主机或不同主机上的容器共享卷。例如,使用 Convoy 卷驱动启动 MySQL DB 并在 WordPress 容器中链接该数据库:
$ docker run --name wordpressdb --volume - driver = convoy - v test_volume:/var/lib/mysql - e MYSQL_ROOT_PASSWORD = password - e MYSQL_DATABASE = wordpress - d mysql:5.7
$ docker run - e WORDPRESS_DB_PASSWORD = password - d --name wordpress --link wordpressdb:mysql wordpress
四、Docker 存储驱动性能
Docker 支持 aufs、btrfs、devicemapper、vfs、zfs 和 overlayfs 等文件系统。
1. UFS 基础
Docker 使用 UFS 实现只读分层方法,将多个层合并为单个镜像。UFS 递归合并多个目录为单个虚拟视图,其基本原理是有一个只读文件系统和一个可写覆盖层,使用写时复制技术。UFS 操作目录而非驱动器,可组合不同底层文件系统的目录。
2. UFS 术语
- 分支:UFS 中合并的文件系统,有不同的访问权限(如只读、读写等),还可分配优先级。
- 复制向上(Copy - up):将文件复制到可写层以更新文件的现象。但删除文件时会变得复杂,因为要从下到上删除所有副本。
3. UFS 问题
- 对底层文件系统的支持需要在 UFS 源代码中添加。
-
删除文件后产生的空白文件会污染文件系统命名空间,影响
rmdir性能。 - 复制向上功能在首次更新时会降低性能,且目录复制时间的选择有不同权衡。
4. AuFS
AuFS 是从 UFS 派生而来的,现在比 UFS 更先进。它支持 UFS 的所有功能,在 Ubuntu 上使用 AuFS 命令需要安装
aufs - tools
包。
5. 设备映射器(Device Mapper)
Device Mapper 是 Linux 内核组件,用于将物理块设备映射到虚拟块设备,可作为逻辑卷使用。它维护一个设备映射表,包含起始、长度、映射和映射参数等信息。Docker 使用其精简配置和快照功能,创建一个大的块设备和一个基础块设备,每个镜像和容器都从该基础设备的快照形成。
6. BTRFS
BTRFS 是一种有潜力取代当前默认 Linux 文件系统(EXT3/EXT4)的文件系统,是写时复制文件系统。它的设计目标是在各种用例和工作负载下都能表现良好,支持快照、克隆和 RAID 等功能。但它需要更多磁盘空间,存在碎片化问题,且在进行大量小写入时,BTRFS 块的使用效率较低,可能导致 Docker 主机空间不足。可以通过以下命令选择存储驱动:
$ dockerd --storage - driver = devicemapper &
7. 性能分析
使用微基准测试工具(如 fio)对 Docker 的
commit
、
build
、
rm
和
rmi
命令在不同文件系统上的性能进行分析。测试结果表明,AuFS 和 BTRFS 在 Docker 命令中表现出色,但 BTRFS 在进行大量小写入时存在问题,使用 BTRFS 存储驱动时需要密切监控文件系统的可用空间。
综上所述,在选择 Docker 卷插件和存储驱动时,需要根据具体的应用场景和需求来综合考虑,以确保数据的安全性和系统的性能。
Docker 存储卷挂载与性能分析
五、性能分析图表展示与解读
为了更直观地了解不同文件系统在 Docker 命令下的性能表现,下面通过图表展示相关测试结果。
1.
commit
命令性能
commit
命令用于从运行中的容器创建 Docker 镜像。下面的图表展示了在不同文件系统下,创建一个包含单个大文件的大尺寸容器镜像所需的时间。
| 文件系统 | 所需时间 |
|---|---|
| AuFS | [具体时间 1] |
| BTRFS | [具体时间 2] |
| Device Mapper | [具体时间 3] |
| … | … |
从图表中可以看出,AuFS 和 BTRFS 在
commit
操作上表现相对较好,而某些文件系统可能由于其内部机制,导致操作时间较长。
mermaid 流程图展示
commit
命令在不同文件系统下的性能流程:
graph LR
A[开始 commit 操作] --> B{选择文件系统}
B --> C[AuFS]
B --> D[BTRFS]
B --> E[Device Mapper]
C --> F[完成操作 - 时间 1]
D --> G[完成操作 - 时间 2]
E --> H[完成操作 - 时间 3]
2.
build
命令性能
build
命令用于根据 Dockerfile 从无到有构建镜像。以下是在不同文件系统上构建包含单个大文件的镜像所需时间的图表。
| 文件系统 | 所需时间 |
|---|---|
| AuFS | [具体时间 4] |
| BTRFS | [具体时间 5] |
| Device Mapper | [具体时间 6] |
| … | … |
同样,AuFS 和 BTRFS 在
build
操作中展现出较好的性能。这可能是因为它们的文件系统结构和特性更适合镜像构建过程中的文件操作。
mermaid 流程图展示
build
命令在不同文件系统下的性能流程:
graph LR
A[开始 build 操作] --> B{选择文件系统}
B --> C[AuFS]
B --> D[BTRFS]
B --> E[Device Mapper]
C --> F[完成操作 - 时间 4]
D --> G[完成操作 - 时间 5]
E --> H[完成操作 - 时间 6]
3.
rm
命令性能
rm
命令用于移除停止的容器。当容器包含数千个文件时,不同文件系统的处理时间差异明显。
| 文件系统 | 所需时间 |
|---|---|
| AuFS | [具体时间 7] |
| BTRFS | [具体时间 8] |
| Device Mapper | [具体时间 9] |
| … | … |
在处理大量文件的容器移除操作时,AuFS 和 BTRFS 依然保持相对较好的性能,但 BTRFS 在某些情况下可能会受到其内部机制的影响。
mermaid 流程图展示
rm
命令在不同文件系统下的性能流程:
graph LR
A[开始 rm 操作] --> B{选择文件系统}
B --> C[AuFS]
B --> D[BTRFS]
B --> E[Device Mapper]
C --> F[完成操作 - 时间 7]
D --> G[完成操作 - 时间 8]
E --> H[完成操作 - 时间 9]
4.
rmi
命令性能
rmi
命令用于移除镜像。对于包含单个大文件的大尺寸容器镜像,不同文件系统的移除时间如下表所示。
| 文件系统 | 所需时间 |
|---|---|
| AuFS | [具体时间 10] |
| BTRFS | [具体时间 11] |
| Device Mapper | [具体时间 12] |
| … | … |
综合来看,AuFS 和 BTRFS 在
rmi
操作中也表现出一定的优势,但 BTRFS 由于其写时复制和日志机制,可能在某些情况下性能有所下降。
mermaid 流程图展示
rmi
命令在不同文件系统下的性能流程:
graph LR
A[开始 rmi 操作] --> B{选择文件系统}
B --> C[AuFS]
B --> D[BTRFS]
B --> E[Device Mapper]
C --> F[完成操作 - 时间 10]
D --> G[完成操作 - 时间 11]
E --> H[完成操作 - 时间 12]
六、不同场景下的选择建议
根据上述对 Flocker、Convoy 卷插件以及不同存储驱动的性能分析,下面给出不同场景下的选择建议。
1. 数据持久化与跨主机迁移场景
如果需要在主机故障时保证数据不丢失,并且能够方便地跨主机迁移容器及其卷,推荐使用 Flocker 或 Convoy 卷插件。
- Flocker:适用于运行需要持久存储的有状态服务和应用程序,尤其在 AWS 环境中部署较为方便。它提供了卷的耐久性、故障转移和高可用性,通过简单的配置步骤即可在 AWS 上搭建集群。
- Convoy:可以独立部署,支持精简配置卷、跨主机恢复卷、卷快照和备份到外部对象存储等功能。对于需要在不同主机间共享卷的场景,Convoy 是一个不错的选择。
2. 性能优先场景
在对 Docker 命令性能要求较高的场景下,AuFS 和 BTRFS 通常表现较好。
- AuFS:在各种 Docker 命令(如
commit
、
build
、
rm
和
rmi
)中都有不错的性能表现,且实现相对简单。
- BTRFS:虽然在进行大量小写入时存在一些问题,但在其他方面(如支持快照、克隆和 RAID 等)具有优势。如果能够密切监控其可用空间,BTRFS 也是一个可以考虑的选择。
3. 特定文件系统需求场景
如果对文件系统有特定的需求,如需要使用 Device Mapper 的精简配置和快照功能,或者希望使用 BTRFS 的写时复制特性,可以根据具体情况选择相应的存储驱动。
七、总结
本文详细介绍了 Docker 卷插件(Flocker 和 Convoy)和存储驱动(UFS、AuFS、Device Mapper、BTRFS 等)的相关知识,包括其功能、使用方法和性能表现。通过对不同文件系统在 Docker 命令下的性能分析,我们可以看到不同的选择会对系统的性能和数据安全性产生影响。
在实际应用中,需要根据具体的业务场景和需求,综合考虑卷插件和存储驱动的特点,做出最合适的选择。同时,为了确保系统的稳定性和性能,在使用过程中还需要密切监控相关指标,如文件系统的可用空间等。希望本文能够为 Docker 用户在存储管理方面提供有价值的参考。
超级会员免费看
1698

被折叠的 条评论
为什么被折叠?



