Docker容器数据卷

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Docker系列文章:此篇是Docker系列的第四篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,加油!• 为什么要学习Docker• Docker基本概念• Docker镜像基本原理

一、前言


Docker系列文章:

此篇是Docker系列的第四篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,加油!

二、为什么需要容器数据卷


  • 数据的持久化,假设MySQL的数据存储在自身的镜像当中,如果将镜像删除的话,存储的数据就会丢失,这样真的就是删库跑路了,因此需要将容器中的数据持久化到磁盘上去;
  • 如果将数据存储于镜像中,主机上的其他进程不方便访问这些数据;

三、数据卷持久化的三种方式比较


bind mount

存在于主机系统中的任意位置,非 Docker 的进程或者 Docker 容器可能随时对其进行修改,存在潜在的安全风险。bind mount在不同的宿主机系统时不可移植的,比如Windows和Linux的目录结构是不一样的,bind mount所指向的host目录也不能一样。

volume

存于主机文件系统中的某个区域,由Docker管理文件目录(/var/lib/docker/volumes/)。非Docker进程不应该修改这些数据。卷是Docker中持久化数据的最好方式;

tmpfs mount

存于内存中,并不是持久化到磁盘。在容器的生命周期中,可以被容器用来存放非持久化的状态或敏感信息;

四、数据卷使用


bind mount

在使用bind mount可以使用-v或者--volume,这个参数在单容器的情况下使用,在swarm集群中使用--mount,从 Docker 17.06 之后,可以统一使用参数--mount。对于新接触 Docker的来说建议使用--mount,老司机可以继续使用-v,但是还是建议使用--mount。

语法

-v语法

分为三部分,使用冒号进行分割,排列的顺序不能发生变化,每个字段所表达的含是不同的;

  • 映射到宿主机文件的目录的地址;
  • 挂载到容器上的文件目录的地址;
  • 可选字段,用来增加附加项目,比如ro,rw等等;

--mount语法

由一组键值对组成,用逗号进行分割;

两者差别:

使用-v的时候,如果在 Docker Host 不存在要挂载的文件或者目录,Docker 将会自动进行创建,通常是一个目录;

使用--mount的时候,如果在 Docker Host 不存在要挂载的文件或者目录,Docker 不会自动创建目录,并生成一个错误;

使用案例

我们使用Nginx来讲解该案例;

  1. 后台方式启动一个版本为nginx:latest名字叫nginxvolumetest的容器,将容器内端口映射到宿主机9999端口,将宿主机~/Documents/app/docker映射到容器的/usr/share/nginx/html/下面;
docker run -d -it --name nginxvolumetest -p 9999:80 -v ~/Documents/app/docker:/usr/share/nginx/html/ nginx:latest

  1. 检查挂载目录;
docker inspect nginxvolumetest

  1. 进入宿主机对应的目录,在宿主机对应的目录下创建index.html,编辑文件,写入hello,dcoker bind mount!;
#进入宿主机对应的目录
~/Documents/app/docker
#宿主机在docker目录下创建index.html
touch index.html
#编辑文件
vim index.html
#插入
hello,dcoker bind mount!
  1. 进入容器内部,创建test.java文件,检查是否同步过来index.html;
#查看镜像ID
dcoker ps 
#进入容器内部
docker exec -it e240f6b77437 /bin/bash
#进入对应的目录
cd /usr/share/nginx/html/
#在对应目录下创建test.java文件
touch test.java
#查看对应目录下的文件
ls

  1. 查看宿主机对应下的目录文件;
  2. 在浏览器中访问http://localhost:9999/;
  3. 删除对应的docker容器;
docker stop e240f6b77437
docker rm e240f6b77437

-mount使用

#后台方式启动一个名字叫nginxmounttest的容器
#将容器内端口映射到宿主机9999端口
#将宿主机~/Documents/app/docker映射到/usr/share/nginx/html/
#版本为nginx:latest
docker run -d -it --name nginxmounttest -p 9999:80 --mount type=bind,source=/Users/wangtongzhou/Documents/app/docker,target=/usr/share/nginx/html/ nginx:latest
#进入容器内部
docker exec -it 7053db43219f /bin/bash
#查看文件内容
ls

