【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的规划需要运维规划。没有工具解决

相关推荐
Suchadar1 小时前
Docker基础命令(二)——数据卷管理端口映射与容器互联
运维·docker·容器
firstacui1 小时前
Docker容器网络管理与容器数据卷管理
运维·docker·容器
codeRichLife2 小时前
docker拷贝,导入/导出等常用命令
docker
努力搬砖的咸鱼3 小时前
部署你的第一个应用到 K8s
微服务·云原生·容器·kubernetes
lpruoyu4 小时前
【Docker进阶-01】Docker隔离原理与可视化界面-Portainer
docker
舰长1154 小时前
使用 kubeadm搭建生产环境的单 master 节点 K8S 集群(一)
云原生·容器·kubernetes
Swift社区5 小时前
Docker 构建 Python FastAPI 镜像最佳实践
python·docker·fastapi
API开发5 小时前
CentOS 单独安装Docker Compose v2
linux·docker·centos·docker compose
hwj运维之路5 小时前
Docker面试题汇总系列
运维·docker·云原生·容器
chao_7895 小时前
双设备全栈开发最佳实践[mac系统]
git·python·macos·docker·vue·全栈