著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
有些容器会自动产生一些数据,为了不让数据随着 container 的消失而消失,保证数据的安全性。例如:数据库容器,数据库的表会产生一些数据,如果我把 container 给删除,数据就丢失。为了保证数据不丢失,这就有了 Volume 的存在。
Data Volume 结构图
Docker持久化数据的方案
- 基于本地文件系统的Volume。可以在执行
Docker create
或Docker run
时,通过-v
参数将主机的目录作为容器的数据卷。这部分功能便是基本的本地文件系统的 volume 管理。 - 基于plugin的Volume,支持第三方的存储方案,比如NAS,aws
Volume的类型
- 受管理的data Volume:由docker后台自动创建。
- 绑定挂载的Volume:具体挂载位置可以由用户指定。
数据持久化之Data Volume
以官方镜像mysql的dockerfile文件为例。其中dockerfile通过volume指定了当前容器中要备份的文件路径,但是并没有指定说要保存到宿主机的哪个位置。
volume: 映射容器中的文件到本地宿主机硬盘中
8& rm - rf / var / lib / mysql && mkdir - p / var / lib / mysql / var / run / mysqld \&& chown - R mysql : mysql / var / lib / mysql / var / run / mysqld \ # ensure that / var / run / mysqld ( used for socket and lock files ) is writable regardle && chmod 777/ var / run / mysqld \ # comment out a few problematic configuration values 8& find / etc / mysql /- name '*. cnf '-print0\ | xargs -0 grep -1zE'( bind - address | log )”\ | xargs - rt -0 sed - Ei ' s /( bind - address | log )/#&/'\ # don ' t reverse lookup hostnames , they are usually another container && echo '[ mysqld ]\ nskip - host - cache \ nskip - name - resolve '>/ etc / mysql / conf . d / VOLUME / var /1ib/ mysql CoPY docker - entrypoint . sh / usr / local / bin / RUN ln - s usr / local / bin / docker - entrypoint . sh / entrypoint . sh # backwards compat ENTRYPOINT [" docker - entrypoint . sh “] ExPosE 3306 CMD [“ mysqld “ ]
在我们使用docker run
启动mysql镜像容器的时候,容器会默认在宿主机生成一个 volume,至于位置在哪,名字是什么,可以通过如下命令查看
# 查看所有volume docker volume ls # 删除指定volume docker volume rm [volume name] # 查看volume详细 docker volume inspect [volume name]
Lvagranteaocker - nost [ vagrant @ docker - host ~ J $ sudo docker volume 1s DRIVER VOLUME NAME QC e6ee590e90115677b39170b6633ae15257692ba4f8ad387f87f40cf450e669b9 OCal fe82dd5ab639db1199a8adcad4bd3d4deba0548b01796329085de2ce61298c4b [ vagrant @ docker - host ~]$[ vagrantedocker - host Cvagrant @ docker - host - ~]$ sudo [ vagrantedocker - host ~ Js sudo Error : No such volume :fe8[ vagrantedocker - host ~]$ sudo docker run - d -- name mysql2- e MYSQL _ ALLOW _ EMPTY _ PASSWORD - true mysqlAC aocker volume inspect fe8 docker volume inspect fe82dd5ab639db1199a8adcad4bd3d4deba0548b01796329085de2 " CreatedAt ":"2018-01-23T16:13:01Z”, " Driver ":" local ”, " Labels ”: null , “ Mountpoint ":“/ var / lib / docker / volumes /fe82dd5ab639db1199a8adcad4bd3d4deba0548b01796329085de2ce612" Name ":"fe82dd5ab639db1199a8adcad4bd3d4deba0548b01796329085de2ce61298c4b”, " Options ":{} “ Scope ”:" Local ” 98c4b/_ data ”,
此时我们删除容器,发现volume数据卷还在,有保留。
[ vagrant @ docker - host mysql1 Iysql2 [ vagrant @ docker - host Lvagrantedocker - host [ vagrant @ docker - host [ vagrant @ docker - host ~ Js sudo docker ps - a ONTAINER ID IMAGE COMMAND [ vagrant @ docker - host ] s sudo docker colume is docker :' colume is not a docker command . See ' docker -- help ' [ vagrantedocker - host ~ JS sudo DRIVER VOLUME NAME local e6ee590e90115677b39170b6633ae15257692ba4f8ad387f87f40cf450e669b9 0 C fe82dd5ab639db1199a8adcad4bd3d4deba0548b01796329085de2ce61298c4b cker rm mysql1mysql2 CREATED STATUS PORTS NAMES docker volume ls
此时我们会觉得这个data volume name 的名字很长,很不好理解。我们可以通过-v
参数来指定生成的
volume namedocker run -d -v mysql:/var/lib/mysql --name mysql mysql5.7
:
前参数是volume name, :
后面的是要备份的文件目录(容器)
[ vagrant @ docker - host ~]$ sudo docker volume Ls DRIVER VOLUME NAME 1ocal mySql
此时我们删除容器,volume数据卷还在,我们用这个名为mysql的volume作为一个新容器的数据卷,使用它。
docker run -d -v mysql:/var/lib/mysql --name mysql2 mysql5.7
进入mysql2容器中,mysql -uroot 进入数据库中,发现当前数据库数据和之前删除的容器中的数据库数据一样。
数据持久化之bind Mounting
和上面Data Volume不同的是,bind Mounting只能通过docker run -v
方式启动,无法使用dockerfile文件的方式。
运行容器的时候指定本地的一个文件目录和容器中的一个文件目录的映射,通过这个可以做文件数据同步,两方无论哪一方有修改,另一方都会同步内容
docker run -d -v $(pwd):/usr/share/nginx/html -p 80:80 --name nginx nginx
这个时候-v:
前面的参数是本机文件路径, :
后面是docker容器文件目录, $(pwd)
当前命令执行的路径
值得注意的是,使用bind Mounting方式做数据卷的映射时,首次docker run -v
运行,如果本机的文件夹是没有内容的,docker容器中的文件夹是有内容的,则本机的会覆盖dokcer容器中的,也就是容器中原本有内容的也会没有内容。
。