从整个案例中我们看出本地的宿主机文件和docker内部文件是可以相互同步的,删除掉容器以后也不会影响到本地宿主机文件的内容。

只读挂载

  1. 删除之前容器;
docker stop 7053db43219f
docker rm 7053db43219f
  1. 后台方式启动版本为nginx:latest一个名字叫nginxmounttest的容器,将容器内端口映射到宿主机9999端口,将宿主机~/Documents/app/docker映射到容器的/usr/share/nginx/html/目录下,并且设置为只读;
docker run -d -it --name nginxmounttest -p 9999:80 --mount type=bind,source=/Users/wangtongzhou/Documents/app/docker,target=/usr/share/nginx/html/,readonly nginx:latest
#或者-v
docker run -d -it --name nginxvolumetest -p 9999:80 -v ~/Documents/app/docker:/usr/share/nginx/html/:ro nginx:latest
  1. 查询挂载详情;
docker inspect nginxmounttest

  1. 进入容器,创建aaa.java文件
touch aaa.java

readonly设置了只读权限,在容器中是无法对bind mount数据进行修改的。只有宿主机可以进行数据修改。

volume

volume由Docker来进行管理,比如volume的创建,可以使用命令 docker volume create 来创建一个 volume,当容器或者服务创建的时候,Docker 也可以自动的创建一个 volume。

当我们创建了一个volume,它存储在Docker宿主机的存储目录上。当把volume挂载入容器时,此目录就会同步挂载到容器中的目录。与bind mount同步方式一样,不同的是volume是由Docker来管理并且和Docker Host的核心功能进行隔离。

一个给定的volume可以同时挂载到多个容器中。我们在挂载volume时,可以进行命名,叫做具名挂载,也可以是默认随机生成的名字,叫做匿名挂载。当不指定名称的时候,Docker会用一个随机字符串对其进行命名,这样可以保证 volume的唯一性。

此外volume支持使用 volume drivers,允许将数据存储挂载到远程主机上。

语法

-v语法

与bind mount语法类似,在不指定主机地址的时候,就是采用volume的方式进行挂载,分为三部分:

  1. 指定卷的名称;
  2. 容器指定的挂载卷的地址;
  3. 可选字段,用来增加附加项目,比如ro,rw等等;

--mount语法

与bind mount语法类似,使用逗号分隔:

使用案例
  1. 创建名叫test卷;
docker volume test
  1. 进入test卷的_data目录该目录下无文件内容;
cd /var/lib/docker/volumes/test/_data
  1. 后台方式启动一个版本为nginx:latest名字叫nginxvolumetest的容器,将容器内端口映射到宿主机9999端口,source指定本地卷名称,target指定容器中的挂载的地址;
docker run -d -it -p 9999:80  --name nginxvolumetest --mount source=test,target=/usr/share/nginx/html nginx:latest
#或者-v命令
docker run -d -it -p 9999:80 --name nginxvolumetest -v test:/usr/share/nginx/html nginx:latest

  1. 查看容器的挂载详情;
docker inspect nginxvolumetest

  1. 访问localhost:9999;
  2. 再次进入进入test卷的_data目录 会发现文件内容;
cd /var/lib/docker/volumes/test/_data
  1. 在volume的文件中创建a.html;
touch a.html
  1. 进入到容器中 查看挂载目录中的文件;
docker ps
docker exec -it f24efa9063bc bash
ls

  1. 删除容器 会发现卷中的内容还存在;
docker stop f24efa9063bc
docker rm f24efa9063bc

tmpfs

tmpfs不在磁盘上持久存储,也不在 Docker Host 容器里面存储,他存储在host的内存中,它可以在容器的整个生命周期内被容器所使用。

语法

在单容器的情况下使用--tmpfs,并且不能指定参数,在集群的情况下使用--mount,可以指定一些参数;

使用

