本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
1、序言
世间万物,皆有其命数!从出生到老去,终归黄土,无人可避!没人拥有灵明石猴的通天本领来篡改生死簿!
咳咳!扯远了!让我们回到Linux
Linux
上,进程、shell
脚本都一样,都有着生命周期,像ls
、vim
命令,运行完进程当即销毁,自动人间蒸发!正如它轻轻地来了,又轻轻地走了。挥一挥衣袖,不带走一片云彩!而使用Docker
容器也一样,销毁容器时特别是使用了--rm
选项,那么里面产生的数据也将一并销毁!显然,我们不能接受这种情况,因此不能像管理进程、脚本一样来管理容器!
如何解决?在解决问题前,先来了解一个概念!
2、写时复制概念
先来简单回顾一下Docker
容器概念,基于特殊的分层叠加文件系统,容器均于只读镜像之上新建一层可写层,专供该容器使用,底层它无权干涉。因为是只读镜像文件,因此镜像里面包含的所有文件,容器里面都可以读到,当需要增删修改时,容器从底层复制该文件到容器上面供容器进行操作,这就是写时复制机制。
好了!既然数据随着容器生命周期结束而结束,那么我们就不应该将数据存放于专属的可写层!想象一下, 能不能跟CPU
、内存、磁盘一样,内存充当中介,CPU
将数据写入内存缓存,内存再将数据转存至磁盘?
妙哉!妙哉!
当然可以!以后可写层仅充当缓冲区存放临时数据,而后将可写层挂载外部存储空间;数据发生变动时,实时传输至外部存储空间,这样当容器结束其生命周期时,数据因为存放在外部而不受影响,这样就脱离了容器的生命周期,就差一双翅膀就能直接上天!
这就是Docker
设计的Data Volume
,数据卷;我们国人习惯称之为存储卷!下面是Docker官方的图片:
CopyRight by@Docker Cloud
3、Data Volume类型:
-
Bind Mount Volume
,即将容器存储绑定至宿主机指定的已存在的文件目录 -
Volume
,由Docker
管理并自动在宿主机和容器生成对应目录,相比bind灵活些。 -
tmpfs mount
,只存在于宿主机内存而不会存储到磁盘中,且不会写入容器的可写层,利于提高容器性能。
好了!关于存储卷概念先说到这,下面开始演示!
4、语法格式
sanxi@container:~$ sudo docker container run --help | grep volume
-v, --volume list Bind mount a volume #指定到宿主机已存在的目录
--volume-driver string Optional volume driver for the container
--volumes-from list Mount volumes from the specified container(s)
有三个选项,但是官方现在不建议使用
-v
或者--volume
了,我们来使用最新的--mount
选项
5、Volume演示
-
创建与查看
volume
!顺带提一下,volume
是官方推荐的!bind
毕竟老东西了!
sanxi@container:/data$ sudo docker volume create my_baby #先手动创建存储卷
my_baby
sanxi@container:~$ sudo docker volume ls #看下创建成功没有
DRIVER VOLUME NAME
local my_baby
anxi@container:~$ sudo docker container inspect -f {{.Mounts}} bash #格式化inspect信息,不过挺杂乱的。
[{volume my_baby /var/snap/docker/common/var-lib-docker/volumes/my_baby/_data /test local z true }]
-
容器内新增文件,然后销毁容器并在宿主机查看是否存在。
#起一个bash容器,新建个文本文件,然后退出自动销毁容器。如果需要只读,在dst后面加个readonly就行。
sanxi@container:~$ sudo docker run --name bash -it --rm --mount src=my_baby,dst=/test bash:latest
bash-5.0# echo "hello,world" > /test/hello.txt
bash-5.0# exit
exit
#查看容器销毁后,宿主机是否还存在此文件。
sanxi@container:~$ sudo cat /var/snap/docker/common/var-lib-docker/volumes/my_baby/_data/hello.txt
hello,world
###双击666,容器被销毁后数据还在!!!
6、Bind Mount Volume演示
-
先起容器并创建文件,退出销毁容器。
###因为绑定的目录可能比较长,所以我采用的是自定义变量方式
sanxi@container:~$ sudo docker run --name bash -it --rm --mount type=bind,src="$(pwd)/666",dst=/test bash:latest
bash-5.0# cd test/
bash-5.0# echo "sanxi666" > 666.txt
bash-5.0# exit
exit
-
验证文件是否还存在于
bind
的目录
sanxi@container:~$ cat 666/666.txt
sanxi666
###再次双击666!!!
7、tmpfs mount演示
前面说过,tmpfs mount是临时的,仅存活于宿主机的内存中,当容器停止销毁时,tmpfs挂载的临时目录将会被删除且无法保留,也无法在容器间共享。且此功能仅可在==Linux==上运行容器时有效!!!因此仅适合非持久化存储的敏感信息!
-
先起一个容器,,
type
为tmpfs
sanxi@container:~$ sudo docker run --name=bash -it --rm --mount type=tmpfs,dst=/test bash:latest
[sudo] password for sanxi:
bash-5.0#
-
看一下
inspect
信息,可以看到并没有存储路径!
sanxi@container:~$ sudo docker container inspect -f {{.Mounts}} bash
[{tmpfs /test true }]
-
再来看一下存储卷,也是不存在的!因为它是临时的,仅存在于内存而不是存储在磁盘。因此产生的数据在宿主机也是看不到的,一旦退出容器一切都将灰飞烟灭!
sanxi@container:~$ sudo docker volume ls
DRIVER VOLUME NAME
local my_baby
local test8