一. 起因
- 正在使用的Linux是原本用來測試簡易安裝用的,所以根目錄只提供了16GB空間,安裝完畢openSUSE之后發現還行,就覺得湊合用一下就行,沒想到隨着數據量的提升直接把根目錄存滿了。因為沒有使用LVM,所以動態擴容也沒轍,找了一圈方法以后決定把最占空間的docker和映射目錄下的文件進行遷移,於是在/dev/sda1基礎上把120G硬盤又划出了60GB做了/dev/sda2的/home空間。目標就是將原本/ver/lib/docker全量遷移到/home目錄下。
- 鳴謝
二. 遷移docker安裝目錄和鏡像目錄
- 因為使用的docker是用zypper進行安裝的,目錄就在
/var/lib/docker
。 - 檢查docker安裝目錄總大小
du -hs /var/lib/docker/
,同時使用df -h
確認/home目錄是否能容納docker的整個文件夾。(docker system df
檢查所有鏡像和容器占用空間大小,不包含映射目錄占用的空間,需要docker啟動) - 開始遷移:
# 停止docker服務 systemctl stop docker.service # 創建docker在/home下的路徑 mkdir -p /home/docker/lib/docker # 拷貝/var/lib目錄下docker目錄結構(注意:命令為文件內容同步,並不推薦直接使用mv,容易導致失誤) rsync -avz /var/lib/docker /home/lib/docker/ # 檢查/etc/systemd/system/docker.service.d/devicemapper.conf配置是否存在 # 如果是使用zypper安裝,則默認不會有,沒有就手動創建目錄和文件 mkdir -p /etc/systemd/system/docker.service.d/ nano /etc/systemd/system/docker.service.d/devicemapper.conf # 文件中添加以下內容 [Service] ExecStart= ExecStart=/usr/bin/dockerd --graph=/home/docker/lib/docker # 保存並退出編輯器,刷新配置 systemctl daemon-reload # 嘗試啟動docker systemctl restart docker.service # 檢查當前docker啟動狀態是否是active (running) systemctl status docker.service # 檢查docker運行根路徑,不出意外就是:/home/docker/lib/docker docker info | grep "Docker Root Dir" # 檢查鏡像是否完整 docker images # 建議不要急着刪/var/lib/docker,因為映射目錄還沒有遷移,如果失手,還需要這個救急
三. 遷移數據目錄
- 服務器在根目錄下多個地點分布着多個數據目錄,目前都要聚合到/home/docker/mydata目錄下。
- 遷移前務必使遷移目標的容器停止服務
docker stop 容器名
,保證數據的一致性;如果是必須運行的,請見鳴謝ii文章。 - 這里以映射映射目錄較少的redis為例(勿噴為啥redis還要用docker,學習用方便折騰)。
# 停止redis容器 docker stop redis # 創建遷移目標目錄 mkdir -p /home/docker/mydata/redis # 目錄同步 rsync -avz /mydata/redis /home/docker/mydata/redis # 獲取redis容器的名稱 docker ps -a
- 到這里映射目錄和文件已經同步完畢,開始修改配置文件重新指向新的映射目錄:
- 因為docker創建容器的時候就在docker/containers目錄下創建一個配置文件,里面記錄着容器的基礎啟動和目錄映射配置
config.v2.json
。因為是一串超長無格式化JSON字符串,使用Linux自帶的文本編輯器並不容易編輯。建議使用FileZilla之類的工具將文件拷貝到本地后進行編輯,然后再上傳服務器。 - 所有的目錄映射都由同一個
MountPoints
屬性牽頭,作為一個大的對象,每一個目錄映射對應一個對象屬性。 - 如果只是修改外部映射目錄,每一處映射只需要改兩處
Source
屬性的字符串目錄到新的地址即可。如果需要修改容器內目錄,則需要修改三處,除了對象屬性外,還有Destination
、Target
,為了直觀展示需要修改的地方,這里展示一下格式化后的部分配置文件,切記修改的時候不要格式化文件內容!
"MountPoints": { "/data": { # 容器內路徑 "Source": "/home/docker/mydata/redis/data", # 外部映射路徑 "Destination": "/data", # 容器內路徑 "RW": true, "Name": "", "Driver": "", "Type": "bind", "Propagation": "rprivate", "Spec": { "Type": "bind", "Source": "/home/docker/mydata/redis/data", # 外部映射路徑 "Target": "/data" # 容器內路徑 }, "SkipMountpointCreation": false }, "/etc/redis/redis.conf": { "Source": "/home/docker/mydata/redis/conf/redis.conf", "Destination": "/etc/redis/redis.conf", "RW": true, "Name": "", "Driver": "", "Type": "bind", "Propagation": "rprivate", "Spec": { "Type": "bind", "Source": "/home/docker/mydata/redis/conf/redis.conf", "Target": "/etc/redis/redis.conf" }, "SkipMountpointCreation": false } }
- 文件修改完畢以后,將原容器中的
config.v2.json
改名備份后,將修改后的文件上傳到容器目錄中,嘗試啟動docker中的容器:docker start redis
,然后使用docker ps -a
檢查運行結果,成功啟動以后,使用連接工具進入redis檢查是否成功遷移。另一種檢查方式是,將原映射目錄改名,然后啟動docker檢查是否成功啟動,如果成功說明成功一大半了。
四. 部分容器的特殊處理
- 目前支持修改配置文件遷移的容器有:
- Redis
- fastdfs-tracker
- fastdfs-storage
- fastdfs-nginx(遷移失敗,疑似配置錯誤導致)
- 不支持修改配置文件遷移的:
- mysql
不知道為什么不支持改配置文件,貌似有什么緩存機制,重復嘗試三四次,在啟動以后配置文件都變回了原來的映射目錄地址。所以嘗試之后決定拷貝映射目錄然后重新創建容器目錄指向新目錄:# 停掉mysql容器 docker stop mysql # 新路徑創建映射目錄,並同步目錄內容 mkdir -p /home/docker/mydata/mysql rsync -avz /mydata/mysql /home/docker/mydata/mysql # 以新目錄創建新容器,不要指定密碼 docker run -p 3306:3306 --name newmysql \ -v /home/docker/mydata/mysql/log:/var/log/mysql \ -v /home/docker/mydata/mysql/data:/var/lib/mysql \ -v /home/docker/mydata/mysql/conf:/etc/mysql -e \ -d mysql:5.7 # 執行命令以后貌似會鎖住console頁面,斷掉重新登陸,啟動新容器 docker start newmysql # 啟動無問題后,登陸檢查數據是否完整,將老容器刪除,並將新容器進行改名處理 docker rm mysql docker rename newmysql mysql # 將新容器設置為自啟 docker update mysql --restart=always
- mysql