16、Docker 存储与卷管理深度解析

Docker 存储与卷管理深度解析

1. 主机日志访问与共享存储卷备份

从主机系统访问 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),可以实现卷的可移植性,便于跨主机迁移容器及其卷,同时保护数据,因为数据不依赖于主机文件系统。

2. Flocker 卷插件

Flocker 广泛用于运行需要持久存储的容器化有状态服务和应用程序。Docker 仅提供基本的卷管理视图,而 Flocker 通过提供卷的持久性、故障转移和高可用性来增强这一功能。它既可以与 Docker Swarm 和 Compose 手动部署,也可以借助 CloudFormation 模板在 AWS 上轻松设置。

2.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
  4. 选择创建堆栈,然后选择第二个选项并指定 Amazon S3 模板 URL。
  5. 在下一个屏幕上,为账户指定堆栈名称、 AmazonAccessKeyID AmazonSecretAccessKey
  6. 提供键值对来标记此 Flocker 堆栈,并在需要时为此堆栈提供 IAM 角色。
  7. 查看详细信息并启动 Flocker 云形成堆栈。
  8. 堆栈部署完成后,从输出选项卡获取客户端节点和控制节点的 IP 地址。使用 Flocker 堆栈部署开始时生成的键值对通过 SSH 登录到客户端节点。设置以下参数:
    bash $ export FLOCKER_CERTS_PATH=/etc/flocker $ export FLOCKER_USER=user1 $ export FLOCKER_CONTROL_SERVICE=<ControlNodeIP> # 不是 ClientNodeIP! $ export DOCKER_TLS_VERIFY=1 $ export DOCKER_HOST=tcp://<ControlNodeIP>:2376 $ flockerctl status # 应列出两个正在运行的服务器(节点) $ flockerctl ls # 此时应无数据集显示 $ docker info |grep Nodes # 应输出 "Nodes: 2"

如果 flockerctl status flockerctl ls 命令成功运行,则表明 Docker Swarm 和 Flocker 已在 AWS 上成功设置。

2.2 Flocker 卷的使用

可以轻松设置 Flocker 卷,并创建一个在容器或容器主机生命周期之外仍能持久存在的容器:

$ docker run --volume-driver flocker -v flocker-volume:/cont-dir --name=testing-container

这样会创建并挂载一个外部存储块,容器目录将与之绑定。即使容器被删除或主机崩溃,数据仍能得到安全保护。可以在第二个主机上使用相同命令启动替代容器,并访问共享存储。

2.3 本地测试 Flocker

考虑一个包含两个 Docker Swarm 节点和一个 Flocker 客户端节点的用例。在 Flocker 客户端节点上:
1. 创建 docker-compose.yml 文件,定义 redis clusterhq/flask 容器,并提供相应的 Docker 镜像、名称、端口和数据卷配置:
yaml web: image: clusterhq/flask links: - "redis:redis" ports: - "80:80" redis: image: redis:latest ports: - "6379:6379" volumes: ["/data"]
2. 创建 flocker-deploy.yml 文件,定义将部署在同一节点(node - 1)上的两个容器,暂时将 Swarm 集群中的 node - 2 留空:
yaml "version": 1 "nodes": "node-1": ["web", "redis"] "node-2": []
3. 使用上述 .yml 文件部署容器,只需运行以下命令:
bash $ flocker-deploy control-service flocker-deploy.yml docker-compose.yml
部署完成后,可在 http://node - 1 上访问应用程序,它将显示网页的访问计数。

若要将容器迁移到 node - 2,需重新创建部署文件:

"version": 1
"nodes":
  "node-1": ["web"]
  "node-2": ["redis"]

然后运行以下命令进行迁移:

$ flocker-deploy control-service flocker-deploy-alt.yml docker-compose.yml

迁移完成后,SSH 到 node - 2 并列出正在运行的 Redis 容器,访问 http://node2 ,可以看到计数仍然保留,并且每次访问时会递增。

3. Convoy Docker 卷插件

Convoy 是另一个广泛用于提供存储后端的 Docker 卷插件,用 Go 语言编写,其主要优点是可以独立部署。Convoy 作为 Docker 卷扩展运行,类似于中间容器。其初始实现利用 Linux 设备,为卷提供以下四种 Docker 存储功能:
- 精简配置卷
- 跨主机恢复卷
- 对卷进行快照
- 将卷备份到外部对象存储(如 Amazon EBS、虚拟文件系统(VFS)和网络文件系统(NFS))

