這一集下先從一張圖開始
這張圖來自於 docker 官方,主要描述了主機和 docker 間的資料溝通的 3 種方式。分別是 bind mount、volume、tmpfs 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 頁面(資料共享)
透過上面的例項我們知道了:
volume 和容器是分離的,刪除容器並不會刪除 volume
多個容器可以載入相同的卷
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 協議》,轉載必須註明作者和本文連結