【docker】存储卷

【docker】存储卷

什么是存储卷:宿主机和容器的目录绑定关系,然后容器中的进程向这个目录写数据时,就是直接写在宿主机目录上。反之亦然。两者的数据读写一致。

应用

数据持久化

如果容器对相关数据删除,宿主机还会保存这一部分数据。

性能问题

UnionFS对于修改和删除效率太低了,需要一层一层寻找到宿主机。如果使用存储卷,就可以直接找到宿主机

容器和宿主机方便共享

原本需要docker cp完成容器和宿主机cp,现在只需要创建存储卷就可以了。而且,对于容器和容器,想要完成共享会更复杂,使用存储卷就可以最简单完成共享了。


分类

type of mount 文件挂载类型

volume docker 管理卷

管理卷 :宿主机的目录由docker管理,目录默认放在/var/lib/docker/volumes目录下

优点:docker管理,方便

不精准:docker管理不能准确指定使用哪些目录,常作为临时存储

bind mount 绑定卷

绑定卷:宿主机的路径由用户设置、而不是由docekr默认创建

缺点和优点:与 volume docker 正好相反,如果这个目录有东西,我们需要判断是否是容器需要的,如果不需要,要挪出去。实际生产中bind mount使用的最频繁了。

tmpfs mount 临时数据卷

临时卷:容器的目录绑定到宿主机的内存

优点:安全、快速,放内存上不容易被看到

缺点:容器一丢失数据,数据就丢失了,不能持久化

命令

管理卷 volume

用的少,了解

docker volume create 创建存储卷
shell 复制代码
docker volume create [OPTIONS] [VOLUME]
# -d 指定驱动
# --label 指定元数据,也就是指定描述的创建卷的描述信息

示例

shell 复制代码
docker volume create # 创建匿名卷,此时会回显卷的默认名称
docker volume ls # 查看卷
docker volume inspect + 卷id # 查看详细信息,可以看到/data/var/lib/docker/volumes/卷名称/_data我们使用ll查看对应目录,发现默认是空的
docker volume create myvolume  # 创建命名卷,回显myvolume,表示卷的名称
docker volume --laber MYTEST=1 myvolume2 # 可以在Labels字段发现MYTEST
docker volume inspect
docker volume ls

参数

shell 复制代码
-- format可以指定输出格式
-f 可以完成过滤
-q 只返回名字
docker volume prune 删除没有使用的匿名卷(对命名卷不处理)
docker volume rm 删除卷
shell 复制代码
docker rm -f test-container  # 解除卷与容器的关联,不然没法直接删除管理卷
docker volume rm test-vol    # 删除卷

如果卷里面有数据也会清理掉,会连带关联的目录一起清理掉

要区分卷和容器的区别,卷本质上就是在宿主机创建了保存容器数据、完成交互的桥梁,如果仅仅删除容器,不会导致管理卷丢失,也就不会导致宿主机存储的容器的数据丢失,但是如果删除管理卷,数据就真的丢失了

-v 指明目录并创建管理卷
shell 复制代码
docker run -d --name myvolnginx1 -v volnginx1:/usr/share/nginx/html/ nginx:1.24.0
docker volume ls # 可以查看到刚刚设置的管理卷了
ll /data/var/lib/docker/volumes/volnginx1/_data #查看对应的挂载目录,发现有数据
docker exec -it myvolnginx1 bash # 运行宿主机
cd /usr/share/nginx/html/ # 然后对文件修改,会发现使用宿主机查看文件也会被修改
docker run -d --name myvolnginx2 -v volnginx2:/usr/share/nginx/html/:ro nginx:1.24.0 # 带有:ro
# 然后进入容器中删除对应目录,会发现不允许。不过可以在宿主机上可以修改
--mount 指定参数并创建管理卷

示例

shell 复制代码
docker run -d --name mynginx3 --mount 'src=nginxvol3,dst=/usr/share/nginx/html' + 镜像

参数

shell 复制代码
type 表示bind volume tmpfs
src 命名卷,不带有表示匿名卷
dst 表示管理卷
卷的生命周期

如果我们只是删除容器,不会删除卷,此时在宿主机查看对应路径,发现还有对应内容,但是如果我们使用docker volume rm删除卷,就看不到对应目录的内容了。

卷的共享

我们可以-v来把多个容器绑定到同一个卷。实现多个容器共享卷的效果

绑定卷 bind

使用docker bind绑定卷,如果容器卷对应目录在绑定前有东西,但是宿主机对应目录绑定时没有东西,那么容器卷就要先清空了