3.1 使用 Convoy 卷插件的步骤
  1. 验证 Docker 版本是否高于 1.8。
  2. 本地下载插件 tar 文件并提取:
    bash $ wget https://github.com/rancher/convoy/releases/download/v0.5.0/convoy.tar.gz $ tar xvf convoy.tar.gz convoy/ convoy/convoy-pdata_tools convoy/convoy convoy/SHA1SUMS $ 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'
  3. 使用文件支持的循环设备作为伪设备,使文件可作为块设备访问,以演示 Convoy 设备映射器驱动程序:
    bash $ truncate -s 100G data.vol $ truncate -s 1G metadata.vol $ sudo losetup /dev/loop5 data.vol $ sudo losetup /dev/loop6 metadata.vol
  4. 设置好数据和元数据设备后,启动 Convoy 插件守护进程:
    bash sudo convoy daemon --drivers devicemapper --driver-opts dm.datadev=/dev/loop5 --driver-opts dm.metadatadev=/dev/loop6
  5. 在另一个终端实例中,创建一个使用 Convoy 卷 test_volume 并挂载到容器内 /sample 目录的 busybox Docker 容器:
    bash $ sudo docker run -it -v test_volume:/sample --volume-driver=convoy busybox
  6. 在挂载目录中创建示例文件:
    bash / # cd sample/ / # cat > test testing /sample # exit
  7. 使用 Convoy 作为卷驱动程序启动另一个容器,并挂载相同的 Convoy 卷:
    bash $ sudo docker run -it -v test_volume:/sample --volume-driver=convoy --name=new-container busybox
  8. 在新容器中查看之前创建的文件:
    bash / # cd sample/ /sample # ls lost+found test /sample # exit

Convoy 可用于持久数据,如 WordPress 的 MySQL 数据库:

$ 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
4. Docker 存储驱动程序性能

Docker 支持多种文件系统,如 aufs、btrfs、devicemapper、vfs、zfs 和 overlayfs。可插拔的存储驱动程序架构和灵活的卷挂载方式是容器化环境和生产用例的最佳选择。

4.1 UFS 基础知识

Docker 使用 UFS 实现只读分层方法,将多个层组合成单个镜像。UFS 递归地将多个目录合并为单个虚拟视图,其基本需求是有一个只读文件系统和一个可写覆盖层,通过写时复制(copy - on - write)实现文件系统的读写访问错觉。UFS 操作的是目录而非驱动器,底层文件系统无关紧要,它可以组合来自不同底层文件系统的目录。

4.2 UFS 术语
  • 分支(Branches) :UFS 中合并的文件系统,可具有不同的访问权限(如只读、读写等)。UFS 是可堆叠的文件系统,分支还可以分配优先级,决定对文件系统执行操作的顺序。
  • 复制向上(Copy - up) :将文件复制到可写层以更新文件的现象。当尝试删除文件时,由于需要从下到上删除所有副本,可能会在只读层出现错误。在这种情况下,文件从可写层删除,但仍存在于下面的只读层中。
4.3 UFS 存在的问题
  • 底层文件系统支持 :UFS 需要在源代码中添加对底层文件系统的支持,尽管底层文件系统本身不会改变,但 UFS 必须为每个文件系统添加支持。
  • 空白文件(Whiteouts) :删除文件后创建的空白文件会污染文件系统命名空间,降低 rmdir 性能。
  • 复制向上的缺点 :首次更新时性能会降低,因为需要将完整的文件和目录层次结构复制到可写层,并且需要决定目录复制的时间,有两种选择(更新时复制整个目录层次结构或在打开目录时复制),各有优缺点。
4.4 AuFS

AuFS 是另一种 UFS,它从 UFS 文件系统派生而来,受到开发者的关注,目前在功能上领先于 UFS。AuFS 支持 UFS 的所有功能,在 Ubuntu 上使用 AuFS 命令需要安装 aufs - tools 包,更多信息可在 AuFS 手册页中找到。

4.5 Device Mapper

Device Mapper 是 Linux 内核组件,用于将物理块设备映射到虚拟块设备,这些映射设备可作为逻辑卷使用。它维护一个表来定义设备映射,表中包含起始位置、长度、映射类型和映射参数等信息。

