docker從零開始 存儲(三)bind mounts
使用bind mounts
自Docker早期以來bind mounts 一直存在。與volumes相比,綁定掛載具有有限的功能。使用bind mounts時,主機上的文件或目錄將裝入容器中。文件或目錄由其在主機上的完整路徑或相對路徑引用。相反,當您使用卷時,會在主機上的Docker存儲目錄中創建一個新目錄,Docker會管理該目錄的內容。
該文件或目錄不需要已存在於Docker主機上。如果它尚不存在,則按需創建。綁定掛載非常高效,但它們依賴於具有特定目錄結構的主機文件系統。如果您正在開發新的Docker應用程序,請考慮使用命名卷。您無法使用Docker CLI命令直接管理bind mounts。
選擇-v或--mount標誌
最初,-v
或者--volume
標誌用於獨立容器,--mount
標誌用於群集服務。但是,從Docker 17.06開始,您還可以使用--mount
獨立容器。一般來說, --mount
更明確和冗長。最大的區別在於-v
語法將所有選項組合在一個字段中,而--mount
語法將它們分開。以下是每個標誌的語法比較。
具體的用法 和 差異請參看上一節以介紹。
使用綁定裝載啟動容器
考慮具有一個source目錄的情況,並在構建源代碼時將構建的代碼保存到另一個目錄source/target/
中,您希望這個構建代碼可用於容器/app/
,
並且您希望容器在每次構建源時都能訪問新構建在開發主機上。target/
目錄綁定到容器中/app/
。從source
目錄中運行命令 。
該$(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
部分:
這表明mount是一個bind
mount,它顯示了正確的源和目標,它表明mount是讀寫的,並且傳播設置為rprivate
。
停止容器刪除容器:
$ 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
使用只讀bind mounts
對於某些開發應用程序,容器需要寫入綁定裝入,因此更改會傳播回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:latest
ecb63dfecfdb2602ee32c6e6a34930f86501a052a58fe0da8aacad1f31ecfdeb
[root@benjamincloud ~]# docker run -itd --name devtest2 -v "$(pwd)"/target:/app:z nginx:latest
3427fa5a5ff671454a64186d2cb8fda0553e6c7e912559d43265dd8724cbc2db
[root@benjamincloud ~]# docker run -itd --name devtest3 -v "$(pwd)"/target:/app:z nginx:latest
78abe5d52173bc7cc327983cbb9dac5bdc9bc3cb164fa4fb6940215299191be5
docker從零開始 存儲(三)bind mounts