自Docker早期以來bind mounts 一直存在。與volumes相比,綁定掛載具備有限的功能。使用bind mounts時,主機上的文件或目錄將裝入容器中。文件或目錄由其在主機上的完整路徑或相對路徑引用。相反,當您使用卷時,會在主機上的Docker存儲目錄中建立一個新目錄,Docker會管理該目錄的內容。linux
該文件或目錄不須要已存在於Docker主機上。若是它尚不存在,則按需建立。綁定掛載很是高效,但它們依賴於具備特定目錄結構的主機文件系統。若是您正在開發新的Docker應用程序,請考慮使用命名卷。您沒法使用Docker CLI命令直接管理bind mounts。nginx
最初,-v
或者--volume
標誌用於獨立容器,--mount
標誌用於羣集服務。可是,從Docker 17.06開始,您還可使用--mount
獨立容器。通常來講, --mount
更明確和冗長。最大的區別在於-v
語法將全部選項組合在一個字段中,而--mount
語法將它們分開。如下是每一個標誌的語法比較。docker
具體的用法 和 差別請參看上一節以介紹。
app
考慮具備一個source目錄的狀況,並在構建源代碼時將構建的代碼保存到另外一個目錄source/target/
中,您但願這個構建代碼可用於容器/app/
,測試
而且您但願容器在每次構建源時都能訪問新構建在開發主機上。使用如下命令將target/
目錄綁定到容器中/app/
。從source
目錄中運行命令 。spa
該$(pwd)
子命令將擴展到Linux或者MacOS主機的當前工做目錄。設計
[root@benjamincloud ~]# mkdir target [root@benjamincloud ~]# docker run -tid --name devtest --mount type=bind,source="$(pwd)"/target,target=/app nginx:latest bc8d4cb8bdc26bc77ddc64aa810f7868a13e1019072767a024d8f14b2e4f0a8a
使用docker inspect devtest
驗證綁定安裝正確建立。尋找Mounts
部分:3d
這代表mount是一個bind
mount,它顯示了正確的源和目標,它代表mount是讀寫的,而且傳播設置爲rprivate
。code
中止容器刪除容器:blog
$ docker container stop devtest $ docker container rm devtest
若是將bind-mount綁定到容器上的非空目錄中,則bind mounts 會隱藏目錄的現有內容。這多是有益的,例如當您想要測試新版本的應用程序而不構建新鏡像時。固然,它也可能使人驚訝,而且此行爲與docker volume行爲不一樣。
此示例設計極端,但將容器/usr/
目錄的內容替換爲主機上的目錄/tmp/。在大多數狀況下,這會致使容器沒法運行。
這些--mount
和-v
示例具備相同的最終結果。
[root@benjamincloud ~]# docker run -dit --name broken-container --mount type=bind,source=/tmp,target=/usr nginx:latest afe70a7698112b93f0d5f200611b80dfe6c4f9e05ad1e8134183975d14428866 docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"nginx\": executable file not found in $PATH": unknown.
容器已建立但沒法啓動。去掉它:
$ docker container rm broken-container
對於某些開發應用程序,容器須要寫入綁定裝入,所以更改會傳播回Docker主機。在其餘時候,容器只須要讀訪問權限。
此示例修改上面的示例,但ro
經過在容器中的掛載點以後添加(默認狀況下爲空)選項列表,將目錄掛載爲只讀綁定掛載。若是存在多個選項,請用逗號分隔。
[root@benjamincloud ~]# docker run -dit --name devtest --mount type=bind,source="$(pwd)"/target,target=/app,readonly nginx:latest c77da99626fd7c8389cc09aee405951f3bd0837a7a78de9d1eb667da2a24cf5f
使用docker inspect devtest
驗證綁定安裝正確建立。尋找Mounts
部分:
綁定傳播默認rprivate
爲bind mounts和volume。這裏只配置 mount binds,而且僅適用於Linux主機。綁定傳播是一個高級主題,許多用戶永遠不須要配置它。
綁定傳播是指在給定的bind mounts或命名volume中建立的掛載是否能夠傳播到該裝載的副本。考慮一個掛載點/mnt
,掛載在/tmp
。
傳播設置控制是否/tmp/a
也可使用掛載/mnt/a
。每一個傳播設置都有一個遞歸對位。在遞歸的狀況下,請考慮將/tmp/a被
/foo掛載
。傳播設置控制/mnt/a
和/或/tmp/a是否
將存在。
傳播設置 | 描述 |
---|---|
shared |
原始掛載的子掛載將暴露給副本掛載,副掛載的副掛載也會傳播到原始掛載。 |
slave |
相似於共享掛載,但只在一個方向上。若是原始掛載程序公開子掛載,則副本掛載程序能夠看到它。可是,若是副本掛載公開子掛載,則原始掛載沒法看到它。 |
private |
掛載是私人的。其中的子掛載不會暴露給副本掛載,而子掛載中的副本掛載不會暴露給原始掛載。 |
rshared |
與共享相同,但傳播也擴展到嵌套在任何原始掛載點或副本中的掛載點。 |
rslave |
與從屬相同,但傳播也延伸到嵌套在任何原始掛載點或副本掛載點。 |
rprivate |
默認值。與private相同,意味着原始或副本掛載點中任何位置的掛載點都不會沿任一方向傳播。 |
在你掛載點設置綁定傳播以前,主機文件系統須要已經支持綁定傳播。
有關綁定傳播的更多信息,請參閱共享子樹的 Linux內核文檔。
如下示例將target/
目錄掛載到容器兩次,第二個掛載同時設置ro
選項和rslave
綁定傳播選項。
這些--mount
和-v
示例具備相同的結果。
[root@benjamincloud ~]# docker run -dit --name devtest --mount type=bind,source="$(pwd)"/target,target=/app --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave nginx:latest
如今,若是你建立/app/foo/
,/app2/foo/
也存在
[root@benjamincloud ~]# mkdir target/foo [root@benjamincloud ~]# docker exec devtest ls /app2/ foo [root@benjamincloud ~]# docker exec devtest ls /app/ foo
果使用selinux
,能夠添加z
或Z
選項以修改要裝入容器的主機文件或目錄的selinux標籤。這會影響主機自己上的文件或目錄,而且可能會產生Docker範圍以外的後果。
z
選項表示綁定裝載內容在多個容器之間共享。Z
選項表示綁定裝載內容是私有且非共享的。使用極端謹慎使用這些選項。綁定安裝系統目錄(例如/home
或/usr
使用該Z
選項)會致使主機沒法運行,您可能須要手動從新標記主機文件。
重要提示:將bind mounts與服務一塊兒使用時,selinux標籤(:Z
和:z
)以及將:ro
被忽略。
此示例設置z
選項以指定多個容器能夠共享綁定裝載的內容:
沒法使用--mount
標誌修改selinux標籤。
[root@benjamincloud ~]# docker run -itd --name devtest -v "$(pwd)"/target:/app:z nginx:latestecb63dfecfdb2602ee32c6e6a34930f86501a052a58fe0da8aacad1f31ecfdeb[root@benjamincloud ~]# docker run -itd --name devtest2 -v "$(pwd)"/target:/app:z nginx:latest3427fa5a5ff671454a64186d2cb8fda0553e6c7e912559d43265dd8724cbc2db[root@benjamincloud ~]# docker run -itd --name devtest3 -v "$(pwd)"/target:/app:z nginx:latest 78abe5d52173bc7cc327983cbb9dac5bdc9bc3cb164fa4fb6940215299191be5