Docker 存储卷
docker在运行时是基于分层镜像得联合挂载机制来实现的,而在这种分层构建镜像联合挂载并在最上层实现读写层的时候会发现一个特点,所有的有容器中的进程所生成的数据都是被最上面的可写层所保存而这个可写层本身并不属于镜像层而属于当前容器,它属于容器内部的组件。
1、生命周期,Data Volume,存储卷
容器的生命周期随着启动而创建,随着停止而结束(比如我们系统上运行ls,我们在系统上运行ls的命令就相当于在系统上创建了一个进程,这个进程从你输入ls回车开始、输出内容结束,这个就是进程的生命周期,从你创建进程开始到进程退出结束任务完成而终止,在比如我们vim打开编辑器输入文本,系统会运行一个vim进程,当我们输入文本wq保存退出时vim进程终止,容器启动时加上--rm选项容器停止就会被直接删除,但是此前如果这个进程创建了数据默认在可写层,如果你一旦把容器删掉,它此前生成的数据将不存在,为了保存该容器的数据,我们可以将容器的可写层的数据挂载到宿主机,当容器删除数据依然存在,可直接使用数据去创建新的容器,这样数据可以脱离于容器的生命周期而存在,这种机制就叫做存储卷)
2、存储卷是什么,为什么要做存储卷
Docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像层并在镜像栈顶部添加一个读写层
如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件得只读版本以然存在,只是已经被读写层中该文件得副本所隐藏,此即“写时复制(cow)”机制
关闭并重启容器,其数据不受影响;但删除docker容器,则其更改将会全部丢失
存在问题:
a、存储于联合文件系统中,不易于宿主机访问
b、容器间数据共享不便
c、删除容器数据会丢失
解决方案:“卷(volume)”
卷是容器上的一个或多个目录,此类目录可绕过联合文件系统,与宿主机上的某目录“绑定(关联)”
3、存储卷的类型
a、绑定挂载卷Bind mount volume
绑定挂在卷是指在宿主机上的目录是用户指定的,在容器中的目录也是用户指定的
绑定挂载卷例子:
[root@bogon ~]# mkdir /data/volumes/v1 -p //在宿主机上创建一个挂载卷目录
[root@bogon ~]# docker run --name mbbox5 -it -v /data/volumes/v1:/mydata busybox //运行容器时指定存储卷
/ # ls /mydata //查看目录
[root@bogon ~]# cd /data/volumes/v1 //宿主机进入挂载卷目录
[root@bogon v1]# ls
[root@bogon v1]# echo hello > my.txt //写个文件容器中查看mydata下面的文件
/ # ls
bin dev etc home mydata proc root sys tmp usr var
/ # cat /mydata/my.txt
hello
/ # exit //退出容器
[root@bogon ~]# docker rm mbbox5 //删除容器去查看存储卷
mbbox5
[root@bogon ~]# cd /data/volumes/v1 //进入挂载卷目录
[root@bogon v1]# cat my.txt //查看文件
hello我们用现有数据去挂载启动一个新的容器
[root@bogon ~]# docker run --name mbbox7 -it -v /data/volumes/v1:/my/data busybox //用存储卷的目录直接运行新的容器
/ # cd /my/data/
/my/data # ls
my.txt
/my/data # cat my.txt //查看宿主机的文件在容器中是否存在
hello所以说存储卷可以脱离容器的生命周期而存在
b、docker管理卷 docker
管理卷是指容器中的目录是用户指定的,宿主机上的目录是固定目录下自动生成的
docker管理卷例子:
[root@bogon ~]# docker run --name mbbox5 -it -v /mydata busybox //启动容器时创建存储卷
/ # ls
bin dev etc home mydata proc root sys tmp usr var[root@bogon ~]# docker container inspect mbbox5 //查看mbbox5的详细信息
[{"Id": "cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545","Created": "2020-08-10T08:04:42.474604567Z","Path": "sh","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 45098,"ExitCode": 0,"Error": "","StartedAt": "2020-08-10T08:04:42.80629229Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:018c9d7b792b4be80095d957533667279843acf9a46c973067c8d1dff31ea8b4","ResolvConfPath": "/var/lib/docker/containers/cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545/resolv.conf","HostnamePath": "/var/lib/docker/containers/cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545/hostname","HostsPath": "/var/lib/docker/containers/cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545/hosts","LogPath": "/var/lib/docker/containers/cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545/cd837a3cfaa7d0e7b771c6b41215edce8382c18d838e0eafc04d132290043545-json.log","Name": "/mbbox5","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": true,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"Capabilities": null,"Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/5664a3a82d7c9db1e732cd347dd3dcbe1bf182bfd9b84b1a87eb4b0d0f9ec303-init/diff:/var/lib/docker/overlay2/bb945e3d5f5421c019f8022b69070c014e1d842466a3ee2e7a464ef09494f723/diff","MergedDir": "/var/lib/docker/overlay2/5664a3a82d7c9db1e732cd347dd3dcbe1bf182bfd9b84b1a87eb4b0d0f9ec303/merged","UpperDir": "/var/lib/docker/overlay2/5664a3a82d7c9db1e732cd347dd3dcbe1bf182bfd9b84b1a87eb4b0d0f9ec303/diff","WorkDir": "/var/lib/docker/overlay2/5664a3a82d7c9db1e732cd347dd3dcbe1bf182bfd9b84b1a87eb4b0d0f9ec303/work"},"Name": "overlay2"},"Mounts": [{"Type": "volume","Name": "d79e92f534c136d505a27725a2373795bfe892daf95ad6b9f9b85b2d3708e5f4","Source": "/var/lib/docker/volumes/d79e92f534c136d505a27725a2373795bfe892daf95ad6b9f9b85b2d3708e5f4/_data", //宿主机具体目录"Destination": "/mydata", //容器的具体目录"Driver": "local","Mode": "","RW": true,"Propagation": ""}],"Config": {"Hostname": "cd837a3cfaa7","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["sh"],"Image": "busybox","Volumes": {"/mydata": {}},"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "f3037bba96a253e86ab0ddf9fabeaa2207d672b54afba1c486297065618342f3","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/f3037bba96a2","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "3c95f4051dcbd4b5d9b21135689d718482fd11ff20a5fc36097459b3d27cd3bc","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "c0abba7360378d6a7cf08213748f59c6330f3688c8731c0672069926279c5a6a","EndpointID": "3c95f4051dcbd4b5d9b21135689d718482fd11ff20a5fc36097459b3d27cd3bc","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
][root@bogon ~]# cd /var/lib/docker/volumes/d79e92f534c136d505a27725a2373795bfe892daf95ad6b9f9b85b2d3708e5f4/_data //我们cd到宿主机的目录
[root@bogon _data]# vi test.txt //在宿主机的目录中编辑一个文件
[root@bogon _data]# cat test.txt //查看文件
aaa
bbb
ccc
ddd我们切换至容器内部去查看这个文件
/ # ls
bin dev etc home mydata proc root sys tmp usr var
/ # cat mydata/test.txt
aaa
bbb
ccc
ddd
/mydata # exit //退出docker容器在宿主机上查看卷是否被删除:
[root@bogon ~]# cat /var/lib/docker/volumes /d79e92f534c136d505a27725a2373795bfe892daf95ad6b9f9b85b2d3708e5f4/_data/text.txt
aaa
bbb
ccc
ddd注意:这种方式相当于打通了一个通道可以让宿主机和容器之间任意传输文件
4、容器之间使用同一个卷去共享数据
可以共享:NET、IPC、UTS
不能共享:Mount、User、Pid
[root@bogon ~]# mkdir /data/volumes/v1 -p //在宿主机上创建一个挂载卷目录
[root@bogon ~]# cd /data/volumes/v1 //宿主机进入挂载卷目录
[root@bogon v1]# ls
[root@bogon v1]# echo hello > my.txt //写个文件
[root@bogon ~]# docker run --name mbbox7 -it -v /data/volumes/v1:/my/data busybox //运行mbbox7容器
/ # cd /my/data/
/my/data # ls
my.txt
/my/data # cat my.txt
hello[root@bogon v1]# docker run --name mbbox8 -it --rm --volumes-from mbbox7 busybox //运行mbbox8容器去复制mbbox7容器的卷
/ # ls
bin dev etc home my proc root sys tmp usr var
/ # cd my/data/
/my/data # ls
my.txt
/my/data # cat my.txt
hello
因此这个卷中的数据就可以实现容器共享了
Docker 存储卷相关推荐
- Docker存储卷简述和测试
Docker存储卷 文章目录 Docker存储卷 COW机制 什么是存储卷 使用存储卷的好处 为什么要用存储卷 存储卷管理方式 存储卷的分类 容器数据管理 COW机制 Docker镜像由多个只读层叠加 ...
- Docker存储卷volume(V18.X)
文章目录 1. 简介 1.1 介绍 1.2 作用 1.3 分类 2. 存储卷使用 2.1 设置卷的命令 2.1.1 -v或`--volume`选项指定卷 2.1.2 `--mount`指定卷 2.1. ...
- Docker存储卷(V18.X)
Docker存储卷(V18.X) 原文: Docker存储卷(V18.X) 简介 介绍 Docker的存储卷称之为volume,本质上容器上的一个或者多个目录,而这些目录绕过了联合文件系统,与宿主机中 ...
- Docker 学习6 Docker存储卷
一.什么是存储卷 二.为什么要用到数据卷 三.数据卷是怎么被管理的 四.存储卷种类 五.在容器中使用存储卷 1.只声明容器路径 [root@localhost docker]# docker run ...
- docker存储卷篇
在之前的文章中,我们说过,容器的服务如果需要提供给外部访问,需要把端口映射出来.docker的数据存储卷也是一样的道理,我们在使用docker的时候,有些应用是需要保存数据的,这些需要保存数据的应用就 ...
- Docker存储卷基本操作
简介 Docker镜像是由多个只读层添加而成,启动容器时,Docker加载值读镜像层并在镜像栈顶部添加一个读写层. 如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会在读写层下面的只读层复 ...
- docker存储卷的使用
COW技术原理(Copy On Write,写时复制) Ø 直接映射原始盘的数据内容 Ø 当原始盘的旧数据有修改时,在修改之前自动将旧数据存入前端盘 Ø 对前端盘的修改不回写到原始盘 Docker镜像 ...
- Docker存储卷(Volume)
简介 想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的.Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载只读镜像层 ...
- docker修改镜像的存储位置_云原生存储详解:容器存储与 K8s 存储卷(内含赠书福利)...
作者 | 阚俊宝 阿里巴巴技术专家 参与文末留言互动,即有机会获得赠书福利! 导读:云原生存储详解系列文章将从云原生存储服务的概念.特点.需求.原理.使用及案例等方面,和大家一起探讨云原生存储技术新 ...
最新文章
- python tkinter 布局_python tkinter学习——布局
- XAMPP 相关设置(linux下的)
- 基于KNN的相关内容推荐
- Android Prelink
- python3报错:importError: dynamic module does not define module export function (PyInit_cv_bridge_boost
- leetcode算法题--替换空格
- Windows程序设计之创建窗口示例
- JQueryDOM之创建节点
- MAC安装linux双系统
- VS2008 调试windows服务项目
- 苹果/安桌点歌系统代码
- AD9的PCB技巧——环形焊盘的封装
- LYNC 2010 中文测试版已经可以下载
- Redis原理(Replication、Sentinel、Twemproxy、RedisCluster)
- Qt在VS中的使用方法详解
- 使用lgb.cv时出现ValueError: Supported target types are: (‘binary‘, ‘multiclass‘). Got ‘continuous‘ instea
- 常用软件密码破解完全指南[转]
- vscode如何一键生成vue模板
- 一个有成就感又有挫败感的日子
- github上star42.4K的开源电商平台
热门文章
- Android平台 Target API level 升级到 31,在Android 12上启动黑屏卡死
- 【JavaSE】abstract 抽象类 快到碗里来 (◕ᴗ◕✿)
- JAVA-乐观锁更新失败或业务异常后接口重试
- 搜索引擎常用搜索技巧
- 我的2022和2023(技术总结、开发工具简介和未来展望)
- 在智能制造背景下,MES有哪些发展趋势?
- ORACLE 12C EM 端口5500关闭及如何修改默认端口
- 矩阵切换器有哪些控制方式,有什么好处
- intel 服务器最新cpu,英特尔发布至强 Xeon W-3300 系列服务器处理器:最高 38 核
- 使用mac聚焦搜索无法搜索软件的情况