1. 程式人生 > >深入理解Docker Volume(二)

深入理解Docker Volume(二)

轉自:http://dockone.io/article/129

【編者的話】繼上一篇文章深入理解Docker Volume(一)後,DockerOne翻譯了深入理解Volume的第二篇文章。本文重點介紹了兩種建立Volume方式的異同以及使用docker run命令建立Volume時,指定主機目錄與不指定主機目錄的區別。

Docker的難點之一就是Volume的使用,這也是很多人都會問到的問題。所以讓我們一起來深入看看Docker Volume是如何工作的。

很多人都對Volume有一個誤解,他們認為Volume是為了持久化。如此想法是因為他們覺得容器不能持久化,所以Volume應該是為了滿足這個需求而設計的。其實容器會一直存在,除非你刪除它們:



這可能來自於容器不是持久的想法,這樣確實是不對的。容器是持久的,直到你刪除他們,並且你只能這樣做:

docker rm my_container

如果你沒有執行此命令,那麼你的容器會一直存在,依舊可以啟動、停止等。如果你找不到你的容器,可以執行此命令:
docker ps -a

docker ps只能顯示正在執行的容器,但是容器也會處於停止狀態,這種情況下,上面的命令(譯者注:-a引數會列出所有的容器)會顯示所有的容器,無論它們處於什麼狀態。docker run ...命令可以有很多的組合(譯者注:它提供了Docker容器從建立到啟動的所有功能),它會建立一個新的容器,然後啟動它。

綜上,再次宣告:Volume並不是為了持久化。

什麼是Volume

Volume可以將容器以及容器產生的資料分離開來,這樣,當你使用docker rm my_container刪除容器時,不會影響相關的資料。

Volume可以使用以下兩種方式建立:
  • 在Dockerfile中指定VOLUME /some/dir
  • 執行docker run -v /some/dir命令來指定

無論哪種方式都是做了同樣的事情。它們告訴Docker在主機上建立一個目錄(預設情況下是在/var/lib/docker下),然後將其掛載到指定的路徑(例子中是:/some/dir)。當刪除使用該Volume的容器時,Volume本身不會受到影響,它可以一直存在下去。

如果在容器中不存在指定的路徑,那麼該目錄將會被自動建立。


你可以告訴Docker同時刪除容器和其Volume:
docker rm -v my_container


有時候,你想在容器中使用主機上的某個目錄,你可以通過其它的引數來指定(譯者注:注意冒號前面的和後面的內容):
docker run -v /host/path:/some/path ...

這明確地告訴Docker使用指定的主機路徑來代替Docker自己建立的根路徑並掛載到容器內指定的路徑(以上例子為/some/path)。需要注意的是,這種方式同樣支援檔案。在Docker術語中,這通常被稱為bind-mounts(雖然技術層面上是這樣講的,但是實際的感覺是所有的Volume都是bind-mounts的)。如果主機上的路徑不存在,目錄將自動在給定的路徑中建立。

對待bind-mount Volume和一個“正常”的Volume有一點不同,它不會修改主機上那些非Docker建立的東西:
  1. 一個“正常”的Volume,Docker會自動將指定Volume路徑(如上面的示例/some/path)上的資料複製到由Docker建立的新的目錄下,如果是“bind-mount”,Volume就不會這樣做。(譯者注:這樣做會將主機上的目錄複製到容器)
  2. 當你執行docker rm -v my_container命令時,“bind-mount” 型別的Volume不會被刪除。

容器也可以與其它容器共享Volume。
docker run --name my_container -v /some/path ...
docker run --volumes-from my_container --name my_container2 ...


上面的命令將告訴Docker從第一個容器掛載相同的Volume到第二個容器,它可以在兩個容器之間共享資料。

如果你執行docker rm -v my_container命令,而上方的第二容器依然存在,那Volume不會被刪除,如果你不使用docker rm -v my_container2命令刪除第二個容器,那它會一直存在。

Dockerfiles裡的VOLUME

正如前面提到的,Dockerfile中的VOLUME指令也可以做同樣的事情,類似docker run命令中的-v引數(除了你不能在Dockerfile指定主機路徑)。也正因為如此,構建映象時可以得到驚奇的效果。

在Dockerfile中的每個命令都會建立一個新的用於執行指定命令的容器,並將容器提交到映象,每一步都是在前一步的基礎上構建。因此在Dockerfile中ENV FOO=bar等同於:
cid=$(docker run -e FOO=bar <image>)
docker commit $cid

下面讓我們來看看這個Dockerfile的例子發生了什麼:
[{{
FROM debian:jessie
VOLUME /foo/bar
RUN touch /foo/bar/baz
}}}

docker build -t my_debian .
我們期待的是Docker建立一個名為my_debian並且Volume是/foo/bar的映象,以及在/foo/bar/baz下添加了一個空檔案,但是讓我們看看等同的CLI命令列實際上做了哪些:
cid=$(docker run -v /foo/bar debian:jessie)
image_id=$(docker commit $cid)
cid=$(docker run $image_id touch /foo/bar/baz)
docker commit $(cid) my_debian


真實過程可能並不是這樣,但是類似。

在這裡,/foo/bar會首先建立,所以我們每次通過這個映象啟動一個容器,都會有一個空的/foo/bar目錄。正如前面所說,Dockerfile中每個命令都會建立一個新容器。也就是說,每次都會建立一個新的Volume。由於例子的Dockerfile中是先指定Volume的,所以當執行touch /foo/bar/baz命令的容器建立時,一個Volume會被掛載到/foo/bar,然後baz才能被寫入此Volume,而不是實際的容器或映象的檔案系統內。

所以,牢記Dockerfile中VOLUME指令的位置,因為它在你的映象內建立了不可改變的目錄。

docker cp#8509),docker commitdocker export還不支援Volume(在文章截稿時)。

目前,在容器的建立/銷燬期間來管理Volume(建立/銷燬)是唯一的方式,這有點古怪,因為Volume是為了從容器的生命週期中分離容器內的資料與。Docker團隊正在處理這個問題,但尚未合併(#8484)。

如果您想了解Docker Volume的更多功能,請移步這裡



===========================
譯者介紹
田浩浩悉尼大學USYD碩士研究生,目前在珠海從事Android應用開發工作。業餘時間專注Docker的學習與研究,希望通過DockerOne把最新最優秀的譯文貢獻給大家,與讀者一起暢遊Docker的海洋。

相關推薦

深入理解Docker Volume

轉自:http://dockone.io/article/129 【編者的話】繼上一篇文章深入理解Docker Volume(一)後,DockerOne翻譯了深入理解Volume的第二篇文章。本文重點介紹了兩種建立Volume方式的異同以及使用docker run命令建立

Java——深入理解Class物件:Class物件的載入及其獲取方式

上一篇部落格Java——深入理解Class物件(一)帶大家簡單認識了一下Java中Class物件。 現在帶大家瞭解一下Class物件的載入及其獲取方式。 1.Class物件的載入 在Java——深入理解Class物件(一)我們已提到過,Class物件是由JVM載入的,那它必然不會是胡亂載

深入理解 Laravel Eloquent——模型間關係關聯

Eloquent是什麼 Eloquent 是一個 ORM,全稱為 Object Relational Mapping,翻譯為 “物件關係對映”(如果只把它當成 Database Abstraction Layer 陣列庫抽象層那就太小看它了)。所謂 “物件”,就是本文所說的 “模型(Model)

深入理解HTTP協議——協議詳解篇

1.HTTP/1.0和HTTP/1.1的比較 RFC 1945定義了HTTP/1.0版本,RFC 2616定義了HTTP/1.1版本。 1.1建立連線方面 HTTP/1.0 每次請求都需要建立新的TCP連線,連線不能複用。HTTP/1.1 新的請求可以在上次請求建立

深入理解阻塞佇列——ArrayBlockingQueue原始碼分析

在深入理解阻塞佇列(一)——基本結構中,介紹了BlockingQueue這一介面的子類以及子介面。本文主要就其中的一個實現類:ArrayBlockingQueue進行原始碼分析,分析阻塞佇列的阻塞是如何實現的。 概述 ArrayBlockingQueue

深入理解線性模型---基於似然函式的估計

目錄 1. 引言 2. 關於\(\varepsilon\)假設 3. 基於似然函式的估計 3.1 基於假設1 3.2 基於假設2 3.3. 基於假設3

深入理解協程:yield from實現非同步協程

原創不易,轉載請聯絡作者 深入理解協程分為三部分進行講解: 協程的引入 yield from實現非同步協程 async/await實現非同步協程 本篇為深入理解協程系列文章的第二篇。 yield from yield from是Python3.3(PEP 380)引入的新語法。主要用於解決在生成器

深入理解二分查詢、二分答案

二分答案     如果已知候選答案的範圍[min,max],有時候我們不必通過計算得到答案,只需在此範圍內應用“二分”的過程,逐漸靠近答案(最後,得到答案)! 一、何時可以使用“二分答案”     不是任何題目都適合使用“二分答案”的,我Sam觀察到一般有以下的一

[轉]畢設- 深入HBase架構解析

node 角度 發送 under 收集 .org fig 服務器 url 深入HBase架構解析(二) 前言 這是《深入HBase架構解析(一)》的續,不多廢話,繼續。。。。 HBase讀的實現 通過前文的描述,我們知道在HBase寫時,相同Cell(RowKe

深入學習之mysql表的操作

uniq order fault change incr 相關 約束 設置 type 1、表:是數據庫中的存儲數據的基本單位,一個表包含若幹個字段和值 2、創建表:   CREATE TABLE 表名稱 (   字段名1  數據庫類型1  [約束條件1],   字段名2  

Docker入門

docker安裝 docker基礎命令 一、Docker相關概念1.Docker: namespace,cgroup: 解決方案: lxc,openvz lxc:linux containers docker最初就是lxc的封裝版本。 docker engine/docker server:輸

深入理解JavaScript系列16:閉包Closures

ava hive auto flow style this quest 情況 知識 介紹 本章我們將介紹在JavaScript裏大家常常來討論的話題 —— 閉包(closure)。閉包事實上大家都已經談爛了。雖然如此,這裏還是要試著從理論角度來討論下閉包,

laravel服務容器-----深入理解控制反轉IoC和依賴註入DI

outer 十分 綁定 之間 module 還需 true 更多 我們 首先大家想一想什麽是容器,字面意思就是盛放東西的東西,常見的變量,對象屬性都是容器,一個容器能夠裝什麽東西,完全在於你對這個容器的定義。有的容器不僅僅只是存文本,變量,而是對象,屬性,那麽我們通過這種容

Docker系列鏡像管理

nginx orm lda cast anaconda rip search fff spa 2.1 查看鏡像 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docke

docker學習

ner 命名 post latest nbsp 動態 應用 test 自己的 基本概念: Docker包括三個基本概念:  鏡像(Image): 特殊的文件系統,提供容器運行時所需的程序、庫、資源、配置文件。鏡像不包含動態數據,內容在構建後不會被改變。  容器(Contai

深入理解多態 1

之間 數據 override 擴展 結束 不同的 img over str 1.1 public abstract class Birds{ 2 3 //什麽樣的方法是抽象方法 4 5 public abstract void Fly(); 6

[轉]深入理解閉包

copy AI strong 查找 cte 分組操作 spa 方法 詳細介紹 嚴格來講,IIFE並不是閉包,因為它並不滿足函數成為閉包的三個條件。但一般地,人們認為IIFE就是閉包,畢竟閉包有多個定義。本文將詳細介紹IIFE的實現和用途 實現   函數跟隨一對圓括號()

docker實戰之redis的使用

系統版本 Redis的使用 redis啟動 font height https eight img ont docker中安裝redis的步驟比較簡單,Linux系統版本centos7.4 1.官方倉庫https://hub.docker.com/r/library/red

Docker入門基本操作

ddr root eba nxv let targe rules gist gdi (一)、容器的使用1、docker客戶端命令。輸入docker查看docker用法的語法和相關的命令。 [root@localhost ~]# docker Usage: docker

深入學習Motan系列——服務釋出

闖關經驗: 袋鼠走過了第一關,順利搭建出了Demo,信心爆棚。不過之後,心想怎麼去研究這個框架呢。查了一下,官方文件,好像沒什麼東西可以研究啊。後來,又搜了搜部落格,因為這是微博的框架嘛,所以搜尋時用百度進行搜尋。後來發現,原始碼工程motan-demo-server中的MotanApiExportDemo