目录

  • 一. 起因
  • 二. 迁移docker安装目录和镜像目录
  • 三. 迁移数据目录
  • 四. 部分容器的特殊处理

一. 起因

  1. 正在使用的Linux是原本用来测试简易安装用的,所以根目录只提供了16GB空间,安装完毕openSUSE之后发现还行,就觉得凑合用一下就行,没想到随着数据量的提升直接把根目录存满了。因为没有使用LVM,所以动态扩容也没辙,找了一圈方法以后决定把最占空间的docker和映射目录下的文件进行迁移,于是在/dev/sda1基础上把120G硬盘又划出了60GB做了/dev/sda2的/home空间。目标就是将原本/ver/lib/docker全量迁移到/home目录下。

二. 迁移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(迁移失败,疑似配置错误导致)
  1. 不支持修改配置文件迁移的:
  • 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