1. 程式人生 > >[Docker]Volume

[Docker]Volume

系統調用 並且 names 成了 指定 保存 ace dock 鏡像

  容器技術使用rootfs機制和Mount Namespace,構建出一個同宿主機完全隔離開的文件系統環境

  那容器裏進程新建的文件,怎麽樣才能讓宿主機獲取到?宿主機上的文件和目錄,怎麽樣才能讓容器裏的進程訪問到?

  Docker Volume就可以解決這個問題,它允許你將宿主機上指定的目錄或文件掛載到容器裏面進行讀取和修改操作

  在Docker項目裏,它支持兩種Volume聲明方式,可以把宿主機目錄掛載進容器的/test目錄當中

$docker run -v /test …  //docker沒有顯式聲明宿主機目錄,Docker會默認在宿主機上創建一個臨時目錄/var/lib/docker/volumes/[VOLUME_ID]/_data,然後把它掛載到容器的/test目錄上
$docker run 
-v /home:/test … //直接把宿主機的/home目錄掛載到容器的/test目錄上

  Docker如何將宿主機上的目錄或文件掛載到容器裏面呢?

  當容器進程被創建之後,盡管開啟了Monut Namespace,但是在它執行chroot之前,容器進程一直可以看到宿主機上的整個文件系統(包括了要使用的容器鏡像,這個鏡像的各個層,保存在/var/lib/docker/aufs/diff目錄下,在容器啟動後,它們會被聯合掛載在var/lib/docker/aufs/mnt中)。在執行chroot之前,把Volume指定的宿主機目錄(如/home目錄)掛載到指定的容器目錄(如/test目錄)在宿主機對應的目錄(var/lib/docker/aufs/mnt/[可讀寫層ID]/test,這個Volume的掛載工作就完成了。由於執行了這個掛載操作,容器進程(Docker初始化進程dockerinit,負責完成根目錄的準備、掛載設備和目錄、配置hostname等一系列需要容器內進行的初始化操作,最後它通過execv()系統調用,讓應用進程取代自己,成為容器裏PID=1的進程)已經創建了,也就意味著此時Monut namespace 已經開啟了。所以這個掛載事件只在容器裏可見,在宿主機是看不見容器內部的這個掛載點的,這就保證了容器的隔離性不會被Volume打破。

  這裏使用到的掛載技術,就是Linux的綁定掛載(bind mount)機制,它的主要作用是允許你將一個目錄或者文件,而不是整個設備掛載到一個指定的目錄上,並且這時你在該掛載點上進行的任何操作,只是發生在被掛載的目錄或者文件上,而源掛載點的內容則會被隱藏起來且不受影響。

[Docker]Volume