玖叶教程网

前端编程开发入门

容器无损迁移的研究(容器转移)

个人在实际业务中经常使用到容器,也会涉及到容器的迁移,尤其是每逢年末双11双12云主机打折,换机器是必然步骤,因此容器的迁移也是经常要用的。在对容器不太精通的情况下,经常迁移不成功,后来有段时间使用docker export 导出运行的容器文件系统,再使用docker import 导入镜像,复制挂接的目录,然后重新运行容器,总能成功。但是突然有一天,使用同样方式迁移的时候发现运行容器命令出错,报错没有指定运行命令,我确定之前是没有问题的,这应该是docker版本升级之后带来的。在运行的时候指定运行命令,这让我觉得很难受,于是对容器迁移做了一个比较深入的研究。

结论

runlike 很重要,推荐需要进行容器迁移的一定要安装,或者安装笔记要记好,记好每个容器运行的指令。

runlike 安装方式

pip3 install runlike

容器的迁移需要与原容器运行同样的指令,如果不一样,会导致一些数据的丢失。

docker export /import +volume的迁移(含本地文件夹或者volume类型)

docker commit /docker save /docker load +volume的迁移(含本地文件夹或者volume类型)

使用同样的image版本+ volume的迁移(含本地文件夹或者volume类型)

都能实现容器的无损转移,关键点在与容器运行指令要与原来的指令一样

推荐容器迁移方式

自有镜像容器,采用docker commit/docker save/docker load +volume迁移来实现,这样不需要指定启动命令

官方镜像容器,采用拉取官方镜像 +volume迁移来实现

迁移都需要使用runlike来获取容器的启动命令,或者用笔记记录容器的启动命令,推荐使用runlike

windows下docker desktop 附带了此功能,见容器下copy docker run

测试过程

在现有的服务器上有一个容器运行的是rabbitmq,并且队列里面有一些正在运行的队列,尝试对其进行迁移。能正常启动,数据还在,原有的队列还在,才算迁移成功。

服务器centos7 +docker版本Docker version 20.10.18, build b40c2f6。测试时间为2022年12月

迁移服务器windows11 docker desktop 4.14.1

方式一 docker export /docker import 再打包挂载的文件目录。原有启动命令无法启动,存在的问题,在启动容器时,需要指定运行的启动命令;runlike生产的启动指令可以正常启动

用原有启动指令报错

docker run --name=rabbitmq3.9.13-management --hostname=myRabbit --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxx --volume=D:\docker\rabbitmq-data:/var/lib/rabbitmq --volume=/var/lib/rabbitmq -p 127.0.0.1:15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true 7ff5

报错

docker: Error response from daemon: No command specified.

运行runlike分析的启动指令能正常启动

docker run --name=rabbitmq3.9.13-management --hostname=myRabbit --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxxx --env=PATH=/opt/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OPENSSL_VERSION=1.1.1m --env=OPENSSL_SOURCE_SHA256=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 --env='OPENSSL_PGP_KEY_IDS=0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D' --env=OTP_VERSION=24.2.1 --env=OTP_SOURCE_SHA256=380a77aef34ad449bf8370a380b7901364b9be23e3d25068fc5c43258bcbec11 --env=RABBITMQ_DATA_DIR=/var/lib/rabbitmq --env=RABBITMQ_VERSION=3.9.13 --env=RABBITMQ_PGP_KEY_ID=0x0A9AF2115F4687BD29803A206B73A36E6026DFCA --env=RABBITMQ_HOME=/opt/rabbitmq --env=RABBITMQ_LOGS=- --env=HOME=/var/lib/rabbitmq --env=LANG=C.UTF-8 --env=LANGUAGE=C.UTF-8 --env=LC_ALL=C.UTF-8 --volume=D:\docker\rabbitmq-data:/var/lib/rabbitmq/mnesia --volume=/var/lib/rabbitmq -p 127.0.0.1:15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true 7ff5 rabbitmq-server

上面7ff5 是用docker export导出的镜像

注意docker export/docker import的这种镜像无法直接启动了。每次创建容器都需要指定启动的命令,非常麻烦。

docker export 的镜像测试创建一个新的容器试试

docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 7ff5

报错

docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 7ff5
docker: Error response from daemon: No command specified.
See 'docker run --help'.

尝试带相关缺省环境变量,可以正常启动

docker run --name=rabbitmq3.9.13-management2 --hostname=myRabbit2 --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxxx --env=PATH=/opt/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OPENSSL_VERSION=1.1.1m --env=OPENSSL_SOURCE_SHA256=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 --env='OPENSSL_PGP_KEY_IDS=0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D' --env=OTP_VERSION=24.2.1 --env=OTP_SOURCE_SHA256=380a77aef34ad449bf8370a380b7901364b9be23e3d25068fc5c43258bcbec11 --env=RABBITMQ_DATA_DIR=/var/lib/rabbitmq --env=RABBITMQ_VERSION=3.9.13 --env=RABBITMQ_PGP_KEY_ID=0x0A9AF2115F4687BD29803A206B73A36E6026DFCA --env=RABBITMQ_HOME=/opt/rabbitmq --env=RABBITMQ_LOGS=- --env=HOME=/var/lib/rabbitmq --env=LANG=C.UTF-8 --env=LANGUAGE=C.UTF-8 --env=LC_ALL=C.UTF-8  -p 127.0.0.1:15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true 7ff5 rabbitmq-server

去掉启动命令,启动不了,需要指定启动命令