--mount
  • --mount的src表示宿主机目录

  • 如果宿主机对应目录不存在,不可以创建绑定卷

  • 如果宿主机对应目录没有文件,容器对应目录也要清空

示例

shell 复制代码
docker run -d --name mynginx7 --mount 'type=bind,src=/data/maxhou/testmountbind,dst=/usr/share/nginx/html' + 镜像
-v
  • -v 只有一个参数和volume不一样,第一个参数多了一个宿主机目录的参数

  • 如果宿主机对应目录不存在,会自动在宿主机创建对应目录

  • 如果宿主机对应目录没有文件,容器对应目录也要清空

示例

shell 复制代码
docker run -d --name mynginx6 -v /data/maxhou/testbind:/usr/share/nginx/html/ + 镜像
共享和管理卷相同

临时卷 tmpfs (只能linux使用)

  • 如果我们刚好绑定了容器内部已经存在文件的目录,那么目录里面的内容会被清理掉
  • 容器可以正常访问对应目录,对于容器来说,和文件没有区别,但是本质上存储的数据都在内存上。如果我们重启容器,就会发现对应目录空了。

示例

shell 复制代码
docker run -d --name mynginx10 -tmpfs /test1 + 镜像 # 这个/test1表示容器内的数据
--mount 指明多参数

示例

shell 复制代码
docker run -d --name mynginx11 --mount type=tmpfs,dst=/test2 + 镜像

案例

shell 复制代码
docker run -d --name mynginx18 -p 8091:80 --mount type=tmpfs,dst=/usr/share/nginx/html,tmpfs-size=1m

docker exec -it mynginx18 bash 
cd /usr/share/nginx/ # 发现目录是空的,这是因为被覆盖了
# 如果我们向对应目录放内容,如果发现文件大小大于规定的大小,会提示空间不足
# 如果我们想在宿主机查找对应文件:/data/var/lib/docker/... 我们可以使用find查找创建的文件
# 如果容器消失,在宿主机就看不到对应文件了

实战案例

MYSQL灾难恢复

创建绑定卷

shell 复制代码
docker run --name mysql2 -v /data/maxhou/mysql2test:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7 # 在docker官方搜索mysql镜像,然后找到对应版本修改密码和宿主机路径即可
# 然后创建一个database table

删除容器

shell 复制代码
docker rm -f mysql2

启动新的容器绑定宿主机目录

shell 复制代码
docker run --name mysql2new -v /data/maxhou/mysql2test:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7 
docker exec -it mysql2new bash
# 然后根据密码进入mysql,查询database table 
# 发现仍然存在数据

结论:可以使用绑定卷来防止容器删除导致数据丢失,实现持久化

不同卷的应用场景

volume:不需要规划具体目录场景

bind:控制谁来使用哪个目录

tmpfs:用于敏感文件,容器关闭后文件就消失了

存储卷在实际研发带来的问题

  • 存储卷是有状态应用。如果我们希望不同主机共享存储卷信息,需要搭建NFS或者其他共享存储工具,实现共享存储。docker不能自己完成这样的功能。

  • 启动参数未知,每次容器启动都需要很多参数------为此需要容器编排工具,比如k8s

  • 复杂场景仍然需要运维,mysql扩容缩容、为什么挂掉,mysql的规划需要运维规划。没有工具解决

相关推荐
绯雨千叶1 小时前
修改Docker镜像和容器的默认存储目录(迁移原有数据)
运维·docker·容器
悬弧1 小时前
第1章:Dashboard初体验 - 你的可视化K8s控制台
云原生·容器·kubernetes
就叫飞六吧2 小时前
docker一键部署gitlab
docker·容器·gitlab
ernesto_ji5 小时前
docker部署nginxUI
docker
虚伪的空想家12 小时前
云镜像,虚拟机镜像怎么转换成容器镜像
服务器·docker·容器·k8s·镜像·云镜像·虚机
人工智能训练13 小时前
Linux 系统核心快捷键表(可打印版)
linux·运维·服务器·人工智能·ubuntu·容器·openeuler
x***133913 小时前
使用Docker快速搭建Redis主从复制
redis·docker·容器
czc13114 小时前
4K QPS 博客社区:CCBlog 全栈开源,Springboot项目实战,Docker一键部署
spring boot·redis·docker·开源·vue·rabbitmq
sanduo11214 小时前
docker 构建编排过程中常见问题
运维·docker·容器