儲存空間
預設情況下,容器內建立的所有檔案都儲存在可寫入的容器層中。這表示
- 當該容器不再存在時,資料不會保留,而且如果其他程序需要該資料,可能難以從容器中取得。
- 容器的可寫入層與執行容器的主機緊密耦合。您無法輕鬆地將資料移到其他地方。
- 寫入容器的可寫入層需要使用儲存驅動程式來管理檔案系統。儲存驅動程式使用 Linux 核心提供聯集檔案系統。與直接寫入主機檔案系統的資料磁碟區相比,這種額外的抽象化會降低效能。
Docker 提供了兩個選項,讓容器將檔案儲存在主機上,以便即使在容器停止後也能保留檔案:磁碟區和繫結掛載。
Docker 也支援容器將檔案儲存在主機的記憶體中。此類檔案不會被保留。如果您在 Linux 上執行 Docker,則會使用 tmpfs
掛載將檔案儲存在主機的系統記憶體中。如果您在 Windows 上執行 Docker,則會使用命名管道將檔案儲存在主機的系統記憶體中。
選擇正確的掛載類型
無論您選擇使用哪種類型的掛載,資料在容器內看起來都相同。它會在容器的檔案系統中顯示為目錄或個別檔案。
視覺化磁碟區、繫結掛載和 tmpfs
掛載之間差異的簡單方法是考慮資料在 Docker 主機上的位置。