后台方式启动一个版本为nginx:latest名字叫nginxtmptest的容器,将容器内端口映射到宿主机9999端口,采用tmpfs使用卷,target指定容器中的挂载的地址;

docker run -d -it -p 9999:80 --name nginxtmptest --mount type=tmpfs,target=/usr/share/nginx/html nginx:latest

五、使用场景


bind mount
  1. 宿主机中的配置文件、开发环境、代码需要共享给宿主机上面的容器;
volume
  1. 多个正在运行的容器之间共享数据场景;
  2. 容器的数据永久存储在一个远程主机或者一个云服务器上;
  3. 当我们需要备份数据,或者恢复数据,或者需要把数据从一个宿主机迁移到另外一个宿主机的时候,我们可以将正在使用volume的容器停止下来,然后把volume的目录备份下来就可以了;
tmpfs

不需要将持久化的数据保留在宿主机或容器内使用tmpfs;

六、数据卷容器


如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门提供数据卷给其他容器挂载。复制卷始终具有相同的挂载点,数据卷的生命周期一直持续到没有容器使用它为止,类似于继承关系。

  1. 守护进程方式启动一个名字叫centos01共享目录为/data1版本为centos最近一个版本的容器;
docker run -d -it --name centos01 -v /data1 centos:latest
  1. 进入centos01容器内部;
#查看下容器id
docker ps 
#进入容器内部
docker exec -it ec09d368858f /bin/bash
  1. 进入目录data1,创建文件;
#查看文件目录
ls
#进入目录data1
cd data1
#创建文件
touch data01.txt
  1. 守护进程的方式启动一个名字为centos02共享容器数据卷centos01版本为centos最近一个版本的容器;
docker run -d -it --name centos02 --volumes-from centos01 centos:latest
  1. 进入centos02容器内部,检查文件目录是否存在data01.txt文件;
#进入容器内部
docker exec -it ec09d368858f /bin/bash
#进入data1
cd data1
#ls查看文件目录发现存在data01.txt文件
ls
  1. 进入centos02容器内部data1目录,在对应目录下创建data02.txt;
#在对应目录下创建data02.txt
touch data02.txt
  1. 再次进入centos01的容器进入data1目录,会发现data02.txt文件已经同步过来了;
cd data1
ls

七、总结


Docker将数据持久化的方式:

  1. docker cp命令将容器中的数据拷贝到宿主机上;
  2. 数据卷技术docker volume将容器内的数据映射到宿主机上;
  3. 数据卷容器docker --vlolumes-from使用特定的容器的数据卷,多个容器之间进行容器数据同步;
相关文章
|
17天前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
161 77
|
26天前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
4天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
39 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
10天前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
31 3
实战~如何组织一个多容器项目docker-compose
|
4天前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
19 4
|
19天前
|
数据建模 应用服务中间件 nginx
docker替换宿主与容器的映射端口和文件路径
通过正确配置 Docker 的端口和文件路径映射,可以有效地管理容器化应用程序,确保其高效运行和数据持久性。在生产环境中,动态替换映射配置有助于灵活应对各种需求变化。以上方法和步骤提供了一种可靠且易于操作的方案,帮助您轻松管理 Docker 容器的端口和路径映射。
63 3
|
26天前
|
存储 安全 数据安全/隐私保护
Docker 容器化应用管理更加高效,但数据安全和业务连续性成为关键。
在数字化时代,Docker 容器化应用管理更加高效,但数据安全和业务连续性成为关键。本文探讨了 Docker 应用的备份与恢复策略,涵盖备份的重要性、内容、方法及常见工具,制定备份策略,恢复流程及注意事项,并通过案例分析和未来趋势展望,强调备份与恢复在保障应用安全中的重要性。
33 2
|
26天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
67 7
|
26天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
32 5
|
26天前
|
开发框架 安全 开发者
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。本文探讨了 Docker 在多平台应用构建与部署中的作用,包括环境一致性、依赖管理、快速构建等优势,以及部署流程和注意事项,展示了 Docker 如何简化开发与部署过程,提高效率和可移植性。
57 4