返回部落格

在 Docker 容器之間共享資料

在 Docker 容器之間共享資料

簡介

Docker 是一個容器平台,它是一個輕量級、虛擬化、可攜式、軟體定義的標準化環境,允許軟體與運行在實體主機上的其他軟體隔離運行。Docker 是軟體開發中持續開發與整合(CI/CD)維度的關鍵組成部分。透過提供一致的執行環境,Docker 確保軟體無論部署在何種實體主機上,其行為都保持一致。如需深入的 Docker 生態系統概述,請參閱這篇文章.

雖然 Docker 容器是獨立的,但有時它們需要共享數據的存取權限,或者在容器停止後將數據持久化到磁碟。數據可以是資料庫、日誌檔案或使用者產生的數據的形式。此類數據無法包含在 Docker 映像檔設定檔中,但它需要可供您的應用程式使用以按預期運行。在 Docker 容器中共享和持久化數據是由 Docker Volumes 處理的。Docker 數據卷可以在創建容器時創建,也可以在稍後創建並掛載到容器中。 在本教學中,我們將討論在容器之間共享數據的四種不同方法。

先決條件

請注意,雖然我們使用的是 Ubuntu 20.04,但只要按照上述先決條件中的說明安裝了 Docker 並將 sudo 使用者添加到 docker 群組中,Docker 的指令和命令就可以在任何其他作業系統上運行。

步驟 1:創建獨立的 Docker 數據卷

我們將首先創建與任何 Docker 容器無關的獨立數據卷。為此,我們可以使用在 Docker 1.9 版本中引入的命令 docker volume create。輸入以下命令以創建一個名為 Step1DataVolume :

您應該會看到以下輸出,表示數據卷創建成功:

Docker Volume Create

現在我們有了獨立的數據卷,我們可以從官方 Ubuntu 映像檔創建一個新容器作為示例來使用它。輸入以下命令以創建容器並掛載該數據卷:

在此命令中, --rm 旗標將在退出後自動刪除容器。而 -v 旗標用於指定和掛載數據卷。 -v 旗標接受數據卷的名稱、一個冒號以及數據卷在容器中應出現的絕對路徑。請記住,當命令運行時,如果路徑中指定的目錄不存在,它們將被創建。如果它們已經存在,掛載的數據卷將隱藏現有的內容。對於 -ti 旗標, -t 提供對終端機的存取權限,而 -i 允許我們透過終端機與容器進行互動。

在容器內部時,運行以下命令將一些數據寫入數據卷:

輸入 exit 並按下 enter 以退出容器。如前所述,由於使用了 --rm 旗標,容器在您退出時會自動刪除,但數據卷仍然可以存取。

要驗證數據卷是否仍然存在,您可以使用 docker volume inspect 命令:

您應該會看到以下輸出:

Docker Volume Inspect

接下來,讓我們創建一個新容器。首先,掛載該數據卷,看看我們是否可以存取在上一個容器中創建的文字。輸入以下命令,使用 ubuntu 映像檔:

在容器內,執行以下命令以驗證 StepOne.txt 檔案是否存在:

您應該會看到類似的輸出:

Docker Volume Content 1

接下來,輸入 exit 並按下 enter 以退出容器。在此步驟中,您學習了如何使用獨立的 Docker 資料卷來處理資料持久化,以及如何將資料卷掛載到容器中。

步驟 2:建立一個在刪除容器時仍能保留資料的 Docker 資料卷

在此步驟中,我們將使用單一命令在建立容器的同時建立資料卷。然後,我們將刪除該容器並將該資料卷掛載到新的容器。此命令與在以下步驟中使用的命令類似:步驟 1,但是,我們新增了一個旗標 --name,以指定容器的名稱:

在容器內部時,輸入以下命令將資料寫入資料卷,並驗證資料是否存在:

以下是這三個命令的輸出:

Persistent Docker Volume

接下來,退出容器。當您使用以下命令重新啟動容器時,資料卷將會自動掛載:

在容器內,透過檢查 StepTwo.txt 檔案是否存在,以驗證資料卷是否已掛載,命令如下:

以下是輸出:

Docker Volume After Restart

您現在可以退出容器。Docker 會阻止刪除其他容器正在引用的資料卷。您可以嘗試使用以下命令來刪除資料卷:

您應該會在輸出中看到錯誤訊息:

Error Response

讓我們使用輸出中顯示的容器 ID,並搭配 docker rm 命令來刪除容器:

請將醒目提示的 container id 替換為您終端機中顯示的容器 id。該命令會刪除容器,但不會刪除我們建立的資料卷。您可以使用 docker volume ls 命令列出可用的資料卷以進行驗證:

以下是輸出:

Docker Volume List

要刪除在 步驟 2 中建立的容器,請輸入以下命令:

