一. 起因
- 正在使用的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