Docker?Volume的用法看這一篇就夠了
1. 簡(jiǎn)介
默認(rèn)情況下,在容器內(nèi)創(chuàng)建的所有文件都存儲(chǔ)在可寫(xiě)容器層上。
這意味著:
- 當(dāng)該容器不再存在時(shí),數(shù)據(jù)不會(huì)持續(xù)存在,并且如果另一個(gè)進(jìn)程需要數(shù)據(jù),則可能很難將數(shù)據(jù)從容器中取出。
- 容器的可寫(xiě)層與運(yùn)行容器的主機(jī)緊密耦合。您無(wú)法輕松地將數(shù)據(jù)移動(dòng)到其他地方。
- 寫(xiě)入容器的可寫(xiě)層需要 存儲(chǔ)驅(qū)動(dòng)程序來(lái)管理文件系統(tǒng)。存儲(chǔ)驅(qū)動(dòng)程序提供了一個(gè)聯(lián)合文件系統(tǒng),使用 Linux內(nèi)核。
- 與使用直接寫(xiě)入主機(jī)文件系統(tǒng)的數(shù)據(jù)卷相比,這種額外的抽象會(huì)降低性能 。
- Docker 有兩個(gè)選項(xiàng)讓容器在主機(jī)上存儲(chǔ)文件,以便即使在容器停止后文件也能持久保存:volumes和 bind mounts。
Docker 還支持將文件存儲(chǔ)在主機(jī)內(nèi)存中的容器。此類文件不會(huì)持久保存。如果您在 Linux 上運(yùn)行 Docker,則使用tmpfs mount將文件存儲(chǔ)在主機(jī)的系統(tǒng)內(nèi)存中。
掛載類型
volumes
:由 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 mounts
:掛載僅存儲(chǔ)在主機(jī)系統(tǒng)的內(nèi)存中,永遠(yuǎn)不會(huì)寫(xiě)入主機(jī)系統(tǒng)的文件系統(tǒng)
2. 原理
在 linux 系統(tǒng)上,docker 將images, containers, volumes等相關(guān)的數(shù)據(jù)存儲(chǔ)在/var/lib/docker
下。
當(dāng)我們運(yùn)行docker build
命令時(shí),docker 會(huì)為 dockerfile 中的每條指令構(gòu)建一層。
這些圖像層是只讀層。
當(dāng)我們運(yùn)行docker run
命令時(shí),docker 會(huì)構(gòu)建容器層,它們是讀寫(xiě)層。
您可以在容器上創(chuàng)建新文件,例如下圖中的temp.txt。
您還可以修改容器上屬于圖像層的文件,例如下圖中的app.py。
執(zhí)行此操作時(shí),會(huì)在容器層上創(chuàng)建該文件的本地副本,并且更改僅存在于容器上——這稱為 Copy-on-Write 機(jī)制。
這很重要,因?yàn)槎鄠€(gè)容器和子圖像使用相同的圖像層。
容器上的文件的生命周期與容器的生命周期一樣長(zhǎng)。
當(dāng)容器被銷(xiāo)毀時(shí),其上的文件/修改也會(huì)被銷(xiāo)毀。
為了持久化數(shù)據(jù),我們可以使用我們?cè)谏弦还?jié)中看到的卷映射技術(shù)。
3. 命令
您可以使用docker volume create
命令創(chuàng)建 docker 卷。
此命令將在/var/lib/docker/volumes
目錄中創(chuàng)建一個(gè)卷。
docker volume create data_volume docker volume ls docker volume inspect data_volume
docker run命令時(shí),您可以使用-v
標(biāo)志指定要使用的卷。這稱為卷掛載。
docker run -v data_volume:/var/lib/postgres postgres
如果該卷不存在,docker 會(huì)為您創(chuàng)建一個(gè)。現(xiàn)在,即使容器被銷(xiāo)毀,數(shù)據(jù)也會(huì)保留在卷中。
如果您想將數(shù)據(jù)放在 docker 主機(jī)上的特定位置或磁盤(pán)上已有數(shù)據(jù),您也可以將此位置掛載到容器上。這稱為綁定安裝。
docker run -v /data/postgres:/var/lib/postgres postgres
刪除
docker volume rm data_volume
4. 應(yīng)用
4.1 目錄 bind mount
echo "<h1>Hello from Host</h1>" > ./target/index.html docker run -it --rm --name nginx -p 8080:80 -v "$(pwd)"/target:/usr/share/nginx/html nginx
訪問(wèn):http://localhost:8080/
,您應(yīng)該會(huì)看到“Hello from Host”
4.2 隱式創(chuàng)建 Docker volume
#創(chuàng)建demo-earthly卷掛載 docker run -it --rm --name nginx -p 8080:80 -v demo-earthly:/usr/share/nginx/html nginx docker volume ls ls /var/lib/docker/volumes/target/_data/demo-earthly #查看卷內(nèi)容 docker run -it --rm -v demo-earthly:/opt/demo-earthly ubuntu ls /opt/demo-earthly
4.3 顯式創(chuàng)建 Docker 卷
docker volume create --name demo-earthly
4.4 從 Dockerfile 聲明一個(gè) Docker 卷
可以使用語(yǔ)句在 Dockerfile 中聲明卷VOLUME
Dockerfile:
FROM nginx:latest RUN echo "<h1>Hello from Volume</h1>" > /usr/share/nginx/html/index.html VOLUME /usr/share/nginx/html
利用Dockerfile構(gòu)建鏡像
$ docker build -t demo-earthly . $ docker run -p 8080:80 demo-earthly $ docker volume ls DRIVER VOLUME NAME local 20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281 $ docker volume inspect 20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281 [ { "CreatedAt": "2022-07-28T11:02:14+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281/_data", "Name": "20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281", "Options": null, "Scope": "local" } ] $ docker inspect -f '{{ .Mounts }}' amazing_carson [{volume 20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281 /var/lib/docker/volumes/20879e3f0bfaf0eed63cb7f37c4b9545084a703f888a230b8aedc2082c836281/_data /usr/share/nginx/html local true }]
每次啟動(dòng)一個(gè)新容器時(shí),都會(huì)創(chuàng)建另一個(gè)卷,內(nèi)容為/usr/share/nginx/html
.
4.5 另一種方式掛載 mount 參數(shù)
-v并且–volume是使用以下語(yǔ)法將卷安裝到容器的最常見(jiàn)方法:
-v <name>:<destination>:<options>
該卷將以只讀方式安裝:
docker run -it -v demo-volume:/data:ro ubuntu
另一種方法-v是--mount
選項(xiàng)添加到docker run命令中。–mount是 的更詳細(xì)的對(duì)應(yīng)物-v。
語(yǔ)法:
docker run --mount source=[volume_name],destination=[path_in_container] [docker_image]
示例
docker run -it --name=example --mount source=demo-volume,destination=/data ubuntu
4.6 使用配置卷 docker-compose
使用docker-compose命令在多個(gè)容器之間輕松共享數(shù)據(jù)更方便。
docker-compose.yml
目錄掛載
version: "3.2" services: web: image: nginx:latest ports: - 8080:80 volumes: - ./target:/usr/share/nginx/html
docker-compose.yml
創(chuàng)建卷
version: "3.2" services: web: image: nginx:latest ports: - 8080:80 volumes: - html_files:/usr/share/nginx/html web1: image: nginx:latest ports: - 8081:80 volumes: - html_files:/usr/share/nginx/html volumes: html_files:
聲明了一個(gè)名為并html_files
在服務(wù)中使用它的卷。多個(gè)容器(web、web1)可以掛載同一個(gè)卷。
運(yùn)行docker-compose up
將創(chuàng)建一個(gè)名為<project_name>_html_filesif
它不存在的卷。然后運(yùn)行docker volume ls
以列出創(chuàng)建的兩個(gè)卷,從項(xiàng)目名稱開(kāi)始。
您還可以在 docker-compose 文件之外管理容器,但您仍然需要在下面聲明它們volumes并設(shè)置屬性external: true
。
version: "3.2" services: web: image: nginx:latest ports: - 8080:80 volumes: - html_files:/usr/share/nginx/html volumes: html_files: external: true
如果你沒(méi)有html_files
,你可以使用docker volume create html_files
來(lái)創(chuàng)建它。
當(dāng)你添加 時(shí)external
,Docker 會(huì)找出卷是否存在;但如果沒(méi)有,就會(huì)報(bào)錯(cuò)。
4.7 從共享卷在容器之間復(fù)制文件
創(chuàng)建容器并創(chuàng)建掛載卷
docker create volume demo-earthly docker run -it --name=another-example --mount source=demo-volume,destination=/data ubuntu root@ded392c589ea:/# touch /data/demo.txt
導(dǎo)航到數(shù)據(jù)卷目錄并使用命令創(chuàng)建一個(gè)文件touch demo.txt
。
退出容器,然后啟動(dòng)一個(gè)another-example-two
具有相同數(shù)據(jù)量的新容器:
docker run -it --name=another-example-two --mount source=demo-volume,destination=/data ubuntu root@feef37293ea5:/# ls /data
參考:
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker安裝MySQL并使用Navicat連接的使用示例
在Docker里運(yùn)行MySQL的方式還是很方便的,本文主要介紹了Docker安裝MySQL并使用Navicat連接的使用示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10docker在windows創(chuàng)建卷后本地找不到的完美解決方法
這篇文章主要介紹了docker在windows創(chuàng)建卷后本地找不到的完美解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-02-02利用docker搭建web服務(wù)環(huán)境的方法步驟
這篇文章主要給大家介紹了關(guān)于利用docker搭建web服務(wù)環(huán)境的方法步驟,文中通過(guò)是示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09云原生使用Docker部署mysql數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程
使用docker部署mysql,可以省去mysql的安裝配置過(guò)程,而且不限制數(shù)量,即起即用,下面這篇文章主要給大家介紹了關(guān)于云原生使用Docker部署mysql數(shù)據(jù)庫(kù)的詳細(xì)過(guò)程,需要的朋友可以參考下2023-03-03docker-compose ports和expose的區(qū)別詳解
這篇文章主要介紹了docker-compose ports和expose的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01docker靈活的構(gòu)建PHP環(huán)境的實(shí)現(xiàn)
這篇文章主要介紹了docker靈活的構(gòu)建PHP環(huán)境的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Docker + Nodejs + Kafka + Redis + MySQL搭建簡(jiǎn)單秒殺環(huán)境
本文給大家分享的是使用Docker + Nodejs + Kafka + Redis + MySQL模擬搭建起來(lái)的商品秒殺環(huán)境,非常的實(shí)用和熱門(mén),有需要的小伙伴可以參考下2017-01-01