文章目錄
- 一、存儲卷概念
- 二、存儲卷分類
- 2.1 管理卷
- 2.2 綁定數據卷
- 2.3 臨時數據卷
- 三、MySQL災難恢復
- 四、存儲卷的局限性
一、存儲卷概念
什么是存儲卷?
??Docker 存儲卷 是 Docker 容器中用于持久化存儲數據的獨立文件系統區域。它獨立于容器的聯合文件系統,其生命周期可以完全獨立于創建它的容器。簡單來說,可以把它理解成容器中的一個共享文件夾或外部硬盤,這個文件夾直接映射到主機(或其它遠程存儲)上的一個真實目錄。
為什么要使用存儲卷?
- 容器銷毀或誤操作等會導致數據丟失,而存儲卷就可以起到一個數據備份的作用。
- 宿主機和容器,容器和容器,它們之間文件系統是相互隔離的,要完成數據交互很麻煩,而存儲卷起到一個交通樞紐的功能,或者說相當于一個“共享目錄”。
二、存儲卷分類
Docker 提供了三種方式將數據從宿主機掛載到容器中:
??管理卷(volume docker
)。默認映射到宿主機的/var/lib/docker/volumes
目錄下,只需要在容器內指定容器的掛載點是什么,而被綁定宿主機下的那個目錄,是由容器引擎 daemon
自行創建一個空的目錄,或者使用一個已經存在的目錄,與存儲卷建立存儲關系,這種方式極大解脫用戶在使用卷時的耦合關系,缺陷是用戶無法指定那些使用目錄,臨時存儲比較適合;
??綁定數據卷(bind mount
)。映射到宿主機指定路徑下,在宿主機上的路徑要人工的指定一個特定的路徑,在容器中也需要指定一個特定的路徑,兩個已知的路徑建立關聯關系。
??臨時數據卷(tmpfs mount
).映射到于宿主機內存中,一旦容器停止運行,tmpfs mounts
會被移除,數據就會丟失,用于高性能的臨時數據存儲。
2.1 管理卷
創建卷
方法一:Volume命令操作
命令清單:
docker volume create
:創建存儲卷docker volume inspect
:顯示存儲卷詳細信息docker volume ls
: 列出存儲卷docker volume prune
:清理所有無用數據卷docker volume rm
:刪除卷,使用中的無法刪除
示例:
- 注:
docker volume create
不加卷名稱,生成匿名存儲卷 - 注:
docker volume inspect
支持查看多個存儲卷 - 注:
docker volume rm
和docker volume prune
加-f
選項表示強制刪除
方法二:-v 或者–mount 指定
在docker run
創建并啟動容器時添加-v
或--mount
都可以完成管理卷的創建和掛載
-v 選項
功能:完成目錄映射
語法:
docker run -v name:directory[:options]
參數:
- 第一個參數:卷名稱
- 第二個參數:卷映射到容器的目錄
- 第三個參數:選項,如 ro 表示 readonly
示例:
效果:
–mount選項
功能:完成目錄映射
語法:
--mount '<key>=<value>,<key>=<value>'
關鍵參數:
type
:類型表示 bind, volume, or tmpfssource,src
:對于命名卷,這是卷的名稱。對于匿名卷,省略此字段destination,dst,target
:文件或目錄掛載在容器中的路徑ro,readonly
:只讀方式掛載
示例:
docker run -d --name myweb2 --mount 'src=myweb2,dst=/usr/share/nginx/html' nginx:1.24.0
效果和-v選項相同
- 注意1:添加ro選項限制的是容器里的寫權限。
- 注意2:容器刪除卷的數據不會刪除,除非用 docker volume rm 刪除。因為卷本身就是來保護數據的。
- 注意3:卷共享。不同容器可以使用同一個卷,解決了容器與容器之間數據交互繁瑣的問題。
2.2 綁定數據卷
綁定卷 bind mount
:-v
和 --mount
都可以完成綁定卷的創建
-v 選項
功能:完成卷映射
語法:
docker run -v name:directory[:options] ………
- 注意1:-v選項下,如果宿主機沒有對應的目錄,會自動創建,而–mount則會掛載失敗。
- 注意2:與管理卷不同,容器目錄原有數據會被清空,同步成宿主機目錄下的數據。
- 注意3:ro限制的是宿主機的寫操作。
–mount選項
功能:完成目錄映射
語法:
--mount '<key>=<value>,<key>=<value>'
關鍵參數:
type
: 類型表示bind
,volume
,or tmpfs
source
,src
: 宿主機目錄,這個和管理卷是不一樣的destination
,dst,target
: 文件或目錄掛載在容器中的路徑ro,readonly
: 只讀方式掛載
示例:
docker run -d --name=myweb3 --mount
type=bind,src=/home/qsy/gitDocker/data/test2
,dst=/usr/share/nginx/html nginx:1.24.0
注意:在命令行中不能像這個把指令分行寫(必須寫在一行),這里只是方便展示。
效果同-v
選項。
特性 | 管理卷 | 綁定卷 |
---|---|---|
創建者 | Docker | 用戶自己 |
存儲位置 | Docker管理的區域 | 用戶指定的任何目錄 |
控制權 | Docker | 用戶 |
移植性 | 高 | 低 |
典型用途 | 數據庫數據、應用程序產生的需要持久化的數據 | 配置文件、源代碼、日志文件(在主機和容器間共享) |
備份與遷移 | 使用 docker volume 命令操作,相對簡單 | 需要操作主機文件系統,復雜度高 |
2.3 臨時數據卷
臨時卷 tmpfs
:臨時卷數據位于內存中,在容器和宿主機之外(僅在容器運行期間存在)。
局限性
- 不同于管理卷和綁定卷,不能在容器之間共享 tmpfs 掛載
- 這個功能只有在 Linux 上運行 Docker 時才可用
創建卷
方法一:
–tmpfs選項
功能:完成臨時卷映射
語法:
--tmpfs /app
- 注意1:數據在宿主機內存里,/app是容器目錄。如果該目錄不存在則會創建。
- 注意2:該容器的目錄會被清空。
- 注意3:當容器重啟后,tmpfs目錄會被銷毀,或恢復成原來的樣子。
示例:
docker run -d --name=myweb4 --tmpfs /test1 nginx:1.24.0
方法二:
--mount
選項
功能:完成目錄映射
語法:
--mount '<key>=<value>,<key>=<value>'
關鍵參數:
type
:類型表示bind
,volume
,or tmpfs
destination,dst,target
:掛載在容器中的路徑tmpfs-size
:tmpfs
掛載的大小(以字節為單位)。默認無限制。tmpfs-mode
:tmpfs
的八進制文件模式。例如,700 或 0770。默認為 1777 或全局可寫。
示例:
docker run -d --name=myweb5 --mount type=tmpfs,dst=/usr/share/nginx/html nginx:1.24.1
三、MySQL災難恢復
接下來我們演示把數據庫容器數據丟失,然后通過存儲卷恢復的過程,分為以下幾步:
- 掛載存儲卷
- 模擬數據生產
- 刪除數據庫容器
- 恢復數據
- 登錄mysql并查看數據是否恢復
創建mysql容器并掛載:
docker run -d --name 容器的名字 -v 宿主機目錄:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=數據庫密碼 mysql:版本號
模擬數據庫存儲:
刪除mysql容器
恢復數據(數據都在宿主機目錄下,再用同樣的方式掛載就行)
登錄數據庫查看數據是否恢復:
四、存儲卷的局限性
- 數據生命周期與容器分離:這既是一個優點,也是一個缺點。卷的生命周期獨立于容器,即使刪除了所有使用該卷的容器,卷及其數據仍然存在。它有效的保護了容器的數據,但很容易導致“孤兒卷”或“僵尸卷”堆積,占用大量磁盤空間,如果不手動清理,會造成資源浪費。
- 可移植性挑戰:卷本身在創建時是“空白”的,其內容通常由容器在運行時填充。你不能像鏡像一樣,輕松地將一個包含數據的卷從一個環境(如開發機)直接“復制”或“遷移”到另一個環境(如生產服務器)。
- 備份和遷移流程復雜:備份一個正在被容器使用的活躍卷存在數據一致性的風險(例如,數據庫文件可能在備份過程中被修改)。標準的 Docker 命令沒有提供一鍵式的卷備份功能。
- 空間分配不靈活:Docker 卷默認使用宿主機的存儲空間,你無法像在虛擬機中那樣,輕松地為單個卷設置大小限制。一個失控的容器進程(例如,日志瘋狂輸出)可能會寫滿整個卷,進而占滿宿主機的磁盤空間,導致宿主機和其他容器都出現問題。
- 安全性與訪問控制:卷中的數據默認由容器的用戶(通常是 root)擁有和寫入。如果容器以特權模式運行或被攻破,攻擊者可以通過卷對宿主機文件系統造成破壞(盡管比綁定掛載更安全)。
非常感謝您能耐心讀完這篇文章。倘若您從中有所收獲,還望多多支持呀!