容器在运行的过程中,难免会涉及到文件的读写,比如 Web 服务器读取静态文件,记录访问日志和错误日志,设定网站根目录以及目录权限,还有多个容器之间共享数据等等。
Docker 在容器中管理数据主要有两种方式:
在使用 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
-