您的位置:首页 > 运维架构 > Docker

Docker容器技术介绍(五) --- 目录、文件及数据

2017-11-01 16:37 676 查看
容器在运行的过程中,难免会涉及到文件的读写,比如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


再到容器中查看 /var/www 目录的情况

[root@localhost ~]# ll /www/
total 72
-rwxrwxrwx. 1 root root  657 Aug 28 16:10 aes1.lua
-rwxrwxrwx. 1 root root 1088 Aug 28 18:33 aes2.lua
drwxr-xr-x. 4 root root 4096 Sep 27 20:22 composer-demo
-rwxrwxrwx. 1 root root  166 Jun  9 17:02 data.php
-rwxrwxrwx. 1 root root   86 Jul 20 17:13 gcc.sh
-rwxrwxrwx. 1 root root   15 Sep  1  2016 index.html
-rwxrwxrwx. 1 root root   21 Sep 27 16:33 index.php
-rwxrwxrwx. 1 root root 1076 Jul 20 18:05 mcrypt.c
-rwxrwxrwx. 1 root root 3360 Jul 20 18:05 mcrypt.o
-rwxrwxrwx. 1 root root 2590 Jul 20 17:42 mcrypt.php
-rwxrwxrwx. 1 root root 7933 Jul 20 18:05 mcrypt.so
-rwxrwxrwx. 1 root root  556 Jul 20 16:17 module.c
-rwxrwxrwx. 1 root root 2624 Jul 20 16:12 module.o
-rwxrwxrwx. 1 root root  110 Sep  5 11:03 redis.php
drwxrwxrwx. 2 root root 4096 Aug 28 14:23 so
-rwxrwxrwx. 1 root root 3058 Jul 20 17:59 test.lua
-rwxrwxrwx. 1 root root   26 Sep 27 16:48 test.php
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                  NAMES
f14532375dc9        nginx:latest        "nginx -g 'daemon of   17 minutes ago      Up 17 minutes       0.0.0.0:8080->80/tcp   fervent_banach
[root@localhost ~]# docker exec -it f14 /bin/bash
root@f14532375dc9:/# ls -l /var/www
total 72
-rwxrwxrwx. 1 root root  657 Aug 28 08:10 aes1.lua
-rwxrwxrwx. 1 root root 1088 Aug 28 10:33 aes2.lua
drwxr-xr-x. 4 root root 4096 Sep 27 12:22 composer-demo
-rwxrwxrwx. 1 root root  166 Jun  9 09:02 data.php
-rwxrwxrwx. 1 root root   86 Jul 20 09:13 gcc.sh
-rwxrwxrwx. 1 root root   15 Sep  1  2016 index.html
-rwxrwxrwx. 1 root root   21 Sep 27 08:33 index.php
-rwxrwxrwx. 1 root root 1076 Jul 20 10:05 mcrypt.c
-rwxrwxrwx. 1 root root 3360 Jul 20 10:05 mcrypt.o
-rwxrwxrwx. 1 root root 2590 Jul 20 09:42 mcrypt.php
-rwxrwxrwx. 1 root root 7933 Jul 20 10:05 mcrypt.so
-rwxrwxrwx. 1 root root  556 Jul 20 08:17 module.c
-rwxrwxrwx. 1 root root 2624 Jul 20 08:12 module.o
-rwxrwxrwx. 1 root root  110 Sep  5 03:03 redis.php
drwxrwxrwx. 2 root root 4096 Aug 28 06:23 so
-rwxrwxrwx. 1 root root 3058 Jul 20 09:59 test.lua
-rwxrwxrwx. 1 root root   26 Sep 27 08:48 test.php


把宿主机的程序映射到Docker容器中使用

可以看到这样就可以容器中很方便的访问宿主机的目录和文件了。通常为了让容器轻量,很多常用的系统命令在容器中并不存在, -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@localhost ~]# docker exec -it 51d1 /bin/bash
root@51d1452cc2be:/# ls /opt/bin/
arch	    cgdelete	chown  df	      env	  gawk	    ipcalc		loadkeys  mkdir       netstat	     pwd       rview	su	    true	     usleep
awk	    cgexec	cp     dmesg	      ex	  gettext   iptables-xml	logger	  mknod       nice	     raw       sed	sync	    ulockmgr_server  vi
basename    cgget	cpio   dnsdomainname  false	  grep	    iptables-xml-1.4.7	login	  mktemp      nisdomainname  readlink  setfont	tar	    umount	     view
bash	    cgset	cut    domainname     fgrep	  gtar	    kbd_mode		ls	  more	      ping	     rm        sh	taskset     uname	     ypdomainname
cat	    cgsnapshot	dash   dumpkeys       find	  gunzip    kill		lsblk	  mount       ping6	     rmdir     sleep	touch	    unicode_start    zcat
cgclassify  chgrp	date   echo	      findmnt	  gzip	    link		lscgroup  mountpoint  plymouth	     rpm       sort	tracepath   unicode_stop
cgcreate    chmod	dd     egrep	      fusermount  hostname  ln			lssubsys  mv	      ps	     rvi       stty	tracepath6  unlink
root@51d1452cc2be:/# /opt/bin/cat /var/www/index.php
<?php

echo "hello";