Docker 使用 Device Mapper 的精简配置和快照功能,允许在同一数据卷上存储多个虚拟设备。使用两个单独的设备分别存储数据和元数据,Docker 创建一个大的块设备并在其上创建一个薄池,然后创建一个基础块设备,每个镜像和容器都是该基础设备的快照。

4.6 BTRFS

BTRFS 是一种有潜力取代当前默认 Linux 文件系统(EXT3/EXT4)的文件系统,它是一种写时复制(CoW)文件系统,每次更新数据时都会创建新副本,因此需要更多的存储空间,并且存在碎片化问题。

BTRFS 的主要设计目标是开发一种适用于各种用例和工作负载的通用文件系统,它支持快照、克隆和 RAID(级别 0、1、5、6、10)。其布局由 B - 树表示,类似于 B - 树森林,并且具有复杂的空间回收机制和垃圾回收器,使用引用计数回收未使用的磁盘空间,同时使用校验和确保数据完整性。

可以通过在 dockerd 命令行中传递 --storage - driver 选项或在 /etc/default/docker 文件中设置 DOCKER_OPTS 选项来选择存储驱动程序:

$ dockerd --storage-driver=devicemapper &
4.7 性能分析

使用微基准测试工具(如 fio)对 Docker 的 commit build rm rmi 命令在不同文件系统上的性能进行分析。测试结果表明,AuFS 和 BTRFS 在 Docker 命令中表现出色,但 BTRFS 容器进行大量小写入时,会导致 BTRFS 块使用效率低下,最终可能导致 Docker 主机空间不足,并且由于 BTRFS 的日志记录技术,顺序写入性能会受到影响,可能会使性能减半。因此,使用 BTRFS 存储驱动程序时需要密切监控 BTRFS 文件系统的可用空间。

Docker 存储与卷管理深度解析

5. 存储驱动性能对比

为了更直观地了解不同存储驱动在 Docker 中的性能表现,下面通过表格形式对之前提到的几种主要存储驱动(AuFS、BTRFS、Device Mapper)在不同 Docker 命令下的性能进行对比:
| 存储驱动 | commit 命令 | build 命令 | rm 命令 | rmi 命令 | 其他特点 |
| — | — | — | — | — | — |
| AuFS | 表现良好 | 表现良好 | - | - | 从 UFS 派生,功能领先,操作目录,支持写时复制 |
| BTRFS | 表现良好 | 表现良好 | - | - | 写时复制文件系统,支持快照、克隆、RAID,有空间回收机制,但大量小写入可能导致空间不足,顺序写入性能受影响 |
| Device Mapper | - | - | - | - | 利用 Linux 内核组件,支持精简配置和快照,使用数据和元数据设备 |

以下是一个 mermaid 流程图,展示不同存储驱动在 Docker 操作中的选择逻辑:

graph LR
    A[选择存储驱动] --> B{是否需要写时复制特性}
    B -- 是 --> C{是否对空间使用和顺序写入性能要求高}
    C -- 是 --> D[选择 AuFS]
    C -- 否 --> E[选择 BTRFS]
    B -- 否 --> F{是否需要精简配置和快照功能}
    F -- 是 --> G[选择 Device Mapper]
    F -- 否 --> H[根据其他需求选择 vfs、zfs 等]
6. 不同场景下的存储驱动选择建议

根据不同的应用场景和需求,合理选择 Docker 存储驱动至关重要。以下是一些具体的场景及对应的存储驱动选择建议:
- 开发和测试环境
- 特点 :对性能要求相对较低,更注重快速部署和灵活性。
- 建议 :可以选择 AuFS 或 vfs。AuFS 功能丰富,易于使用;vfs 简单直接,适合快速搭建测试环境。
- 生产环境 - 大量小文件读写
- 特点 :需要高效的文件读写性能,对数据的持久性和可靠性要求高。
- 建议 :优先考虑 AuFS,它在处理大量小文件时表现出色,且具有较好的兼容性。
- 生产环境 - 数据备份和恢复需求高
- 特点 :需要支持快照和克隆功能,以便快速备份和恢复数据。
- 建议 :BTRFS 是不错的选择,它原生支持快照和克隆,能够满足数据备份和恢复的需求。
- 生产环境 - 对存储资源管理要求高
- 特点 :需要对存储资源进行精细管理,如精简配置和动态分配。
- 建议 :Device Mapper 提供了强大的存储资源管理功能,适合这种场景。

7. 总结与最佳实践

