前言
學(xué)習(xí)本文需要一些了解Docker的概念以及一些名詞。
個(gè)人網(wǎng)站:https://linzyblog.netlify.app/
一、在Docker中管理數(shù)據(jù)
1、為什么要掛載?
默認(rèn)情況下,在容器內(nèi)創(chuàng)建的所有文件都存儲(chǔ)在可寫容器層上。這意味著:
- 當(dāng)該容器被刪除時(shí),數(shù)據(jù)也會(huì)被同樣刪除,如果有另一個(gè)進(jìn)程需要數(shù)據(jù),就很難從容器中取出數(shù)據(jù)。
- 容器的可寫層與運(yùn)行容器的宿主機(jī)緊密耦合,你無(wú)法將數(shù)據(jù)移動(dòng)到其他地方。
- 寫入容器的可寫層需要存儲(chǔ)驅(qū)動(dòng)程序來(lái)管理文件系統(tǒng)。存儲(chǔ)驅(qū)動(dòng)程序提供了一個(gè)聯(lián)合文件系統(tǒng),使用 Linux 內(nèi)核。與使用直接寫入主機(jī)文件系統(tǒng)的數(shù)據(jù)卷相比,這種額外的抽象會(huì)降低性能 。
Docker有兩種方法:volumes 卷 和 bind mounts 綁定掛載 可以讓容器在主機(jī)上存儲(chǔ)文件,以便即使容器停止或刪除后文件也能持久化保存。
Docker 還支持將文件存儲(chǔ)在主機(jī)內(nèi)存中的容器。此類文件不會(huì)持久保存。如果您在 Linux 上運(yùn)行 Docker,則使用tmpfs 掛載將文件存儲(chǔ)在主機(jī)的系統(tǒng)內(nèi)存中。如果您在 Windows 上運(yùn)行 Docker,命名管道用于將文件存儲(chǔ)在主機(jī)的系統(tǒng)內(nèi)存中。
2、選擇正確的掛載方式
無(wú)論你選擇那種掛載的方式,容器內(nèi)的數(shù)據(jù)看起來(lái)都是一樣的。數(shù)據(jù)以目錄或文件系統(tǒng)中的單個(gè)文件的形式公開(kāi)。
卷(volumes)、綁定掛載(bind mounts)和 tmpfs掛載(tmpfs mounts) 之間的差異就是數(shù)據(jù)在Docker主機(jī)上的位置不同。
- 卷(volumes):存儲(chǔ)在由 Docker(/var/lib/docker/volumes/在 Linux 上)管理的主機(jī)文件系統(tǒng)的一部分中。非 Docker 進(jìn)程不應(yīng)修改文件系統(tǒng)的這一部分。卷是在 Docker 中持久化數(shù)據(jù)的最佳方式。
- 綁定掛載(bind mounts):可以存儲(chǔ)在主機(jī)系統(tǒng)的任何位置。它們甚至可能是重要的系統(tǒng)文件或目錄。Docker 主機(jī)或 Docker 容器上的非 Docker 進(jìn)程可以隨時(shí)修改它們。
- tmpfs掛載(tmpfs mounts):僅存儲(chǔ)在主機(jī)系統(tǒng)的內(nèi)存中,永遠(yuǎn)不會(huì)寫入主機(jī)系統(tǒng)的文件系統(tǒng)。
二、卷(volume)
1、卷的概述
卷(volume)提供了將容器的特定文件系統(tǒng)路徑連接回主機(jī)的能力,簡(jiǎn)單來(lái)說(shuō)就是將容器的目錄映射到主機(jī)上。如果容器中的目錄已掛載,則該目錄中的更改也會(huì)在主機(jī)上看到。如果我們?cè)谌萜髦貑r(shí)掛載相同的目錄,我們會(huì)看到相同的文件,這就是容器的持久化和同步操作。
- Docker Volume 命令能讓容器從宿主機(jī)中讀取文件,或從容器中持久化數(shù)據(jù)到宿主機(jī)中,讓容器與容器產(chǎn)生的數(shù)據(jù)分離開(kāi)來(lái),一個(gè)容器可以掛載多個(gè)不同的目錄。
- Volume的生命周期是獨(dú)立于容器的生命周期之外的,即使容器刪除了,Volume也會(huì)被保留下來(lái),Docker不會(huì)因?yàn)檫@個(gè)Volume沒(méi)有被容器使用而自動(dòng)回收。
- 在容器中,添加或修改這個(gè)文件夾里的文件也不會(huì)影響到容器的聯(lián)合文件系統(tǒng)。
2、卷的優(yōu)點(diǎn)
卷是Docker容器生成和使用數(shù)據(jù)的首選保存機(jī)制。綁定掛載依賴于主機(jī)的目錄結(jié)構(gòu)和操作系統(tǒng),但卷是完全由Docker管理。
- 卷比綁定掛載更容易備份或遷移數(shù)據(jù)。
- 卷可以直接使用Docker CLI 命令或 Docker API 管理。
- 卷可以在 Linux 和 Windows 容器上運(yùn)行。
- 卷可以在多個(gè)容器之間更安全的共享。
- 卷允許將卷掛載到遠(yuǎn)程主機(jī)或云服務(wù)器上,以加密卷的內(nèi)容或添加其他功能。
- 新卷的內(nèi)容可以由容器預(yù)先填充。
- Docker Desktop 上的卷比 來(lái)自Mac 和 Windows 主機(jī)的綁定掛載具有更高的性能。
此外,與將數(shù)據(jù)持久化到容器的可寫層相比,卷通常是更好的選擇,因?yàn)榫聿粫?huì)增加使用它的容器的大小,而且卷的內(nèi)容存在于給定容器的生命周期之外
注意:如果你的容器需要生成非持久化狀態(tài)數(shù)據(jù),優(yōu)先選擇tmpfs 掛載以避免將數(shù)據(jù)永久存儲(chǔ)在任何地方,并且避免寫入容器的可寫層來(lái)提高容器性能。
3、卷的使用
- 格式:
docker run -it -v 主機(jī)目錄:容器內(nèi)目錄
- 測(cè)試:
- 使用卷將容器內(nèi)/home目錄掛載綁定到主機(jī)的E:/home/test目錄下,Docker會(huì)自動(dòng)在主機(jī)創(chuàng)建目錄
- 用docker inspect 命令查看容器掛載數(shù)據(jù),找到Mounts數(shù)據(jù)
- Type:掛載的類型,可以是bind、volume或 tmpfs。
- Source:主機(jī)內(nèi)目錄路徑地址。
- Destination:Docker容器內(nèi)目錄的路徑地址。
- 在容器的/home目錄下進(jìn)行操作
在主機(jī)目錄也會(huì)同時(shí)創(chuàng)建一個(gè)test.go。
這是同步的過(guò)程,雙方目錄掛載后,雙方各自的操作是雙向綁定的。
- 停止Docker 容器后,修改主機(jī)目錄內(nèi)的文件內(nèi)容,啟動(dòng)容器后,數(shù)據(jù)是否還是會(huì)同步到容器
是可以的,掛載目錄是雙向綁定的,以后只需在本地修改即可,容器內(nèi)也會(huì)自動(dòng)同步
4、實(shí)戰(zhàn):持久化數(shù)據(jù)
1)MySQL容器為什么掛載數(shù)據(jù)卷?
我們每次啟動(dòng)一個(gè)MySQL容器,數(shù)據(jù)庫(kù)都是空的。刪除容器后,數(shù)據(jù)也同樣丟失,如果有其他進(jìn)程也在訪問(wèn)這個(gè)數(shù)據(jù)庫(kù),就會(huì)取不出數(shù)據(jù)。
數(shù)據(jù)卷:設(shè)計(jì)用來(lái)持久化數(shù)據(jù)的,它的生命周期獨(dú)立于容器,不會(huì)因?yàn)槿萜鞅粍h除后自動(dòng)刪除,并且也不存在垃圾回收這樣的機(jī)制來(lái)處理沒(méi)有任何容器引用的 數(shù)據(jù)卷。
2)MySQL容器掛載數(shù)據(jù)卷
- 拉取MySQL鏡像,運(yùn)行容器的時(shí)候做掛載數(shù)據(jù)卷,啟動(dòng)MySQL容器需要配置密碼
docker run -d -p 3310:3306 -v E:/home/mysql/conf:/etc/mysql/conf.d -v E:/home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysqltest mysql:5.7
可選項(xiàng)名稱 | 說(shuō)明 |
---|---|
-d | 在后臺(tái)運(yùn)行容器并打印容器 ID |
-p | -p xxxx:yyyy:宿主機(jī)上xxxx端口對(duì)應(yīng)容器中yyyy端口,在外部訪問(wèn)時(shí)用的是宿主機(jī)上的端口 |
-v | 卷掛載 |
-e | 環(huán)境配置 |
–name | 容器名稱 |
- 啟動(dòng)容器成功之后,本地用navicat連接數(shù)據(jù)庫(kù)測(cè)試一下
3. 新建一個(gè)test數(shù)據(jù)庫(kù),建立test數(shù)據(jù)表,并插入幾條數(shù)據(jù)。
- 刪除MySQL容器,在重新運(yùn)行后,測(cè)試一下數(shù)據(jù)是否還存在,數(shù)據(jù)是否是持久化的。
我們可以看到數(shù)據(jù)依舊存在,我們掛載在本地的數(shù)據(jù)并沒(méi)有隨著容器的刪除而丟失,它的生命周期已經(jīng)獨(dú)立于容器,這就實(shí)現(xiàn)了容器數(shù)據(jù)持久化。
5、Volume命令
1)docker volume create
- 作用:創(chuàng)建數(shù)據(jù)卷
- 格式:
docker volume create [OPTIONS] [卷名]
- 說(shuō)明
創(chuàng)建容器可以使用和存儲(chǔ)數(shù)據(jù)的新卷。如果未指定名稱,Docker 會(huì)生成一個(gè)隨機(jī)名稱。
- 可選項(xiàng):
名稱,簡(jiǎn)寫 | 默認(rèn) | 描述 |
---|---|---|
–driver,-d | local | 指定卷驅(qū)動(dòng)程序名稱 |
–label | 為卷設(shè)置元數(shù)據(jù) | |
–name | 指定卷名 | |
–opt,-o | 設(shè)置驅(qū)動(dòng)程序特定選項(xiàng) |
- 例子:
2)docker volume inspect
- 作用:顯示一個(gè)或多個(gè)卷的詳細(xì)信息
- 格式:
docker volume inspect [OPTIONS] 卷名 [卷名...]
- 說(shuō)明:
返回有關(guān)卷的信息。默認(rèn)情況下,此命令將所有結(jié)果呈現(xiàn)在 JSON 數(shù)組中。您可以指定替代格式來(lái)為每個(gè)結(jié)果執(zhí)行給定的模板。Go 的 text/template包描述了該格式的所有細(xì)節(jié)。
- 可選項(xiàng):
名稱,簡(jiǎn)寫 | 默認(rèn) | 描述 |
---|---|---|
–format,-f | 使用給定的 Go 模板格式化輸出 |
- 例子:
- 當(dāng)你創(chuàng)建一個(gè)Volume,Docker都會(huì)默認(rèn)在宿主機(jī)的/var/lib/docker/volumes目錄下自動(dòng)創(chuàng)建一個(gè)子目錄,默認(rèn)情況下都是目錄名都是一串UUID。
- 如果指定了名稱,則目錄名是Volume名稱。Volume里的數(shù)據(jù)都存儲(chǔ)在這個(gè)子目錄的_data目錄下。
3)docker volume ls
- 作用:查看本地?cái)?shù)據(jù)卷列表
- 格式:
docker volume ls [OPTIONS]
- 說(shuō)明:
列出 Docker 已知的所有卷??梢允褂?-f or --filter標(biāo)志進(jìn)行過(guò)濾。
- 可選項(xiàng):
名稱,簡(jiǎn)寫 | 默認(rèn) | 描述 |
---|---|---|
–filter,-f | 提供過(guò)濾器值(例如 ‘dangling=true’) | |
–format | 使用 Go 模板格式化打印卷 | |
–quiet,-q | 只顯示卷名 |
- 例子:
4)docker volume prune
- 作用:刪除所有未使用的本地卷
- 格式:
docker volume prune [OPTIONS]
- 說(shuō)明:
刪除所有未使用的本地卷。未使用的本地卷是那些未被任何容器引用的本地卷
- 可選項(xiàng):
名稱,簡(jiǎn)寫 | 默認(rèn) | 描述 |
---|---|---|
–filter | 提供過(guò)濾器值(例如 ‘label= | |
–force,-f | 不提示確認(rèn) |
- 例子:
5)docker volume rm
- 作用:刪除一個(gè)或多個(gè)卷
- 格式:
docker volume rm [OPTIONS] 卷名[卷名...]
- 說(shuō)明:
刪除一個(gè)或多個(gè)卷。您不能刪除容器正在使用的卷。
- 可選項(xiàng):
名稱,簡(jiǎn)寫 | 默認(rèn) | 描述 |
---|---|---|
–force,-f | 強(qiáng)制刪除一個(gè)或多個(gè)卷 |
- 例子:
6、匿名掛載和具名掛載
1)匿名掛載
沒(méi)有給數(shù)據(jù)卷名字的掛載。
除了最后一條由具體名字的掛載,其他都是匿名掛載的
格式:
docker run -d -P -v 容器內(nèi)路徑 鏡像名:tag1
2)具名掛載
給數(shù)據(jù)卷指定名字的掛載。
最后一條是具名掛載的數(shù)據(jù)卷
格式:
docker run -d -P --name 容器名稱 -v 卷名稱:容器內(nèi)路徑 鏡像名:tag
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-511623.html
3)如何區(qū)分掛載?
如何區(qū)分匿名掛載、具名掛載還是指定路徑掛載呢?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-511623.html
- 匿名掛載:-v 容器內(nèi)路徑
- 具名掛載 :-v 卷名:容器內(nèi)路徑
- 指定路徑掛載:-v /宿主機(jī)路徑:容器內(nèi)路徑
到了這里,關(guān)于Docker(五)進(jìn)階:Docker卷(volumes)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!