docker run --name=rabbitmq3.9.13-management2 --hostname=myRabbit2 --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxxx --env=PATH=/opt/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OPENSSL_VERSION=1.1.1m --env=OPENSSL_SOURCE_SHA256=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 --env='OPENSSL_PGP_KEY_IDS=0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D' --env=OTP_VERSION=24.2.1 --env=OTP_SOURCE_SHA256=380a77aef34ad449bf8370a380b7901364b9be23e3d25068fc5c43258bcbec11 --env=RABBITMQ_DATA_DIR=/var/lib/rabbitmq --env=RABBITMQ_VERSION=3.9.13 --env=RABBITMQ_PGP_KEY_ID=0x0A9AF2115F4687BD29803A206B73A36E6026DFCA --env=RABBITMQ_HOME=/opt/rabbitmq --env=RABBITMQ_LOGS=- --env=HOME=/var/lib/rabbitmq --env=LANG=C.UTF-8 --env=LANGUAGE=C.UTF-8 --env=LC_ALL=C.UTF-8  -p 127.0.0.1:15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true 7ff5

感觉目前的docker export可能有bug,丢失了部分环境信息,我确信之前的一年前的版本是可以正常运行的,不需要指定命令

方式二:docker commit 然后再docker save 镜像,docker load 加载镜像

这种导入的镜像可以直接规范的方式创建新的容器,不需要指定启动命令

docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 e189

附加volume数据看看能不能恢复队列内容,经测试报cookie权限问题,修复后发现没有恢复原有的cookie,使用docker create 也没有能恢复原来的队列,重新复制卷的内容

docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 --volume=D:\docker\rabbitmq-data2:/var/lib/rabbitmq/ e189
docker create --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 --volume=D:\docker\rabbitmq-data2:/var/lib/rabbitmq/ e189

尝试用原来的启动指令创建容器看看,发现原来的序列恢复了。所以容器能不能恢复原有状态,和启动命令有很大关系。

docker run --name=rabbitmq3.9.13-management --hostname=myRabbit --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxxx --env=PATH=/opt/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OPENSSL_VERSION=1.1.1m --env=OPENSSL_SOURCE_SHA256=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 --env='OPENSSL_PGP_KEY_IDS=0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D' --env=OTP_VERSION=24.2.1 --env=OTP_SOURCE_SHA256=380a77aef34ad449bf8370a380b7901364b9be23e3d25068fc5c43258bcbec11 --env=RABBITMQ_DATA_DIR=/var/lib/rabbitmq --env=RABBITMQ_VERSION=3.9.13 --env=RABBITMQ_PGP_KEY_ID=0x0A9AF2115F4687BD29803A206B73A36E6026DFCA --env=RABBITMQ_HOME=/opt/rabbitmq --env=RABBITMQ_LOGS=- --env=HOME=/var/lib/rabbitmq --env=LANG=C.UTF-8 --env=LANGUAGE=C.UTF-8 --env=LC_ALL=C.UTF-8 --volume=D:\docker\rabbitmq-data2:/var/lib/rabbitmq --volume=/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true e189

方式三:拉取官方镜像配合挂接原有的数据目录及volume,原来的序列还在,成功迁移

直接用迁移的数据,重新拉取官方镜像

rabbitmq:3.9.13-management

docker run -d --hostname my-rabbit4 --name some-rabbit4 -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password -p 15672:15672 -p 5672:5672 --volume=D:\docker\rabbitmq-data:/var/lib/rabbitmq/ rabbitmq:3.9.13-management

直接拉取的官方镜像,配合迁移的用户数据,原来的数据序列没有了。容器能启动

其中由于cookie权限的问题,导致运行失败,需要进行权限修改

docker run -it --privileged --rm -v d:\docker\rabbitmq-data2:/tochange alpine /bin/sh

修改了权限之后。能正常启动。但是原来的队列没有了。

使用runlike获取的运行命令,指定官方版本,配合挂载迁移的文件目录,实现了容器的无损迁移

docker run --name=rabbitmq3.9.13-management --hostname=myRabbit --env=RABBITMQ_DEFAULT_USER=abc --env=RABBITMQ_DEFAULT_PASS=xxxxxx --env=PATH=/opt/rabbitmq/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --env=OPENSSL_VERSION=1.1.1m --env=OPENSSL_SOURCE_SHA256=f89199be8b23ca45fc7cb9f1d8d3ee67312318286ad030f5316aca6462db6c96 --env='OPENSSL_PGP_KEY_IDS=0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D' --env=OTP_VERSION=24.2.1 --env=OTP_SOURCE_SHA256=380a77aef34ad449bf8370a380b7901364b9be23e3d25068fc5c43258bcbec11 --env=RABBITMQ_DATA_DIR=/var/lib/rabbitmq --env=RABBITMQ_VERSION=3.9.13 --env=RABBITMQ_PGP_KEY_ID=0x0A9AF2115F4687BD29803A206B73A36E6026DFCA --env=RABBITMQ_HOME=/opt/rabbitmq --env=RABBITMQ_LOGS=- --env=HOME=/var/lib/rabbitmq --env=LANG=C.UTF-8 --env=LANGUAGE=C.UTF-8 --env=LC_ALL=C.UTF-8 --volume=D:\docker\rabbitmq-data2:/var/lib/rabbitmq --volume=/var/lib/rabbitmq -p 15672:15672 -p 5672:5672 --restart=no --runtime=runc --detach=true rabbitmq:3.9.13-management



发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言