在此步驟中,您能夠在建立容器的同時建立 Docker 資料卷。讓我們來看看如何從含有資料的現有目錄中建立資料卷。

步驟 3:從含有資料的現有目錄中建立 Docker 資料卷

如果您想將資料複製到資料卷中,您可以在建立容器的同時建立資料卷,並提供基礎映像檔中包含該資料的目錄路徑。在下方的命令中,我們建立了一個容器,並在 /var 新增了一個資料卷,這是基礎映像檔中包含資料的目錄:

當命令執行時,基礎映像檔的 /var 目錄中的內容將會被複製到資料卷中。該資料卷可以掛載到新的容器。接下來,退出容器:

Create Docker Volume

輸入以下命令以建立容器、掛載資料卷,並使用 ls 命令列出資料卷的內容:

您應該會從命令中看到類似的輸出,這是基礎映像檔中 /var 目錄內容的複本,現在已可在 Step3DataVolume:

Copy Docker Volume

雖然掛載 /var 目錄(如我們在此範例中所做的那樣)可能不切實際,但它有助於我們理解,您可以將自訂映像檔中建立的任何目錄掛載到 Docker 磁碟卷,以便其他容器可以使用該資料。

步驟 4:在多個 Docker 容器之間共享資料

在大多數情況下,您會希望多個容器存取同一個 Docker 磁碟卷中的資料。在先前的範例中,我們僅將磁碟卷連接到一個容器。現在,您將學習如何將磁碟卷連接到多個容器。雖然您可以輕鬆實現這一點,但 Docker 並不處理檔案鎖定。對於寫入同一個磁碟卷的多個容器,您必須單獨設計在這些容器中執行的應用程式,以處理寫入共享資料儲存庫的操作,從而避免資料損壞。

  • 建立 Step4Container1Step4DataVolume

使用 docker run 指令搭配 --name 旗標來建立具名容器:

在容器內,執行以下指令以建立文字檔並新增一些文字:

之後,退出容器並返回主機環境。現在,我們想建立另一個容器,並將 Step4Container1 的磁碟卷掛載到其中。

  • 建立 Step4Container2 並連接來自容器 Step4Container1

執行以下指令以建立 Step4Container2 並掛載來自 Step4Container1:

在容器內,使用 cat 指令來驗證資料持久性:

您應該會看到以下輸出:

Container Data Sharing

我們可以從 Step4Container2 輸入以下指令來向檔案附加更多文字:

在此之後退出容器,我們將返回 Step4Container1 以檢查資料是否仍然存在。

  • 驗證不同容器之間在 Docker 磁碟卷中所做的變更

要檢視變更,您首先要重新啟動 Step4Container1 ,使用指令:

使用以下指令檢查變更:

您應該會看到類似於下方螢幕截圖的輸出:

Copied Container Data

一旦您驗證了兩個容器都可以讀取和寫入同一個磁碟卷,您現在就可以退出容器。如前所述,Docker 並不處理檔案鎖定,處理共享資料儲存庫的讀寫存取應該是在容器內執行的應用程式邏輯的工作。Docker 允許將磁碟卷掛載為唯讀,以防止僅需要唯讀存取的容器意外損壞資料,方法是新增 :ro ,如接下來的範例所示。

  • 將磁碟卷掛載到 Docker 容器為唯讀

在此範例中,我們將建立一個名為 Step4Container3 的容器。在建立指令中,我們掛載來自 Step4Container1 的磁碟卷,並新增 :ro 以指定此容器具有唯讀存取權限,但無法寫入該磁碟卷。在您的終端機中執行以下指令:

進入容器後,您可以透過輸入以下指令來讀取磁碟卷中的文字檔:

Read Only Mount

然而,如果您嘗試使用以下指令刪除該檔案:

您將在終端機中收到如下錯誤訊息:

Read Only Error

驗證讀寫權限後,您可以退出容器。如果您想清理本教學中建立的容器和資料卷,請執行以下命令:

在此步驟中,您學習了如何使用 Docker 資料卷在多個容器之間共享資料,以及如何將資料卷以唯讀方式掛載到容器中。

結論

在本教學中,您建立了多個 Docker 資料卷,並學習了如何在 Docker 容器之間共享資料。在處理容器之間的資料共享時,我們注意到容器內部的個別應用程式邏輯必須處理檔案鎖定,以防止在寫入共享資料儲存時發生資料損壞,因為 Docker 沒有處理檔案鎖定的實作。

如需有關使用 Docker 的更多資源,您可能需要查看更多教學,位於 我們的部落格:

祝您運算愉快!

author

Pranay Kapgate

作者 · CloudSigma

Preslav Dobrev 是 CloudSigma 的創意設計師,專注於透過傳統與創新行銷渠道建立一致的企業形象。他擅長將藝術願景與策略行銷相融合,創造具有影響力的品牌敘事。

留言

目前尚無留言。成為第一個留言的人吧。