Volume
Volume是容器数据卷。我们经常创建删除一些容器,但有时候需要保留容器中的一些数据,这时候就用到了Volume。它也是容器之间数据共享的技术,可以将容器中产生的数据同步到本地。实际就是把容器中的目录挂载到运行着容器的服务器或个人电脑上。
挂载命令-v
第一种挂载volume的方式是通过命令-v
来挂载。
指定路径挂载
类似于-p 主机端口:容器内端口
,-v
也是-v 主机目录:容器内目录
。这种方式是指定路径挂载。
在主机建一个/mainHome目录,我有一个centos镜像,用它跑起一个容器来,将容器的/home目录映射到主机/mainHome目录。
root@KitDevVps:~# mkdir mainHome
root@KitDevVps:~# pwd
/root
root@KitDevVps:~# docker run -it -v /root/mainHome:/home centos /bin/bash
[root@b486ed5aa77f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@b486ed5aa77f /]# cd /home/
[root@b486ed5aa77f home]# ls
[root@b486ed5aa77f home]# touch test.txt
[root@b486ed5aa77f home]# ls
test.txt
[root@b486ed5aa77f home]# exit
exit
root@KitDevVps:~# ls /root/mainHome/
test.txt
可以看到映射之后,我进入容器内,在它的/home下创建了一个test.txt,退出容器回到主机的/root/mainHome下,发现也已经有了一个test.txt文件。
目前我们了解了修改容器内文件可以让容器外面挂载到的目录出现变化。我们尝试在容器外编辑这个test.txt文件,然后进容器内查看。虽然我们基本已经清楚这是多此一举,但还是尝试一下。
root@KitDevVps:~# cd /root/mainHome/
root@KitDevVps:~/mainHome# vim test.txt
root@KitDevVps:~/mainHome# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b486ed5aa77f centos "/bin/bash" 5 minutes ago Exited (0) 4 minutes ago boring_cerf
242fdc2bba7d centos "-it /bin/bash" 6 minutes ago Created optimistic_dubinsky
1cdd55fd90c5 nginx "/docker-entrypoint.…" 11 hours ago Up 7 hours 0.0.0.0:80->80/tcp nginx1
7d2fd4e741ba hello-world "/hello" 13 hours ago Exited (0) 13 hours ago elastic_goldstine
root@KitDevVps:~/mainHome# docker start b486ed5aa77f
b486ed5aa77f
root@KitDevVps:~/mainHome# docker exec -it b486ed5aa77f /bin/bash
[root@b486ed5aa77f /]# cat /home/test.txt
Hello Volume!
可以看到容器内的test.txt的内容也随之发生了变化。而且我们之前exit
时,实际上容器就已经stop了,我们是在容器停止之后修改了本机的test.txt文件,重新运行起容器,发现容器内的test.txt文件也发生了变化。可以说是非常灵活。
注意,如果运行容器时没有使用-d,没有让其后台运行,在容器内时,可以使用ctrl+p+q来退出容器,此时容器依旧会在运行,使用exit退出,我预计它不会运行,但容器也会继续运行。这一块跟我前面结果有出入,让我摸不到头脑。后面我又有一次没有-d,exit后容器stop了,ctrl+p+q没有stop。-d后exit容器也没有stop。现在的结论就是:
- 没有-d,使用exit,容器会stop
- 没有-d,使用ctrl+p+q,容器不会stop
- 没有-d,使用exit退出,容器stop,再使用
docker start 容器名
启动,容器依旧会在后台运行 - 没有-d,使用ctrl+p+q退出,容器不会stop
- 有-d,使用exit,容器不会stop
- 有-d,使用ctrl+p+q,容器不会stop
- 有-d,使用exit退出,容器stop,再使用
docker start 容器名
启动,容器依旧会在后台运行,使用ctrl+p+q - 有-d,使用ctrl+p+q退出,容器不会stop
可以使用docker inspect <容器id>
来查看容器详细信息,其中会包括卷挂载的目录等。
如果我想用docker搞一个nginx,又不想一遍一遍地进入容器修改配置文件,因为我可能随时删除容器。此时就可以用这种方式。每次运行新容器,只需要把主机存放配置文件的目录挂载到容器存放配置文件的目录即可。因为即使删掉容器,主机的目录和里面的内容不会丢失。
注意:可以同时挂载多个目录,格式:-v 主机目录1:容器内目录1 -v 主机目录2:容器内目录2 -v...
如果只写-v 容器内目录
,是匿名挂载的格式,会自动在主机生成目录。
docker volume ls
是查看所有本机的卷的指令,可以用docker volume --help
来查看更多用法。
root@KitDevVps:~# docker volume ls
DRIVER VOLUME NAME
local sqlvolume
不知道为什么,竟然不显示之前我挂载的mainHome,可能是那个只是目录的映射,不是卷,用docker volume create
创建出来的才是卷。
尝试一下匿名挂载和具名挂载:
具名挂载
具名挂载的命令:-v 卷名:容器内路径
。卷名前面如果加上个“/”,就会变成指定路径挂载。注意区分。
具名挂载:
root@KitDevVps:~# docker run -d -P --name centos01 -v centos01:/home centos
775b213506eb2bc06228ac25d2f8e36f5abfccaba80658accc072a7fd7af6879
root@KitDevVps:~# docker volume ls
DRIVER VOLUME NAME
local centos01
local sqlvolume
docker run -d -P --name centos01 -v centos01:/home centos
这行命令中,-d是后台运行,-P大写P是随机指定端口,-v centos01:/home
的centos01
是卷名,不是主机目录,这里很容易跟主机目录混淆,要留心。冒号后面是容器内目录。我在指令中加了-d让它后台运行,但docker自动把这个镜像关闭了,原因似乎是docker理解这个容器没用了,就自动关掉了。下次尝试不加-d。
删掉容器,看看volume还在不在:
root@KitDevVps:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
775b213506eb centos "/bin/bash" 37 seconds ago Exited (0) 35 seconds ago centos01
1cdd55fd90c5 nginx "/docker-entrypoint.…" 21 hours ago Up 18 hours 0.0.0.0:80->80/tcp nginx1
7d2fd4e741ba hello-world "/hello" 24 hours ago Exited (0) 24 hours ago elastic_goldstine
root@KitDevVps:~# docker rm centos01
centos01
root@KitDevVps:~# docker volume ls
DRIVER VOLUME NAME
local centos01
local sqlvolume
<