参:https://cloud.tencent.com/developer/article/2027894

Docker镜像与容器的备份迁移

容器迁移直接看最后的案例的方式。推荐使用 commit 构建新镜像,导出后迁移。

 用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。

save、export 和 commit 的区别

docker save是用来保存镜像的

  • 用途:用于将一个或多个 Docker 镜像保存到一个压缩的 tar 文件中。
  • 特点:保存的 tar 文件包含镜像的所有层、标签、元数据和历史记录,这允许在不同 Docker 环境之间完整地迁移和还原镜像。
  • 场景:适用于在不同 Docker 环境之间共享和迁移镜像,或在无网络连接的环境中部署镜像。

docker export是用来导出容器文件系统的

  • 用途:用于将 Docker 容器(无论是运行中还是已停止的)的文件系统导出为一个 tar 存档文件。
  • 特点:导出的 tar 文件不包含容器的历史记录和元数据,只包含文件系统状态,这使得导出的文件更为紧凑但功能有所损失。
  • 场景:适用于备份或迁移容器的当前状态,但不需要保留完整的容器历史或元数据。

docker commit是用来根据容器的当前状态创建新镜像的

  • 用途:基于正在运行的容器的当前状态创建一个新的 Docker 镜像。
  • 特点:允许捕获容器所做的更改,并保存为一个新的镜像,包括容器的历史记录和元数据。
  • 场景:当对容器进行了修改(如安装软件、更改配置等)后,并希望保存这些更改以便将来创建相同状态的容器或共享该状态时,非常有用。

容器迁移(export/import)

应用场景:

 主要用来制作基础镜像,比如从一个 ubuntu 镜像启动一个容器,然后安装一些软件和进行一些设置后,使用docker export 保存为一个基础镜像。然后,把这个镜像分发给其他人使用,如作为基础的开发环境。

注意

  1. 它只会导出文件系统;会丢失历史记录和元数据,如映射端口、CMD 和 ENTRYPOINT 配置。数据卷也不会包含在导出归档中。
  2. 启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。
# 导出(export):导出容器会丢失历史记录和元数据,类似快照
docker export [container ID or NAMES] > xx.tar	# 将导出容器快照到本地文件(.tar)

# 导入(import)
docker import xx.tar [REPOSITORY:TAG]
案例:

 通过 export 命令也可以将容器里的数据保存,并可以迁移到别的docker主机。

# 创建容器 web
[root@localhost ~]# docker run -itd --name web nginx
9a17f7c9f00a3711018581a1523ecd7a06c40d1408ae5678e034be1a1e4e0cd8

# 新增数据
[root@localhost ~]# docker exec -it web touch /mnt/test.txt
[root@localhost ~]# docker exec -it web ls /mnt/
test.txt

# 导出容器快照
[root@localhost ~]# docker export web > web.tar
[root@localhost ~]# docker import web.tar web:v1
sha256:134f9251e15e56060d564c23cec4be0048434fb90b19188ea64bf77af77b85ff

# 导入容器
[root@localhost ~]# docker images
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
web      v1                       134f9251e15e        10 minutes ago      125MB

# 启动容器
[root@localhost ~]# docker run -itd --name web2 web:v1 /bin/bash
ef07135bcda92c8660392ce29e24c7c8de82f3369fb024ae772c34cd74b9258d
# 查看之前新增的数据
[root@localhost ~]# docker exec -it web2 ls /mnt/
test.txt

构建镜像(commit)

应用场景: 主要作用是将配置好的一些容器生成新的镜像,可以得到复用(再次使用不需要再配置)。将已存在容器中的镜像和修改内容提交为一个新的镜像,通过这个方式同样能保存读写层内容。

注意: commit 命令虽然能实现保存读写层数据,但不适于做数据持久化。

#  返回镜像id;-m :提交时的说明文字;
$ docker commit -m “xxxx” [container ID] xx/xx:v1
  • -a:提交的镜像作者
  • -c:使用dockerfile指令来创建镜像
  • -m:提交时的说明文字
  • -p:在commit的时候,将正在运行的容器暂停
案例
# 启动一个 nginx 容器,并且在容器的 /mnt 目录下创建一个文件
[root@localhost ~]# docker run -itd --name nginxweb -p 80:80 nginx
fda3ca1b33ba4c9dc6a1ca27c7242bbbdc2a08f4e6e7642d3ec5de62e1e8f78c
[root@localhost ~]# docker exec -it nginxweb touch /mnt/test.txt
[root@localhost ~]# docker exec -it nginxweb ls /mnt/
test.txt

# 将 nginxweb 容器 commit 成一个新的镜像
[root@localhost ~]# docker commit nginxweb nginx_test:v2
sha256:a06b16b343036bcbf424c499022ca635bf90740aa7d76acbe0c271a731aba2ef
[root@localhost ~]# docker images
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
nginx_test                      v2                       a06b16b34303        4 seconds ago       127MB

# 使用 nginxweb 生成的新镜像 nginx_test启动一个nginx_v2容器,并查看新容器中的数据
[root@localhost ~]# docker run -itd --name nginx_v2 -p 82:80 nginx_test:v2      
df074341d7a39b072966672ef9bb8769142b67395488e30e81711d0c75f2a821
[root@localhost ~]# docker exec -it nginx_v1 ls /mnt/
test.txt       # 可以看到新容器nginx_v2中有之前nginxweb的数据

镜像迁移(save/load)

应用场景:

 如果应用是使用 docker-compose.yml 编排的多个镜像组合,但要部署的客户服务器并不能连外网。这时,可以使用docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入(一般用于镜像迁移到别处)。

# 导出(save)/
$ docker save > xx.tar [REPOSITORY:TAG] or [container ID]
$ docker save [REPOSITORY:TAG] or [container ID] > xx.tar

# 导入(load)
$ docker load < xx.tar

# 其中-o和>表示输出到文件,xx.tar为目标文件
# 导入后的镜像的tag为空时,需要为镜像做tag
$ docker tag [container ID] [REPOSITORY:TAG]

涉及数据卷迁移

查看 docker 容器详细信息中挂载的宿主机目录

[root@localhost ~]# docker inspect [container ID or NAMES]
[{
	...
	"HostConfig": {	# 容器的宿主机配置信息
		"Binds": [	绑定挂载信息
		"/opt/Development/testA:/vmdir/testA",
		"/opt/Development/testB:/vmdir/testB"
		],
	...
	
	"Mounts": [{	# 容器挂载的卷和绑定挂载信息
		"Type": "bind",
		"Source": "/opt/Development/testA",	# 宿主机的源路径
		"Destination": "/vmdir/testA",		# 容器内的目标路径
		"Mode": "",
		"RW": true,
		"Propagation": "rprivate"
	},
	{
		"Type": "bind",
		"Source": "/opt/Development/testB",
		"Destination": "/vmdir/testB",
		"Mode": "",
		"RW": true,
		"Propagation": "rprivate"
	},
	...
}]

备份相关目录文件:

[root@localhost opt]# tar -zcvf Development.tar.gz Development

迁移后启动:

Development.tar.gz 挂载文件上传迁移服务器解压。

# 启动
[root@localhost ~]# docker run -d \
-p 10004:8810 \	# 端口映射
-p 10005:8811 \
--name [containerNAME]  \
-v /opt/Development/testA:/vmdir/testA \	# 挂载Development.tar.gz的解压目录
-v /opt/Development/testB:/vmdir/testB \
-it [container ID or NAMES] \
sh -c "/start/start_all.sh"	

容器备份迁移案例

 运行一段时间后的容器,其中包含了新的数据,如果想把这些内容数据一并迁移到新的主机上,可以按照以下步骤进行:

1.提交容器构建新的镜像

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
9a17f7c9f00a        nginx               "nginx -g 'daemon of…"   19 hours ago        Up 19 hours         80/tcp              web

[root@localhost ~]# docker commit -p web webdata:v1    // -p暂停web容器并提交为新镜像webdata:v1
sha256:b25ea02c5f1f4efe4c35d6503a277d968d5dfdf0cfd69092b3e99202dd687723

[root@localhost ~]# docker images      //查看提交的新镜像webdata
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
webdata                         v1                       b25ea02c5f1f        3 seconds ago       127MB

2.导出新构建的镜像

[root@localhost ~]# docker save webdata:v1 > webdata.tar

3.将tar压缩包复制到另一台主机

[root@localhost ~]# scp webdata.tar root@192.168.2.128:/root/test

4.在另一台主机上加载镜像的tar压缩包

[root@localhost ~]# cd /root/test
[root@localhost test]# docker load -i webdata.tar
d9d778e6751c: Loading layer [==================================================>]  10.24kB/10.24kB
Loaded image: webdata:v1

[root@localhost test]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
webdata                       v1                  b25ea02c5f1f        12 minutes ago      127MB

5.使用这个加载的镜像运行容器

[root@localhost test]# docker run -itd --name web webdata:v1
51d9ed10961b9620ea6456f5bd75dbd43168b73c7bd184dcccdd25fcf956d9e5

[root@localhost test]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
51d9ed10961b        webdata:v1          "nginx -g 'daemon of…"   35 seconds ago      Up 33 seconds       80/tcp              web

[root@localhost test]# docker exec -it web ls /mnt/
test.txt
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