通过对 Docker 存储驱动和卷管理的深入探讨,我们可以总结出以下最佳实践:
- 卷管理方面
- 选择合适的卷插件 :根据实际需求选择 Flocker 或 Convoy 等卷插件。如果需要在 AWS 等云环境中实现容器和卷的迁移,Flocker 是一个不错的选择;如果希望独立部署并实现卷的共享,Convoy 更合适。
- 数据持久化 :对于重要的数据,如数据库,使用支持持久化的卷插件,确保数据在容器或主机故障时不会丢失。
- 存储驱动选择方面
- 评估应用需求 :在选择存储驱动之前,充分评估应用的读写模式、数据量、性能要求等因素。
- 监控和优化 :使用 BTRFS 存储驱动时,密切监控文件系统的可用空间,避免出现空间不足的问题。定期对存储系统进行性能测试和优化,确保 Docker 环境的稳定运行。

8. 未来展望

随着 Docker 技术的不断发展,存储驱动和卷管理也将不断演进。未来可能会出现更高效、更灵活的存储驱动,以满足日益增长的容器化应用需求。例如,可能会有新的文件系统被集成到 Docker 中,提供更好的性能和功能。同时,卷插件的功能也将不断增强,实现更便捷的跨云、跨数据中心的容器和卷迁移。

总之,深入了解 Docker 的存储驱动和卷管理知识,选择合适的技术方案,并不断关注行业的发展动态,将有助于我们更好地构建和管理容器化应用。

计及源荷不确定性的综合能源生产单元运行调度容量配置优化研究(Matlab代码实现)内容概要:本文围绕“计及源荷不确定性的综合能源生产单元运行调度容量配置优化”展开研究,利用Matlab代码实现相关模型的构建仿真。研究重点在于综合能源系统中多能耦合特性以及风、光等可再生能源出力和负荷需求的不确定性,通过鲁棒优化、场景生成(如Copula方法)、两阶段优化等手段,实现对能源生产单元的运行调度容量配置的协同优化,旨在提高系统经济性、可靠性和可再生能源消纳能力。文中提及多种优化算法(如BFO、CPO、PSO等)在调度预测中的应用,并强调了模型在实际能源系统规划运行中的参考价值。; 适合人群:具备一定电力系统、能源系统或优化理论基础的研究生、科研人员及工程技术人员,熟悉Matlab编程和基本优化工具(如Yalmip)。; 使用场景及目标:①用于学习和复现综合能源系统中考虑不确定性的优化调度容量配置方法;②为含高比例可再生能源的微电网、区域能源系统规划设计提供模型参考和技术支持;③开展学术研究,如撰写论文、课题申报时的技术方案借鉴。; 阅读建议:建议结合文中提到的Matlab代码和网盘资料,先理解基础模型(如功率平衡、设备模型),再逐步深入不确定性建模优化求解过程,注意区分鲁棒优化、随机优化分布鲁棒优化的适用场景,并尝试复现关键案例以加深理解。
内容概要:本文系统分析了DesignData(设计数据)的存储结构,围绕其形态多元化、版本关联性强、读写特性差异化等核心特性,提出了灵活性、版本化、高效性、一致性和可扩展性五大设计原则。文章深入剖析了三类主流存储方案:关系型数据库适用于结构化元信息存储,具备强一致性高效查询能力;文档型数据库适配半结构化数据,支持动态字段扩展嵌套结构;对象存储结合元数据索引则有效应对非结构化大文件的存储需求,具备高扩展性低成本优势。同时,文章从版本管理、性能优化和数据安全三个关键维度提出设计要点,建议采用全量增量结合的版本策略、索引缓存优化性能、并通过权限控制、MD5校验和备份机制保障数据安全。最后提出按数据形态分层存储的核心结论,并针对不同规模团队给出实践建议。; 适合人群:从事工业设计、UI/UX设计、工程设计等领域数字化系统开发的技术人员,以及负责设计数据管理系统架构设计的中高级工程师和系统架构师。; 使用场景及目标:①为设计数据管理系统选型提供依据,合理选择或组合使用关系型数据库、文档型数据库对象存储;②构建支持版本追溯、高性能访问、安全可控的DesignData存储体系;③解决多用户协作、大文件存储、历史版本管理等实际业务挑战。; 阅读建议:此资源以实际应用场景为导向,结合具体数据库类型和表结构设计进行讲解,建议读者结合自身业务数据特征,对比分析不同存储方案的适用边界,并在系统设计中综合考虑成本、性能可维护性之间的平衡。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值