Docker 學習筆記(第五集:資料卷)

chenggx發表於2020-09-03

這一集下先從一張圖開始

資料管理

這張圖來自於 docker 官方,主要描述了主機和 docker 間的資料溝通的 3 種方式。分別是 bind mountvolumetmpfs mount。這次主要學習前兩種方式。讓我們開始吧~

volume (資料卷)

以下內容摘抄自 docker 官方文件

我們知道預設情況下,在容器內建立的所有檔案都儲存在可寫容器層上,這意味著:

  • 當容器不再存在時,資料不會持久存在,而且如果另一個程式需要資料,就很難從容器中取出資料。

  • 容器可寫層與容器執行的主機緊密耦合。您不能輕易地將資料移動到其他地方。

  • 寫入到容器的可寫層需要一個儲存驅動程式來管理檔案系統。儲存驅動程式提供使用Linux核心的聯合檔案系統。與使用直接寫入主機檔案系統的資料卷相比,這種額外的抽象降低了效能。

通過上面的內容告訴我們,不要在容器內容寫入資料,而要使用 volume

那麼資料卷是怎麼儲存資料的呢?

docker 預設在主機上會有一個特定的區域 /var/lib/docker/volumes/ (Linux),該區域用來存放 volume。

例項演示


// 建立一個 volume 名為 my-data

$ docker volume create my-data

my-data

// 建立一個 名為 nginx1 的 nginx 容器並使用 my-data 為 nginx 的主目錄

$ docker run -d -p 8080:80 --name nginx1 --mount source=nginx-data,target=/usr/share/nginx/html nginx

814dea34b7dbf2afd724d12ad50254e2a749f0b65684f04c730ac04181857d04

// 檢視容器的狀態

$ docker container ls --format "table {{.Image}}\t{{.ID}}\t{{.Status}}\t{{.Names}}"

IMAGE CONTAINER ID STATUS NAMES

nginx 814dea34b7db Up 3 minutes nginx1

// 進入 nginx1 容器

$ docker exec -it nginx1 bash

// 修改 index.html 內容為 hello world

# echo hello world > /usr/share/nginx/html/index.html

// 訪問 http://127.0.0.1:8080 我們可以看到 hello world 頁面

// 刪除 nginx1 容器

$ docker rm -f nginx1

// 建立一個 名為 nginx2 的 nginx 容器也使用 my-data 為 nginx 的主目錄

$ docker run -d -p 8080:80 --name nginx2 --mount source=nginx-data,target=/usr/share/nginx/html nginx

// 訪問 http://127.0.0.1:8080 我們也可以看到 hello world 頁面(資料共享)

通過上面的例項我們知道了:

  1. volume 和容器是分離的,刪除容器並不會刪除 volume

  2. 多個容器可以載入相同的卷

  3. volume 在任何系統的容器上都能工作,方便遷移

資料卷常用命令

  • 檢視所有資料卷 bash docker volume ls

  • 建立資料卷 bash docker volume create [卷名稱]

  • 檢視卷詳情 bash docker volume inspect <卷名稱>

  • 刪除資料卷 bash docker volume rm <卷名稱>

  • 刪除無主的卷 bash docker volume prune

溫馨提示:-v 和 –mount 的區別 (因為官方建議新使用者使用 –mount,所以本文只記錄 –mount 的使用方式)

在檢視網上的各種資料的時候發現有人用 -v 引數而有的人又用 –mount 引數,為了確認他們之間的區別我特意查了一下 docker 官網,現在把內容放出來

  • 最初,-v 或–volume 引數用於獨立容器,而 –mount 引數用於群服務。 但是,從 Docker 17.06 開始,您也可以將 –mount 用於獨立容器。 通常,–mount 更為明確和詳細。 他們直接最大的區別是 -v 語法在一個欄位中將所有選項組合在一起,而 –mount 語法將它們分開。

  • 新使用者應該嘗試—mount語法,它比—卷語法更簡單。


上面的內容主要講述的是 local 驅動下的 volume,實際上 volume 還可以使用其他的驅動,這裡先記錄一下,後面在在繼續學習。

bind mount 掛載主機目錄

該方式實際上是將主機上的一個目錄對映到容器中的一個目錄。(使用過虛擬機器的朋友應該比較熟悉)

如果將空檔案或目錄掛載到容器,容器中的該目錄又有檔案,那麼,這些檔案將會被複制到主機上的目錄中。如果將非空的檔案或目錄掛載到容器,容器中的該目錄也有檔案,那麼,容器中的檔案將會被隱藏。

例項演示


// 在主機上建立一個 my-data 目錄

$ mkdir ~/my-data

// 建立一個 名為 nginx3 的 nginx 容器並掛載 my-data 為 nginx 的主目錄

$ cd ~

$ docker run -d -p 8080:80 --name nginx3 --mount type=bind,source="$(pwd)"/my-data,target=/usr/share/nginx/html nginx

// 在 my-data 目錄中建立 index.html 並寫入內容

$ touch my-data/index.html

$ echo hello bind  type > my-data/index.html

// 使用瀏覽器訪問 http://127.0.0.1:8080 可以正常顯示 hello bind  type

// 檢視 nginx3 容器的詳情,注意 mounts 部分,很清晰的顯示了繫結的關係

$ docker inspect nginx3

......

"Mounts":[

{

"Type":"bind",

"Source":"/Users/cc/my-data",

"Target":"/usr/share/nginx/html"

}

]

......

tmpfs 方式 (以後學習)

tmpfs,僅儲存在主機系統的記憶體中,不會寫入主機的檔案系統。


程式設計師的藝術人生

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章