1. 程式人生 > 其它 >Docker - Docker遷移資料目錄和對映目錄

Docker - Docker遷移資料目錄和對映目錄

一. 起因

  1. 正在使用的Linux是原本用來測試簡易安裝用的,所以根目錄只提供了16GB空間,安裝完畢openSUSE之後發現還行,就覺得湊合用一下就行,沒想到隨著資料量的提升直接把根目錄存滿了。因為沒有使用LVM,所以動態擴容也沒轍,找了一圈方法以後決定把最佔空間的docker和對映目錄下的檔案進行遷移,於是在/dev/sda1基礎上把120G硬碟又劃出了60GB做了/dev/sda2的/home空間。目標就是將原本/ver/lib/docker全量遷移到/home目錄下。
  2. 鳴謝
    1. docker如何遷移資料目錄 【作者:linux-123】
    2. Docker(34)- 如何修改 docker 容器的目錄對映 【作者:小菠蘿測試筆記】
    3. 【mysql】docker 安裝的mysql 進行儲存轉移 【作者:intelrain】

二. 遷移docker安裝目錄和映象目錄

  1. 因為使用的docker是用zypper進行安裝的,目錄就在/var/lib/docker
  2. 檢查docker安裝目錄總大小 du -hs /var/lib/docker/,同時使用df -h確認/home目錄是否能容納docker的整個資料夾。(docker system df檢查所有映象和容器佔用空間大小,不包含對映目錄佔用的空間,需要docker啟動)
  3. 開始遷移:
    # 停止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,因為對映目錄還沒有遷移,如果失手,還需要這個救急
    

三. 遷移資料目錄

  1. 伺服器在根目錄下多個地點分佈著多個數據目錄,目前都要聚合到/home/docker/mydata目錄下。
  2. 遷移前務必使遷移目標的容器停止服務docker stop 容器名,保證資料的一致性;如果是必須執行的,請見鳴謝ii文章。
  3. 這裡以對映對映目錄較少的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屬性的字串目錄到新的地址即可。如果需要修改容器內目錄,則需要修改三處,除了物件屬性外,還有DestinationTarget,為了直觀展示需要修改的地方,這裡展示一下格式化後的部分配置檔案,切記修改的時候不要格式化檔案內容!
    "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檢查是否成功啟動,如果成功說明成功一大半了。

四. 部分容器的特殊處理

  1. 目前支援修改配置檔案遷移的容器有:
    • Redis
    • fastdfs-tracker
    • fastdfs-storage
    • fastdfs-nginx(遷移失敗,疑似配置錯誤導致)
  2. 不支援修改配置檔案遷移的:
    • 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