docker dir file data - yaokun123/php-wiki GitHub Wiki

Docker目录、文件及数据

一、简介

容器在运行的过程中,难免会涉及到文件的读写,比如web服务器读取静态文件,记录访问日志和错误日志,设定网站根目录以及目录权限,还有多个容器之间共享数据等等。

Docker在容器中管理数据主要有两种方式:

方式一:数据卷(Data Volumes):容器内数据直接映射到宿主机

方式二:数据卷容器(Data Volume Containers):使用特定容器来管理数据

二、数据卷方式

在使用docker run 命令时,可以使用-v 参数来把主机的目录映射到宿主机,例如把宿主机的 /www 目录映射到Docker容器中的 /var/www 目录

[root@localhost ~]#  docker run -d -p 8080:80 -v /www:/var/www nginx:latest
f14532375dc93a07f092e164149d384cdde6ae4a90b9de97bb7273c8b553f755

可以看到这样就可以在容器中很方便的访问宿主机的目录和文件了。访问容器的www目录其实就是访问宿主机的/var/www目录。 通常为了让容器轻量,很多常用的系统命令在容器中并不存在,-v 参数可以多次使用来映射多个目录,比如我们可以把宿主机的 /bin /usr/bin 等目录映射到容器中,这样我们就可以轻松的使用宿主机中的很多命令:

[root@localhost ~]#  docker run -d -p 8080:80 -v /www:/var/www -v /bin:/opt/bin -v /usr/bin:/opt/usr/bin nginx:latest
51d1452cc2bed5f36c719298acd4d4249251e4e7c3040eaa984d4528dc198ff3

注意,不是所有映射过来的命令都可以使用,对系统环境有一定依赖的可能无法使用,比如:

root@51d1452cc2be:/# /opt/bin/ls /var/www/
/opt/bin/ls: error while loading shared libraries: libcap.so.2: cannot open shared object file: No such file or directory

//比如 ls 命令由于用到了 libcap.so.2 动态链接库,而容器中找不到这个链接库,
//所以使用这个命令时出现了错误,如果确有需要使用该命令,可以把这个链接库在宿主机的目录也映射到容器中,以上述的 ls命令为例:

在宿主机中先用 ldd 命令查看一下 ls 需要链接哪些动态库,可以看到基本都在 /lib64 目录下
[root@localhost ~]# ldd /bin/ls
把宿主机的 /lib64 目录映射到容器中的 /opt/lib64 下:
[root@localhost ~]#  docker run -d -p 8080:80 -v /www:/var/www -v /bin:/opt/bin -v /usr/bin:/opt/usr/bin -v /lib64:/opt/lib64 nginx:latest
90fb69fc990a14599c157496bfe3d75dac8fff3c34439e8ac6e76de1bf2daba5

进入容器中, 新建 /etc/ld.so.conf.d/lib64.conf,并写入 /opt/lib64,使用 ldconfig -v 来重新搜索动态库
root@90fb69fc990a:/# /opt/bin/touch /etc/ld.so.conf.d/lib64.conf
root@90fb69fc990a:/# ls /etc/ld.so.conf.d/lib64.conf
root@90fb69fc990a:/# echo /opt/lib64 > /etc/ld.so.conf.d/lib64.conf 
root@90fb69fc990a:/# /opt/bin/cat /etc/ld.so.conf.d/lib64.conf
/opt/lib64
root@90fb69fc990a:/# ldconfig -v

再来尝试使用 /opt/bin/ls 命令,可以看到映射过来的ls命令可以正常使用了。

三、数据卷容器

如果要在多个容器之间共享数据,最简便的方式就是使用数据卷容器,数据卷容器就是使用一个特定容器来做数据卷,多个其他容器可以同时挂载这个数据卷,从而达到共享数据的目的。

创建数据卷容器也是使用 docker run 跟 -v 参数,这里以 centos:v7.0 镜像创建的容器作为数据卷容器:

[root@localhost www]# docker run -it -v /data --name datacon centos:v7.0 /bin/bash
6c28

ctrl + p/q让终端退出但容器不退出

作为数据卷容器的容器不需要是运行状态,docker run 跟 --volumes-from 参数可以指定某个容器作为数据卷

[root@localhost www]# docker run -d -p 8080:80 --volumes-from=datacon --name=nginx-1 nginx:latest
a1369262ba2596d81291fc2b114161bf0cb8dce436bbff0da7484be05f008998
[root@localhost www]# docker run -d -p 8081:80 --volumes-from=datacon --name=nginx-2 nginx:latest
98939ee55034233323e89f05254d8cfdef887fcdc2a5793f0bf7efefdd51e7e2

上面创建了两个nginx容器 nginx-1 和 nginx-2,并且都使用了datacon 作为数据卷容器,在其中一个容器的数据卷创建一个文件,再到另一个容器中查看:

[root@localhost www]# docker exec -it 989 /bin/bash
root@98939ee55034:/# cd /data/
root@98939ee55034:/data# touch docker.html
root@98939ee55034:/data# /bin/echo  'hello docker' > docker.html
root@98939ee55034:/data# cat docker.html
root@98939ee55034:/data# exit

[root@localhost www]# docker exec -it a13 /bin/bash
root@a1369262ba25:/# ls /data
root@a1369262ba25:/# exit

[root@localhost ~]# docker start -i 6c28
[root@6c281ef87114 /]# ls /data/

可以看到挂载了相同的数据卷容器的容器之间以及和数据局容器之间数据都是共享的。 docker rm 跟 -v 参数可以在删除容器的时候同时卸载数据卷。

[root@localhost ~]# docker rm -v nginx-1
nginx-1
[root@localhost ~]# docker rm -v nginx-2
nginx-2
[root@localhost ~]# docker rm -v 6c28
6c28