磁碟區儲存在 Docker管理的主機檔案系統的一部分中 (Linux 上的
/var/lib/docker/volumes/
)。非 Docker 程序不應修改檔案系統的這一部分。磁碟區是在 Docker 中保存資料的最佳方式。繫結掛載可以儲存在主機系統上的任何位置。它們甚至可能是重要的系統檔案或目錄。Docker 主機或 Docker 容器上的非 Docker 程序可以隨時修改它們。
tmpfs
掛載僅儲存在主機系統的記憶體中,而且永遠不會寫入主機系統的檔案系統。
繫結掛載和磁碟區都可以使用 -v
或 --volume
旗標掛載到容器中,但每種語法略有不同。對於 tmpfs
掛載,您可以使用 --tmpfs
旗標。我們建議對容器和服務使用 --mount
旗標,無論是繫結掛載、磁碟區還是 tmpfs
掛載,因為語法更清晰。
磁碟區
磁碟區由 Docker 建立和管理。您可以使用 docker volume create
命令明確建立磁碟區,或者 Docker 可以在建立容器或服務期間建立磁碟區。
當您建立磁碟區時,它會儲存在 Docker 主機上的目錄中。當您將磁碟區掛載到容器中時,這個目錄就是掛載到容器中的內容。這與繫結掛載的工作方式類似,只是磁碟區由 Docker 管理,並且與主機的核心功能隔離。
一個指定的磁碟區可以同時掛載到多個容器中。當沒有正在執行的容器使用磁碟區時,該磁碟區仍然可供 Docker 使用,並且不會自動移除。您可以使用 docker volume prune
移除未使用的磁碟區。
當您掛載磁碟區時,它可以是具名的或匿名的。匿名磁碟區會被賦予一個隨機名稱,保證在指定的 Docker 主機內是唯一的。就像具名磁碟區一樣,即使您移除使用它們的容器,匿名磁碟區仍然存在,除非您在建立容器時使用 --rm
旗標,在這種情況下,匿名磁碟區會被銷毀。請參閱移除匿名磁碟區。如果您在彼此之後建立多個使用匿名磁碟區的容器,則每個容器都會建立自己的磁碟區。匿名磁碟區不會在容器之間自動重複使用或共用。若要在兩個或多個容器之間共用匿名磁碟區,您必須使用隨機磁碟區 ID 掛載匿名磁碟區。
磁碟區也支援使用磁碟區驅動程式,這允許您將資料儲存在遠端主機或雲端供應商上,以及其他可能性。
繫結掛載
與磁碟區相比,繫結掛載的功能有限。當您使用繫結掛載時,主機上的檔案或目錄會掛載到容器中。檔案或目錄由其在主機上的完整路徑來參考。檔案或目錄不需要事先存在於 Docker 主機上。如果它尚不存在,則會依需建立。繫結掛載速度很快,但它們依賴於主機的檔案系統具有特定的目錄結構。如果您正在開發新的 Docker 應用程式,請考慮改用具名磁碟區。您無法使用 Docker CLI 命令直接管理繫結掛載。
重要
繫結掛載預設允許對主機上的檔案進行寫入存取。
使用繫結掛載的一個副作用是,您可以透過在容器中執行的程序來更改主機檔案系統,包括建立、修改或刪除重要的系統檔案或目錄。這是一個強大的功能,可能會產生安全隱患,包括影響主機系統上非 Docker 的程序。
提示
正在使用大型儲存庫或單體儲存庫,或者使用不再能隨著您的程式碼庫擴展的虛擬檔案系統?請查看同步檔案共享。它透過使用同步檔案系統快取來增強繫結掛載效能,提供快速且彈性的主機到虛擬機器的檔案共享。
tmpfs
tmpfs
掛載不會在磁碟上持久化,無論是在 Docker 主機上還是在容器內。容器可以在其生命週期內使用它來儲存非持久性狀態或敏感資訊。例如,在內部,Swarm 服務使用 tmpfs
掛載將密鑰掛載到服務的容器中。
命名管道
命名管道 可用於 Docker 主機和容器之間的通訊。常見的用例是在容器內執行第三方工具,並使用命名管道連接到 Docker 引擎 API。
磁碟區的良好使用案例
磁碟區是在 Docker 容器和服務中持久化資料的首選方式。磁碟區的一些用例包括
在多個正在執行的容器之間共享資料。如果您沒有明確建立它,則磁碟區會在第一次掛載到容器時建立。當該容器停止或被移除時,磁碟區仍然存在。多個容器可以同時掛載相同的磁碟區,可以是讀寫或唯讀。只有在您明確移除磁碟區時,才會移除它們。
當 Docker 主機不保證具有給定的目錄或檔案結構時。磁碟區可幫助您將 Docker 主機的配置與容器執行階段分離。
當您想要將容器的資料儲存在遠端主機或雲端供應商上,而不是本地時。
當您需要將資料從一個 Docker 主機備份、還原或遷移到另一個 Docker 主機時,磁碟區是更好的選擇。您可以停止使用磁碟區的容器,然後備份磁碟區的目錄(例如
/var/lib/docker/volumes/<volume-name>
)。當您的應用程式在 Docker Desktop 上需要高效能 I/O 時。磁碟區儲存在 Linux 虛擬機器中,而不是主機中,這表示讀寫具有更低的延遲和更高的吞吐量。
當您的應用程式在 Docker Desktop 上需要完全原生檔案系統行為時。例如,資料庫引擎需要精確控制磁碟刷新以保證交易持久性。磁碟區儲存在 Linux 虛擬機器中,可以做出這些保證,而繫結掛載則遠端到 macOS 或 Windows,其中檔案系統的行為略有不同。
繫結掛載的良好使用案例
一般來說,您應該盡可能使用磁碟區。繫結掛載適用於以下類型的用例
將主機的設定檔共享到容器。這是 Docker 預設情況下透過將主機的
/etc/resolv.conf
掛載到每個容器中來提供 DNS 解析的方式。在 Docker 主機上的開發環境和容器之間共享程式碼或建置成品。例如,您可以將 Maven
target/
目錄掛載到容器中,並且每次您在 Docker 主機上建置 Maven 專案時,容器都可以存取重建的成品。如果您以這種方式使用 Docker 進行開發,您的生產 Dockerfile 會將生產就緒的成品直接複製到映像中,而不是依賴繫結掛載。
當 Docker 主機的檔案或目錄結構保證與容器所需的繫結掛載一致時。
tmpfs 掛載的良好使用案例
當您不希望資料持久化在主機或容器內時,tmpfs
掛載最適用。這可能是出於安全原因,或者是在您的應用程式需要寫入大量非持久性狀態資料時保護容器的效能。
使用繫結掛載或磁碟區的訣竅
如果您使用繫結掛載或磁碟區,請記住以下幾點
如果您將**空的磁碟區**掛載到容器中存在檔案或目錄的目錄中,這些檔案或目錄將會被傳播(複製)到磁碟區中。同樣,如果您啟動一個容器並指定一個尚不存在的磁碟區,則會為您建立一個空的磁碟區。這是一種預先填入另一個容器所需資料的好方法。
如果您將**繫結掛載或非空的磁碟區**掛載到容器中存在某些檔案或目錄的目錄中,這些檔案或目錄將會被掛載遮蔽,就像您將檔案儲存到 Linux 主機上的
/mnt
中,然後將 USB 隨身碟掛載到/mnt
中一樣。/mnt
的內容將會被 USB 隨身碟的內容遮蔽,直到 USB 隨身碟被卸載為止。被遮蔽的檔案不會被移除或更改,但在繫結掛載或磁碟區掛載時無法存取。