使用 Docker 時,經常需要備份存儲在 卷 中的數據,或者出於測試目的將數據複製到另一個卷中。
雖然可以考慮使用 docker cp 命令,但此命令僅支持在 容器的檔案系統 和主機之間進行複製,因此無法直接訪問 Docker 管理的卷。
本文將介紹複製 Docker 卷的正確方法,不僅僅是列出命令,還會聚焦於 ‘為什麼’需要使用這種方式 的原理。理解這一原理後,即使不記住命令,也能在需要時自然地加以應用。
核心原理相當簡單。
操作 Docker 卷的最安全和最‘Docker 風格’的方法是利用可以訪問該卷的‘臨時容器’作為橋接。
1. 將現有卷複製到新卷 (Volume-to-Volume)
這是最常見的場景。您可能想將運行中的 db_data 卷複製到測試用的 db_data_test 卷。
🤔 為什麼要使用臨時容器?
Docker 卷存儲在主機檔案系統中的某個地方(如 /var/lib/docker/volumes/...),但 Docker 守護進程管理這一路徑。直接訪問此路徑並使用 cp 命令並不推薦,並且可能導致權限問題或數據一致性問題。
相反,我們將運行一個同時掛載兩個卷的臨時容器。
-
容器將原始卷(
source_volume)掛載到/from路徑。 -
容器將目標卷(
new_volume)掛載到/to路徑。 -
容器啟動後立即執行簡單的 Linux 命令(
cp或tar),將/from的所有數據複製到/to。 -
命令結束後,容器會自動被銷毀(
--rm參數)。
這個容器只用作數據複製的‘工具’。
🚀 如何:命令示例
以下是將 source_data 卷的數據複製到 target_data 卷的示例。
- 創建測試用卷(可選)
docker volume create source_data
docker volume create target_data
# (假設 source_data 中已有數據。)
- 利用臨時容器進行複製
docker run --rm \
-v source_data:/from \
-v target_data:/to \
alpine \
sh -c "cp -a /from/. /to/"
💡 命令解說
-
docker run --rm:--rm標誌表示容器在完成任務並退出時立即刪除容器。這對於臨時任務是必須的。 -
-v source_data:/from: 將source_data卷掛載到容器內的/from目錄中。 -
-v target_data:/to: 將target_data卷掛載到容器內的/to目錄中。 -
alpine: 使用包含基本工具(如cp和sh)且體積極小的alpineLinux 映像。 -
sh -c "...": 在 alpine 容器啟動時要執行的命令。 -
cp -a /from/. /to/:-
-a(archive): 此標誌是核心。與單純複製cp -r不同,這會保留所有屬性,如所有權、權限、時間戳等。在處理敏感數據如數據庫文件時非常重要。 -
/from/.: 意味著/from中的所有內容(包括隱藏文件),而不是/from目錄。
-
2. 將卷數據複製到主機檔案系統(備份)
當您希望將卷的數據備份到本地機器或伺服器的某個特定目錄如 .tar 文件時使用。
🤔 為什麼:如何工作?
原理與第一條相同。但目標不再是‘Docker 卷’,而是‘主機目錄’。
Docker 支持將主機的特定目錄掛載到容器中的綁定掛載(Bind Mount) 功能。
-
容器將
/data路徑掛載為原始卷(source_volume)。 -
容器將
/backup路徑掛載為主機的特定目錄($(pwd)/backup)。 -
容器將
/data的內容複製(或壓縮)到/backup目錄。 -
這項操作發生在容器內部,但由於
/backup與實際主機目錄相連,因此結果將保留在主機上。
🚀 如何:命令示例
將 source_data 卷的數據複製到當前位置($(pwd))的 backup 目錄。
# 在主機上創建備份目錄
mkdir -p $(pwd)/backup
docker run --rm \
-v source_data:/data:ro \
-v $(pwd)/backup:/backup \
alpine \
cp -a /data/. /backup/
💡 命令解說
-
-v source_data:/data:ro: 添加了:ro(只讀)標誌。由於備份只需讀取數據,因此建議 以只讀方式掛載,以防止意外修改原始卷。 -
-v $(pwd)/backup:/backup: 與source_data(卷名)不同,/開頭或包含$(pwd)(當前路徑)的絕對/相對路徑指的是主機目錄。
3. 核心複製技巧 (Tips)
技巧 1: 使用 tar 進行高效複製(壓縮備份)
使用 tar 而不是 cp 命令有多個好處。特別是當將數據打包為存檔文件(.tar.gz)時非常有用。
Volume-to-Volume(使用 tar)
可能比 cp 更快,特別是當文件較多時更為高效。
docker run --rm \
-v source_data:/from \
-v target_data:/to \
alpine \
sh -c "cd /from && tar -cf - . | (cd /to && tar -xf -)"
-
cd /from && tar -cf - .: 轉到/from,並將當前目錄(.)的內容打包為tar,發送到 標準輸出(-)而不是文件。 -
| (cd /to && tar -xf -): 通過管道(|)接收標準輸出,然後在/to目錄解壓tar。
Volume-to-Host(壓縮備份)
將 source_data 卷的內容壓縮為 backup.tar.gz 文件並儲存到主機上。
docker run --rm \
-v source_data:/data:ro \
-v $(pwd):/backup \
alpine \
tar -czf /backup/backup.tar.gz -C /data .
-
tar -czf /backup/backup.tar.gz ...:c(創建),z(gzip 壓縮),f(文件)創建/backup/backup.tar.gz文件。 -
-C /data .: 此部分很重要。首先將工作目錄更改為 /data,然後將其內部的所有內容進行壓縮。這樣,tar 文件內部將不包含多餘的 /data 路徑。
技巧 2: 將主機檔案恢復到卷中
恢復與備份相反,遵循相同的原理僅需反轉 cp 的方向。
# 將 $(pwd)/backup 目錄中的數據恢復到 new_data 卷中
docker run --rm \
-v new_data:/data \
-v $(pwd)/backup:/backup:ro \
alpine \
cp -a /backup/. /data/
總結
處理 Docker 卷的核心在於“使用容器作為工具”的思維方式。與其直接操縱主機上的卷文件,不如啟動一個同時掛載所需卷和目錄的臨時容器,然後在其中安全執行 cp 或 tar 等標準 Linux 命令。
只要記住這一原理,您就能自由地在任何情況下複製、備份和恢復卷數據。
目前沒有評論。