白話理解和使用DOCKER VOLUME

数据酷软件發表於2024-06-11

Docker使用Volume來管理宿主機和容器內資料的對映

什麼是資料卷(Volume)
Docker映象被儲存在一系列的只讀層中。當我們建立一個容器時,Docker會讀取映象(只讀),並在其頂部新增一層讀寫層。如果正在執行中的容器修改了現有檔案,該檔案將會被複製出底層的只讀層,放到最頂層的讀寫層中。讀寫層中原來的舊版本檔案(未被更改過的檔案)仍然存在於映象中。

所以當Docker容器被刪除後,再基於原來的映象建立容器時,將建立一個沒有任何資料更改的容器,在之前那個容器中的資料更改會丟失掉。只讀層和讀寫層的組合被Docker稱為聯合檔案系統(Union File System)。

為了能夠持久化這些更改過的資料,並且能夠很容易實現容器間共享資料,Docker提出了Volume的概念。Volume是外部預設的聯合檔案系統或者是存在於宿主檔案系統中正常的檔案或資料夾。

為什麼需要資料卷(Volume)
這得從Docker容器的檔案系統說起。出於效率等一系列原因,Docker容器的檔案系統在宿主機上存在的方式很複雜,這會帶來下面幾個問題:

不能在宿主機上很方便地訪問容器中的檔案。
無法在多個容器之間共享資料。
當容器刪除時,容器中產生的資料將會丟失。
為了解決這些問題,Docker引入了資料卷(Volume) 機制。資料卷以獨立於Docker檔案系統的形式存在於宿主機中。資料卷的最大特點是:其生存週期獨立於容器的生存週期。

資料卷的設計目的就是資料的持久化,因為其生存週期獨立於容器的生存週期,因此Docker不會在容器刪除時刪除其掛載的資料卷。所以資料卷可以帶來以下好處:

資料卷可在容器之間共享或重用資料。
資料卷的更改可以直接生效。
資料卷的生命週期一直持續到沒有容器使用它為止。
對資料卷操作不會影響到映象本身。
資料卷可以完成容器到宿主機、宿主機到容器以及容器到容器之間的資料共享。

前言

有人會和我一樣麼?我並沒有系統的學習過容器化技術,約在兩年前進了一家公司是做MES的在經過某知名造車新勢力成功搭建.NET CORE3.1實現的系統架構並用K8S方式部署。然後就開始在沒人帶的情況下花點時間實踐了雲原生技能,學習了該公司的系統架構成了配置開發人員。我本來就是野生程式設計師,所以學習雲原生就是邊走邊學。我剛開始並不明白上面的概念,不瞭解VOLUME有什麼作用。直到我最近在學ODOO二開,需要頻繁更新容器裡的檔案。豁然發現使用VOLUME就好了。寫下這篇隨筆純粹打發時間。

正文-Volume命令

 --odoo
docker run -d -v odoo-lib:/var/lib/odoo  -v odoo-config:/etc/odoo -v odoo_extra:/mnt/extra-addons -v odoo_apps:/usr/lib/python3/dist-packages/odoo/addons  -p 8069:8069 --name odoo --restart=always --link db:db -t odoo:17
docker run -d -v odoo-db:/var/lib/postgresql/data -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres -p 5432:5432  --restart=always --name db postgres:15.7--redis
docker run --restart=always --log-opt max-size=100m --log-opt max-file=2 -p 6379:6379 --name myredis -v redis_conf:/etc/redis/redis.conf -v redis_data:/data -d redis redis-server /etc/redis/redis.conf  --appendonly yes  --requirepass dba#redis 
--nginx
docker run \
-p 8080:80 \
--name nginx \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-d nginx:latest

每次docker方式部署mysql,redis,nginx等支援docker方式部署的應用我都要抄人家文章裡的bash命名行。然後收藏夾裡很多地址是關於這些的。其實我知道這些bash命令裡很多是關於docker volumn的,但是就是不想花時間去詳細瞭解。終於我想通了我要知其所以然。

docker volume help

Usage: docker volume COMMAND

Manage volumes

Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.

透過docker volume COMMAND --help可以檢視每個Volume命令的詳情。

docker volume ls

列出所有的資料卷。

[root@izoq008ryseuupz docker]# docker volume ls --help

Usage: docker volume ls [OPTIONS]

List volumes

Aliases:
ls, list

Options:
-f, --filter filter Provide filter values (e.g. 'dangling=true')
--format string Pretty-print volumes using a Go template
-q, --quiet Only display volume names

docker volume create

建立一個資料卷。

[root@izoq008ryseuupz docker]# docker volume create --help

Usage: docker volume create [OPTIONS] [VOLUME]

Create a volume

Options:
-d, --driver string Specify volume driver name (default "local")
--label list Set metadata for a volume
-o, --opt map Set driver specific options (default map[])

是的,上面的內容是抄別人的。為了要讓可讀性稍微有點保障。其實我基本上只用 docker run的時候帶-v引數來自動建立volumn。自動建立的卷在宿主機器上的實際地址在哪裡呢?你可以使用portainer這個視覺化容器管理工具來管理。

你可能不知道哪些路徑需要對映,-v是不限制個數的少了就自己加上。容器內部的地址自己使用docker exec進入容器內部去驗證。portainer是非常簡單易用的。是我必須在伺服器上安裝的工具。所以我其實是不喜歡用bash命令的。

相關文章