root@51d1452cc2be:/# /opt/bin/vi /var/www/index.php


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

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
linux-vdso.so.1 =>  (0x00007ffcf95c6000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fce570a2000)
librt.so.1 => /lib64/librt.so.1 (0x00007fce56e9a000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007fce56c95000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007fce56a8d000)
libc.so.6 => /lib64/libc.so.6 (0x00007fce566f9000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fce564f4000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce572ce000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fce562d7000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007fce560d2000)


把宿主机的 /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@localhost ~]# docker exec -it 90f /bin/bash
root@90fb69fc990a:/# /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

root@90fb69fc990a:/# /opt/bin/touch /etc/ld.so.conf.d/lib64.conf
root@90fb69fc990a:/# ls /etc/ld.so.conf.d/lib64.conf 
/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
ldconfig: Path `/lib/x86_64-linux-gnu' given more than once
ldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than once
/opt/lib64:
liblvm2cmd.so.2.02 -> liblvm2cmd.so.2.02
libfreeblpriv3.so -> libfreeblpriv3.so
libsemanage.so.1 -> libsemanage.so.1
libpci.so.3 -> libpci.so.3.1.10
....

再来尝试使用 /opt/bin/ls 命令:

root@90fb69fc990a:/# /opt/bin/ls /var/www/
aes1.lua  aes2.lua  composer-demo  data.php  gcc.sh  index.html  index.php  mcrypt.c  mcrypt.o	mcrypt.php  mcrypt.so  module.c  module.o  redis.php  so  test.lua  test.php


可以看到映射过来的ls命令可以正常使用了。

以上有点跑题了,让我们回归正题^^

修改容器中的nginx配置文件,把网站根目录更改为 /var/www, 日志文件存储到 /var/www/logs/ 目录下,并在 /var/www/ 新建logs目录, 然后重启容器:

[root@localhost www]# docker stop 90f
90f
[root@localhost www]# docker start 90f
90f
[root@localhost www]# docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                  NAMES
90fb69fc990a        nginx:latest        "nginx -g 'daemon of   36 minutes ago      Up 4 seconds        0.0.0.0:8080->80/tcp   naughty_poincare
[root@localhost www]# docker exec -it 90f /bin/bash
/bin/bash: /opt/lib64/libtinfo.so.5: no version information available (required by /bin/bash)
root@90fb69fc990a:/# ls /var/www/
aes1.lua  aes2.lua  composer-demo  data.php  gcc.sh  index.html  index.php  logs  mcrypt.c  mcrypt.o  mcrypt.php  mcrypt.so  module.c  module.o  redis.php  so	test.lua  test.php


在 /var/www/ 下新建一个 html,然后在宿主机访问这个html:

root@90fb69fc990a:/# touch /var/www/test.html
root@90fb69fc990a:/# echo '<h1>hello docker</h1>' > /var/www/test.html
root@90fb69fc990a:/# /bin/cat /var/www/test.html
<h1>hello docker</h1>
root@90fb69fc990a:/# exit
exit

[root@localhost www]# curl '127.0.0.1:8080/test.html'
<h1>hello docker</h1>
[root@localhost www]# cat /www/logs/access.log
172.17.42.1 - - [31/Oct/2017:08:05:46 +0000] "GET /test.html HTTP/1.1" 200 22 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "-"

可以直接在宿主机中查看nginx 的日志

以上 数据卷就介绍到这里, 接下来介绍 数据卷容器

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

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

[root@localhost www]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mysql                                  5.6.38              52ac9f329cfd        5 days ago          299 MB
nginx                                  latest              2ecc072be0ec        3 weeks ago         108.3 MB
centos                                 v7.0                fae454d6fc7b        5 weeks ago         434.5 MB
mysql                                  5.6.37              c6d1fd492efc        6 weeks ago         299 MB
ubuntu                                 14.04               b44ce450cb60        6 weeks ago         188 MB
quay.io/coreos/etcd                    v3.0.4              3b17a5f34e6c        15 months ago       43.3 MB
index.tenxcloud.com/tenxcloud/ubuntu   latest              2d4cb9fc6d24        23 months ago       251 MB
[root@localhost www]# docker run -it -v /data --name datacon centos:v7.0 /bin/bash
[root@6c281ef87114 /]# ls
bin  boot  data  dev  etc  fastboot  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

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

[root@localhost www]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
6c281ef87114        centos:v7.0         "/bin/bash"         12 minutes ago      Exited (0) 4 minutes ago                       datacon

[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

[root@localhost www]# docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED              STATUS              PORTS                  NAMES
98939ee55034        nginx:latest        "nginx -g 'daemon of   47 seconds ago       Up 46 seconds       0.0.0.0:8081->80/tcp   nginx-2
a1369262ba25        nginx:latest        "nginx -g 'daemon of   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   nginx-1

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

[root@localhost www]# docker exec -it 989 /bin/bash
root@98939ee55034:/# ls
bin  boot  data  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
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
hello docker
root@98939ee55034:/data# exit
exit
[root@localhost www]# docker exec -it a13 /bin/bash
root@a1369262ba25:/# ls /data
docker.html
root@a1369262ba25:/# cat /data/docker.html
hello docker
root@a1369262ba25:/# exit
exit
[root@localhost ~]# docker start -i 6c28
[root@6c281ef87114 /]# ls /data/
docker.html
[root@6c281ef87114 /]# /bin/cat /data/docker.html
hello docker


可以看到挂载了相同的数据卷容器的容器之间以及和数据局容器之间数据都是共享的。

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

以上就是关于Docker对于文件的简单操作,希望对大家有帮助^^
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: