?
This document uses PHP Chinese website manual Release
綁定掛載從 Docker 早期開始就已經存在。與卷相比,綁定安裝具有有限的功能。當您使用綁定掛載時,主機上的文件或目錄被掛載到容器中。文件或目錄由主機上的完整路徑或相對路徑引用。相比之下,當您使用卷時,會在主機上的 Docker 存儲目錄中創(chuàng)建一個新目錄,并且 Docker 會管理該目錄的內容。
文件或目錄不需要已經存在于 Docker 主機上。如果它尚不存在,它會根據需求創(chuàng)建。綁定掛載非常高效,但它們依賴于具有特定目錄結構的主機的文件系統(tǒng)。如果您正在開發(fā)新的 Docker 應用程序,請考慮使用命名卷。您不能使用 Docker CLI 命令直接管理綁定掛載。
最初,-v
或--volume
用標志獨立的容器和--mount
用于群服務標志。但是,從 Docker 17.06開始,您也可以使用--mount
獨立容器。一般來說,--mount
更明確和詳細。最大的區(qū)別在于,-v
語法將所有選項組合在一個字段中,而--mount
語法將它們分開。這是每個標志的語法比較。
提示:新用戶應使用
--mount
語法。有經驗的用戶可能更熟悉這個語法-v
或--volume
語法,但鼓勵使用--mount
,因為研究表明它更易于使用。
-v
或者 --volume
:由三個由冒號(:
)分隔的字段組成。這些字段必須按正確的順序排列,每個字段的含義并不明顯。
在綁定掛載的情況下,第一個字段是主機上文件或目錄的路徑。
第二個字段是文件或目錄將被安裝在容器中的路徑。
第三個字段是可選的,并且是用逗號分隔的選項,諸如列表ro
,consistent
,delegated
,cached
,z
,和Z
。這些選項在下面討論。
--mount
:由多個鍵值對組成,由逗號分隔,每個由一個<key>=<value>
元組組成。--mount
語法比更詳細的-v
或--volume
,但按鍵的順序并不顯著,并且標志的價值更容易理解。
type
安裝件,其可以是bind
,volume
,或tmpfs
。本主題討論綁定掛載,因此類型將始終如此bind
。
source
安裝的。對于綁定掛載,這是 Docker 守護程序主機上文件或目錄的路徑??赡鼙恢付?code>source或src
。
destination
作為其值,其中的文件或目錄將被安裝在容器的路徑??梢灾付?code>destination,dst
或target
。
readonly
選項(如果存在)將導致綁定掛載以只讀方式掛載到容器中。
bind-propagation
選項(如果存在)會更改綁定傳播??梢允且粋€rprivate
,private
,rshared
,shared
,rslave
,slave
。
consistency
選項,如果存在,可以是一種consistent
,delegated
或cached
。此設置僅適用于 Docker for Mac,并在所有其他平臺上被忽略。
--mount
標志不支持z
或Z
修改 selinux 標簽的選項。
以下示例在可能的地方顯示了語法--mount
和-v
語法,并且--mount
首先給出。
-v
與--mount
行為之間的差異由于-v
和--volume
標志長期以來一直是 Docker 的一部分,它們的行為不能改變。這意味著-v
和** --mount
之間有一個不同的行為 。
如果您使用-v
或--volume
綁定 Docker 主機上尚不存在的文件或目錄,-v
將為您創(chuàng)建端點。它始終創(chuàng)建為一個目錄。
如果您使用--mount
綁定貼裝Docker主機上尚不存在的文件或目錄,Docker也不會自動為您創(chuàng)建它,但會產生一個錯誤。
考慮一個你有source
目錄的情況,并且當你構建源代碼時,工件被保存到另一個目錄中source/target/
。您希望工件對容器可用/app/
,并且您希望容器每次在開發(fā)主機上構建源時都可以訪問新的構建。使用以下命令將target/
目錄綁定到您的容器中/app/
。從source
目錄內運行命令。$(pwd)
子命令將擴展到 Linux 或者 MacOS 主機的當前工作目錄。
--mount
和-v
以下實施例產生相同的結果。除非在運行第一個容器后移除devtest
容器,否則無法運行它們。
--mount
-v
$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ nginx:latest
$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ nginx:latest
使用docker inspect devtest
驗證綁定安裝正確創(chuàng)建。尋找Mounts
部分:
"Mounts": [ { "Type": "bind", "Source": "/tmp/source/target", "Destination": "/app", "Mode": "", "RW": true, "Propagation": "rprivate" }],
這表明掛載是一個bind
掛載,它顯示了正確的源和目標,它顯示掛載是可讀寫的,并且傳播設置為rprivate
。
停止容器:
$ docker container stop devtest $ docker container rm devtest
如果將綁定掛載到容器上的非空目錄中,則該目錄的現有內容將被綁定掛載隱藏。這可能是有益的,例如,當您想要測試新版本的應用程序而無需構建新映像時。然而,這也可能令人驚訝,并且這種行為不同于docker卷的行為。
這個例子被認為是極端的,但會將容器/usr/
目錄的內容替換/tmp/
為主機上的/tmp/
目錄。在大多數情況下,這會導致無法正常工作的容器。
--mount
和-v
的示例,最后的結果是一樣的。
--mount
-v
$ docker run -d \ -it \ --name broken-container \ --mount type=bind,source=/tmp,target=/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262:starting container process caused "exec: \"nginx\": executable file not found in $PATH".
$ docker run -d \ -it \ --name broken-container \ -v /tmp:/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262:starting container process caused "exec: \"nginx\": executable file not found in $PATH".
該容器已創(chuàng)建但未啟動。去掉它:
$ docker container rm broken-container
對于某些開發(fā)應用程序,容器能夠寫入綁定安裝非常有用,以便將更改傳播回 Docker 主機。在其他時候,容器應該只能讀取數據而不能修改它。
此示例修改上面的示例,但通過在容器中的裝入點之后添加ro
選項列表(默認為空),將目錄裝載為只讀綁定裝入。如果存在多個選項,請用逗號分隔它們。
--mount
和-v
的實例有同樣的結果。
--mount
-v
$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app,readonly \ nginx:latest
$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app:ro \ nginx:latest
使用docker inspect devtest
驗證綁定安裝正確創(chuàng)建。尋找Mounts
部分:
"Mounts": [ { "Type": "bind", "Source": "/tmp/source/target", "Destination": "/app", "Mode": "ro", "RW": false, "Propagation": "rprivate" }],
停止容器:
$ docker container stop devtest $ docker container rm devtest
綁定傳播默認rprivate
為綁定安裝和卷。它只能配置綁定掛載,并且只能在 Linux 主機上配置。綁定傳播是一個高級話題,許多用戶從不需要配置它。
綁定傳播是指在給定的綁定掛載或命名卷中創(chuàng)建的掛載是否可以傳播到該掛載的副本??紤]一個掛載點/mnt
,它也被掛載/tmp
。傳播設置控制是否掛載/tmp/a
也可用/mnt/a
。每個傳播設置都有一個遞歸對應點。在遞歸的情況下,考慮/tmp/a
也被掛載為/foo
。傳播設置控制是否/mnt/a
和/或/tmp/a
將存在。
傳播設置 | 描述 |
---|---|
shared | 原始安裝的子安裝會暴露給副本安裝,并且副安裝的子安裝也會傳播到原始安裝。 |
slave | 類似于共享安裝,但僅限于一個方向。如果原始安裝展示了一個子安裝,則副本安裝可以看到它。但是,如果副本安裝公開了子安裝,則原始安裝無法看到它。 |
private | 該掛載是私人的。其中的子安裝不會暴露給副本安裝,并且副安裝的子安裝不會暴露給原始安裝。 |
rshared | 與共享相同,但傳播也擴展到嵌套在任何原始或副本裝入點內的掛載點。 |
rslave | 與從屬設備相同,但傳播還擴展到嵌套在任何原始或副本安裝點內的掛載點。 |
rprivate | 默認值。與私有相同,這意味著原始或副本安裝點內的任何位置的安裝點都不會沿任一方向傳播。 |
在可以在安裝點上設置綁定傳播之前,主機文件系統(tǒng)需要已經支持綁定傳播。
有關綁定傳播的更多信息,請參閱共享子樹的 Linux 內核文檔。
以下示例將target/
目錄裝入容器兩次,第二個裝入設置ro
選項和rslave
綁定傳播選項。
--mount
和-v
實例有同樣的結果。
--mount
-v
$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=/app \ --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \ nginx:latest
$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ -v "$(pwd)"/target:/app2:ro,rslave \ nginx:latest
現在如果你創(chuàng)建/app/foo/
,/app2/foo/
也會存在。
如果您使用selinux
,您可以添加z
或Z
選項來修改正在裝入容器的主機文件或目錄的 selinux 標簽。這會影響主機本身的文件或目錄,并可能導致 Docker 范圍之外的后果。
該z
選項指示綁定安裝內容在多個容器之間共享。
該Z
選項指示綁定安裝內容是私有的和未共享的。
使用極端謹慎使用這些選項。綁定系統(tǒng)目錄(例如/home
或/usr
帶有Z
選項)會導致主機無法操作,您可能需要手動重新標記主機文件。
此示例設置z
選項以指定多個容器可以共享綁定掛載的內容:
使用--mount
標志不可能修改 selinux 標簽。
$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app:z \ nginx:latest
Docker for Mac 用于osxfs
將從macOS共享的目錄和文件傳播到 Linux VM。這種傳播使這些目錄和文件可用于在 Docker for Mac 上運行的 Docker 容器。
默認情況下,這些共享是完全一致的,這意味著每次在 macOS 主機上發(fā)生寫入或通過容器中的掛載時,都會將更改刷新到磁盤,以便共享中的所有參與者都具有完全一致的視圖。在某些情況下,完全一致可能會嚴重影響性能。Docker 17.05 和更高版本引入了選項來調整每個安裝,每個容器的一致性設置。以下選項可用:
consistent
或者default
:完全一致的默認設置,如上所述。
delegated
:容器運行時的掛載視圖是權威的。在容器中進行的更新在主機上可見之前可能會有延遲。
cached
:macOS 主機的掛載視圖是權威的。在主機上進行的更新在容器內可見之前可能會有延遲。
這些選項在除 macOS 之外的所有主機操作系統(tǒng)上完全忽略。
--mount
和-v
實例有同樣的結果。
--mount
-v
$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,destination=/app,consistency=cached \ nginx:latest
$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app:cached \ nginx:latest
了解卷。
了解 tmpfs mounts。
了解存儲驅動程序。