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  
再到容器中查看 /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對於文件的簡單操作,希望對大家有幫助^^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM