Docker存储卷篇
Docker存储卷篇
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.写时复制(COW)机制
所谓写时复制的效果如上图所示:
Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。
如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本依然存在,只是已经被读写层中该文件的副本所隐藏,此即"读写复制(COW)"机制。
二.数据卷(Data Volume)概述
1>.什么是存储卷(volume)
关闭并重启容器,其数据不受影响;但删除Docker容器,则其更改将会全部丢失。原因就是我们上面提到的写时复制机制,这个写时复制机制存在于容器,数据默认都保存在容器内。 Docker设计存在的问题:
1>.存储于联合文件系统中,不易于宿主机访问;
2>.容器间数据共享不便;
3>.删除容器其数据会丢失; 解决方案:"存储卷(volume)"
如下图所示:"卷"是容器上的一个或多个"目录",此类目录可绕过联合文件系统,于宿主机上的某个目录"绑定(关联)"
2>.存储卷(volume)的作用
1.数据卷为持久或共享数据提供了几个有用的特性:
1>.Volume于容器(container)初始化之时即会创建,由base image提供的卷中的数据于此期间完成复制;
2>.数据卷可以在容器之间共享和重用;
3>.更新镜像(image)时不会包括对数据卷的更改;
4>.即使容器(container)自身被删除,数据卷仍保持不变。 2.Volume的初衷是独立于容器的生命周期实现数据持久化:
1>.默认情况下删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作;
2>.如果我们删除容器时使用了特殊的选项(类似于linux的"userdel -r"选项)也可以一并删除容器的存储卷,但是生成环境我们不会这样做。 3.卷为docker提供了独立于容器的数据管理机制(如下图所示):
1>.可以把"镜像"想像成静态文件,例如"程序",把卷类比为动态内容,例如"数据";于是,镜像可以重用,而卷可以共享;
2>.卷实现了"程序(镜像)"和"数据(卷)"分离,以及"程序(镜像)"和"制作镜像的主机"分离,用户制作镜像时无须再考虑镜像运行的容器所在的主机的环境;
3>.docker存储卷类型(Volume types)
如下图所示,Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但其在宿主机上的位置有所不同:
1>.绑定挂载卷(Bind mount volume)
指向主机文件系统上用户指定位置的卷。换句话说,在宿主机上的路径你需要人工指定一个特定路径,再容器上的路径也需要指定一个特定路径,让这两个已知路径建立关联关系。随着容器删除,存储卷数据并不会丢失。 2>.docker管理的卷(Docker managed volume)
Docker守护进程在Docker拥有的主机文件系统的一部分中创建管理卷。换句话说,我们只需要在容器内指定挂载点是什么,而绑定的是宿主机哪个路径下的目录我们不需要管,由容器引擎的docker daemon自行创建一个空目录或者使用一个已存在目录与你的存储卷路径建立关联关系。随着容器删除,存储卷数据也随着丢失了。
三.在容器这种使用Volumes
1>.Docker managed volume案例
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it --rm busybox
/ # ls /
bin dev etc home proc root sys tmp usr var
/ #
/ # exit
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it -v /data --rm busybox #注意,我们使用"-v"选项来指定c1容器内docker管理卷存放为位置,而具体对应宿主机的哪个路径我们无需关心,而是由docker daemon进程自行创建,我们可以通过相关命令查看对应的具体路径。
/ #
/ # ls / #很上面的容器相比,很显然,咱们这个容器多出了一个"/data"目录,该目录即为docker managed volume实例。
bin data dev etc home proc root sys tmp usr var
/ #
[root@node101.yinzhengjie.org.cn ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d574ca3e42a6 busybox "sh" minutes ago Up minutes c1
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker inspect c1 #查看c1容器的详细信息,注意观察keys为"Mounts"的"Source"属性对应的值,它所指向的路径就是c1容器"/data"目录所在宿主机的存储路径。
[
{
"Id": "d574ca3e42a6cc08e009ba44b3c7bcd467362ff10c71d9461211a7e9687e2c09",
"Created": "2019-10-19T01:12:06.848411027Z",
"Path": "sh",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": ,
"ExitCode": ,
"Error": "",
"StartedAt": "2019-10-19T01:12:07.402652338Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:19485c79a9bbdca205fce4f791efeaa2a103e23431434696cc54fdd939e9198d",
"ResolvConfPath": "/var/lib/docker/containers/d574ca3e42a6cc08e009ba44b3c7bcd467362ff10c71d9461211a7e9687e2c09/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/d574ca3e42a6cc08e009ba44b3c7bcd467362ff10c71d9461211a7e9687e2c09/hostname",
"HostsPath": "/var/lib/docker/containers/d574ca3e42a6cc08e009ba44b3c7bcd467362ff10c71d9461211a7e9687e2c09/hosts",
"LogPath": "/var/lib/docker/containers/d574ca3e42a6cc08e009ba44b3c7bcd467362ff10c71d9461211a7e9687e2c09/d574ca3e42a6cc08e009ba4
4b3c7bcd467362ff10c71d9461211a7e9687e2c09-json.log", "Name": "/c1",
"RestartCount": ,
"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":
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": ,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": ,
"Runtime": "runc",
"ConsoleSize": [
, ],
"Isolation": "",
"CpuShares": ,
"Memory": ,
"NanoCpus": ,
"CgroupParent": "",
"BlkioWeight": ,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": ,
"CpuQuota": ,
"CpuRealtimePeriod": ,
"CpuRealtimeRuntime": ,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": ,
"KernelMemoryTCP": ,
"MemoryReservation": ,
"MemorySwap": ,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": ,
"CpuPercent": ,
"IOMaximumIOps": ,
"IOMaximumBandwidth": ,
"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/b91e241fd4070485ceb246e18c2d258df9666797453448b287e4253e6a5bc437-init/diff:/var/l
ib/docker/overlay2/ead7a29001855b8898300b67763a050eeb50e5c7988076f4777b56e85365169e/diff", "MergedDir": "/var/lib/docker/overlay2/b91e241fd4070485ceb246e18c2d258df9666797453448b287e4253e6a5bc437/merged",
"UpperDir": "/var/lib/docker/overlay2/b91e241fd4070485ceb246e18c2d258df9666797453448b287e4253e6a5bc437/diff",
"WorkDir": "/var/lib/docker/overlay2/b91e241fd4070485ceb246e18c2d258df9666797453448b287e4253e6a5bc437/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914",
"Source": "/var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data", #注意观察这里,这就是我们c1容器"/data"存储卷对应的宿主机路径。
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "d574ca3e42a6",
"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": {
"/data": {}
},
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "7fcfdb3cbc2d42503fbd9f44d4c9606ee484cedc26d88f7c5c7a7934efb82be5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": ,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/7fcfdb3cbc2d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "d81e297a392c3f6c73422ddb016b9c126a8f50ace798920947d331cea3c9baa0",
"Gateway": "192.168.100.254",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": ,
"IPAddress": "192.168.100.1",
"IPPrefixLen": ,
"IPv6Gateway": "",
"MacAddress": "02:42:c0:a8:64:01",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "7ad23e4ff4b3bbaa8cea6b89507921beb407568e021f3dad666a829ec817be7e",
"EndpointID": "d81e297a392c3f6c73422ddb016b9c126a8f50ace798920947d331cea3c9baa0",
"Gateway": "192.168.100.254",
"IPAddress": "192.168.100.1",
"IPPrefixLen": ,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": ,
"MacAddress": "02:42:c0:a8:64:01",
"DriverOpts": null
}
}
}
}
]
[root@node101.yinzhengjie.org.cn ~]# cd /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data #我们进入到c1容器对应"/data"目录在宿主机的路径,就可以实现c1容器和宿主机数据共享。
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]#
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]# ls
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]#
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]# echo "hello container" >> test.html
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]#
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]# ls
test.html
[root@node101.yinzhengjie.org.cn /var/lib/docker/volumes/3fc67ccb38ce00fb1257950e77ad71b5b01fc0d53f6959eda1e810e970153914/_data]#
[root@node101.yinzhengjie.org.cn ~]# docker inspect c1 #查看c1容器的详细信息,注意观察keys为"Mounts"的"Source"属性对应的值,它所指向的路径就是c1容器"/data"目录所在宿主机的存储路径。
2>.Bind mount volume案例
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it --rm busybox
/ #
/ # ls /
bin dev etc home proc root sys tmp usr var
/ #
/ # exit
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it -v /data/volumes/c1:/data2 --rm busybox #和上面有所不同,我们手动指定宿主机"/data/volumes/c1"(该路径会自动创建)路径和c1容器的"/data2"路径建立关联关系
/ #
/ # ls / #注意,和上面的容器相比,当前容器多出来了一个"/data2"目录,该目录是咱们手动指定的"bind mount volume"卷。
bin data2 dev etc home proc root sys tmp usr var
/ #
[root@node101.yinzhengjie.org.cn ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d6992f8321d busybox "sh" About a minute ago Up About a minute c1
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker inspect c1 #查看c1容器的详细信息,注意观察keys为"Mounts"的"Source"属性对应的值
[
{
"Id": "8d6992f8321d04bbab860550f9d48e9b37c8989052a6f671ebfbe66543f549ad",
"Created": "2019-10-19T01:30:45.806381621Z",
"Path": "sh",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": ,
"ExitCode": ,
"Error": "",
"StartedAt": "2019-10-19T01:30:46.253664572Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:19485c79a9bbdca205fce4f791efeaa2a103e23431434696cc54fdd939e9198d",
"ResolvConfPath": "/var/lib/docker/containers/8d6992f8321d04bbab860550f9d48e9b37c8989052a6f671ebfbe66543f549ad/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/8d6992f8321d04bbab860550f9d48e9b37c8989052a6f671ebfbe66543f549ad/hostname",
"HostsPath": "/var/lib/docker/containers/8d6992f8321d04bbab860550f9d48e9b37c8989052a6f671ebfbe66543f549ad/hosts",
"LogPath": "/var/lib/docker/containers/8d6992f8321d04bbab860550f9d48e9b37c8989052a6f671ebfbe66543f549ad/8d6992f8321d04bbab86055
0f9d48e9b37c8989052a6f671ebfbe66543f549ad-json.log", "Name": "/c1",
"RestartCount": ,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [
"/data/volumes/c1:/data2"
],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount":
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": ,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": ,
"Runtime": "runc",
"ConsoleSize": [
, ],
"Isolation": "",
"CpuShares": ,
"Memory": ,
"NanoCpus": ,
"CgroupParent": "",
"BlkioWeight": ,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": ,
"CpuQuota": ,
"CpuRealtimePeriod": ,
"CpuRealtimeRuntime": ,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": ,
"KernelMemoryTCP": ,
"MemoryReservation": ,
"MemorySwap": ,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": ,
"CpuPercent": ,
"IOMaximumIOps": ,
"IOMaximumBandwidth": ,
"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/3b5c1e2681b83025782d55c671c56e94028d17febc0058e621fdb3d2816c3de8-init/diff:/var/l
ib/docker/overlay2/ead7a29001855b8898300b67763a050eeb50e5c7988076f4777b56e85365169e/diff", "MergedDir": "/var/lib/docker/overlay2/3b5c1e2681b83025782d55c671c56e94028d17febc0058e621fdb3d2816c3de8/merged",
"UpperDir": "/var/lib/docker/overlay2/3b5c1e2681b83025782d55c671c56e94028d17febc0058e621fdb3d2816c3de8/diff",
"WorkDir": "/var/lib/docker/overlay2/3b5c1e2681b83025782d55c671c56e94028d17febc0058e621fdb3d2816c3de8/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "bind",
"Source": "/data/volumes/c1",
"Destination": "/data2",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
"Config": {
"Hostname": "8d6992f8321d",
"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": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "5a5cc75df84d9544f2bcb17d7d155caac3bb70a850b44dd7a7dbafbe9affda69",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": ,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/5a5cc75df84d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "b67ad92c10b5d239071a18f43b17a14a06f15ac4e39bd82f6c0eb8285f1b56f2",
"Gateway": "192.168.100.254",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": ,
"IPAddress": "192.168.100.1",
"IPPrefixLen": ,
"IPv6Gateway": "",
"MacAddress": "02:42:c0:a8:64:01",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "7ad23e4ff4b3bbaa8cea6b89507921beb407568e021f3dad666a829ec817be7e",
"EndpointID": "b67ad92c10b5d239071a18f43b17a14a06f15ac4e39bd82f6c0eb8285f1b56f2",
"Gateway": "192.168.100.254",
"IPAddress": "192.168.100.1",
"IPPrefixLen": ,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": ,
"MacAddress": "02:42:c0:a8:64:01",
"DriverOpts": null
}
}
}
}
]
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# ls /data/volumes/c1/
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker inspect c1 #查看c1容器的详细信息,注意观察keys为"Mounts"的"Source"属性对应的值
[root@node101.yinzhengjie.org.cn ~]# docker inspect -f {{.Mounts}} c1 #我们不用获取c1的全部信息,比如我们只需要获取"Mounts"的概要属性。
[{bind /data/volumes/c1 /data2 true rprivate}]
[root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# docker inspect -f {{.NetworkSettings.IPAddress}} c1 #同理,我们也可以按照这种方式取出其它咱们想要的信息
192.168.100.1
[root@node101.yinzhengjie.org.cn ~]#
四.共享卷(Sharing volumes)
1>.多个容器使用同一个存储卷案例(咱们试验只是使用两个容器,实际上只要资源充足的情况下你可以启动任意个容器共享存储卷)
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it -v /data/volumes/c1:/data --rm busybox #我们创建一个C1容器,并在/data目录中写入测试数据,该容器不要停止它,在重新开启一个终端运行另外一个容器,来和c1容器共享存储卷数据。
/ #
/ # ls /
bin data dev etc home proc root sys tmp usr var
/ #
/ # ls /data/
/ #
/ # echo "<h1>docker container test</h1>" > /data/index.html
/ #
/ # ls /data/
index.html
/ #
/ #
/ # cat /data/index.html
<h1>docker container test</h1>
/ #
[root@node101.yinzhengjie.org.cn ~]# docker run --name c1 -it -v /data/volumes/c1:/data --rm busybox #我们创建一个C1容器,并在/data目录中写入测试数据,该容器不要停止它,在重新开启一个终端运行另外一个容器,来和c1容器共享存储卷数据。
[root@node101.yinzhengjie.org.cn ~]# docker run --name c2 -it -v /data/volumes/c1:/data --rm busybox #通过测试发现,c2和c1虽然不是同一个容器且各自由独立的用户空间,但它们却可以通过存储卷来实现数据共享。
/ #
/ # ls /
bin data dev etc home proc root sys tmp usr var
/ #
/ # ls /data/
index.html
/ #
/ # cat /data/index.html
<h1>docker container test</h1>
/ #
2>.复制使用其它容器的卷
[root@node101.yinzhengjie.org.cn ~]# docker run --name InfrastructureImage -it -v /data/InfrastructureImage/volumes:/data/web/html busybox #此处启动一个基础镜像
/ #
/ # ls /
bin data dev etc home proc root sys tmp usr var
/ # / # ls /data/ -R
/data/:
web /data/web:
html /data/web/html:
/ #
/ #
/ # ifconfig
eth0 Link encap:Ethernet HWaddr ::C0:A8::
inet addr:192.168.100.1 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B) lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B) / #
[root@node101.yinzhengjie.org.cn ~]# docker run --name InfrastructureImage -it -v /data/InfrastructureImage/volumes:/data/web/html busybox #此处启动一个基础镜像
[root@node101.yinzhengjie.org.cn ~]# docker run --name nginx --network container:InfrastructureImage --volumes-from InfrastructureImage -it busybox #此处使用"InfrastructureImage"的容器存储卷配置信息。
/ #
/ # ifconfig
eth0 Link encap:Ethernet HWaddr ::C0:A8::
inet addr:192.168.100.1 Bcast:192.168.100.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B) lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU: Metric:
RX packets: errors: dropped: overruns: frame:
TX packets: errors: dropped: overruns: carrier:
collisions: txqueuelen:
RX bytes: (0.0 B) TX bytes: (0.0 B) / #
/ # ls /data/ -R
/data/:
web /data/web:
html /data/web/html:
/ #
/ #
Docker存储卷篇的更多相关文章
- Docker系列05—Docker 存储卷详解
本文收录在容器技术学习系列文章总目录 1.存储卷介绍 1.1 背景 (1)docker 的 AFUS 分层文件系统 docker镜像由多个只读层叠加面成,启动容器时,docker会加载只读镜像层并在镜 ...
- 6、Docker存储卷
Why Data Volumes? 来自马哥教育 Data volumes Volume types 绑定挂载卷:在宿主机和容器上各指明绑定路径才能进行绑定. docker管理卷:在容器内指定挂载 ...
- Docker存储卷(V18.X)
简介 介绍 Docker的存储卷称之为volume,本质上容器上的一个或者多个目录,而这些目录绕过了联合文件系统,与宿主机中的目录或者其他容器目录进行了绑定关系,这种绑定关系可以看作Linux的mou ...
- Docker存储卷
六.Docker 存储卷(volume) COW:写时复制 Bind mount volume:手动mount绑定的卷 # docker run --name centos-3 -it -v /dat ...
- docker 存储卷 Volumes
一,docker容器面临的困境: 容器运行中产生的数据,是放到容器栈的最顶层,当容器停止并被删除后,这些数据就被删除了. docker采用COW(写时复制)策略,导致性能低下.比如有个mysql容器, ...
- Docker 学习6 Docker存储卷
一.什么是存储卷 二.为什么要用到数据卷 三.数据卷是怎么被管理的 四.存储卷种类 五.在容器中使用存储卷 1.只声明容器路径 [root@localhost docker]# docker run ...
- 5.Docker存储卷
一.概述 1.Docker底层存储机制 Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层. 如果运行中的容器修改了现有的一个已经存在的文件,那 ...
- Docker系列03—Docker 存储卷
一.存储卷介绍 1.1 背景 Docker 的 AFUS 分层文件系统 docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像层并在镜像栈顶部加一个读写层: 如果运行的容器修改了 ...
- docker 第五篇 存储
镜像概述复习 Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层 如果运行中的容器修改了现有的一个已经存在的文件,那改文件将会从读写层下面的只读 ...
随机推荐
- matlab学习笔记13_2匿名函数
一起来学matlab-matlab学习笔记13函数 13_2 匿名函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://ww2.mathworks.cn/help/m ...
- Java之数组类型
如果我们有一组类型相同的变量.例如,5位同学的成绩,可以这么写 public class Main { public static void main(String[] args) { // 5位同学 ...
- c++动态链接问题
https://blog.csdn.net/liu0808/article/details/81169173 https://blog.csdn.net/f110300641/article/deta ...
- hbase 安装(集群模式)
环境:jdk 1.8 + hadoop2.7.6+zookeeper3.4.9+centos7 一.安装zookeeper(集群模式) 0.安装机器 ip ...
- 使用Docker快速搭建Zookeeper和kafka集群
使用Docker快速搭建Zookeeper和kafka集群 镜像选择 Zookeeper和Kafka集群分别运行在不同的容器中zookeeper官方镜像,版本3.4kafka采用wurstmeiste ...
- SQL - 外链接和内连接
外链接和内连接: leetcode 题目:编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息: 第一次的答案:(错误) select ...
- adb devices命令链接设备失败 解决办法
使用adb devices命令链接设备失败 1,检查adb的环境配置是否存在问题 参见我的博客(sdk配置):https://www.cnblogs.com/changpuyi/p/9459025.h ...
- Unity 新手引导
根据Shader动态生成遮罩 源码地址 圆形遮罩镂空处理脚本: using System; using System.Collections.Generic; using UnityEngine; u ...
- Python实现堆
堆 (heap) 是一种经过排序的完全二叉树,其中任一非叶子节点的值均不大于(或不小于)其左孩子和右孩子节点的值. 注:定义来自百度百科. 堆,又被为优先队列(priority queue).尽管名为 ...
- 未安装发布所需的web发布扩展
解决方案:需要安装web deploy 下载网站:https://www.iis.net/downloads/microsoft/web-deploy 假如还是打不开的话,估计时打开方式错误了, 要用 ...