赞
踩
docker 目前集成了CRIU工具,可以在用户空间中冻结以及恢复容器,其中checkpoint是冻结命令,将容器当前运行状态冻结并保存为镜像文件;restore命令则可以根据这些镜像文件重新恢复容器运行。
通过这种方式,可以简单地实现docker容器的热迁移,热迁移示例如下:
- # 在源节点上创建示例容器,容器内每隔1s打印数字
- $ docker run -d --name looper --security-opt seccomp:unconfined busybox \
- /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
-
- # 创建检查点checkpoint1
- $ docker checkpoint create looper checkpoint1
-
- # 查看已打印的数字
- $ docker logs looper
-
- # 在目的节点上创建与源节点相同的容器,但不用运行
- $ docker create --name looper-clone --security-opt seccomp:unconfined busybox \
- /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
-
- # 根据源节点上已保存的检查点文件,在目的节点上重新恢复容器运行
- $ docker start --checkpoint=checkpoint2 looper-clone
-
- # 在目的节点上查看容器内数字打印,新容器将会接着上次中断的数字继续打印
- $ docker logs looper-clone
以上步骤可以将容器looper迁移到looper-clone,但需要将源节点下 /var/lib/docker/{docker id}/checnkpoints/ 下面与检查点同名的文件迁移到目的节点下的同样位置。
尽管CRIU工具可以实现预拷贝,但docker 官方目前还未集成预拷贝,因此需要修改docker的部分源代码。
docker组件主要包含dockerd、containerd、runc等,各组件之间的关系可看这里。
1)cli/command/checkpoint/create.god
func newCreateCommand() *cobra.Command:docker客户端命令行
func runCreate() error:发起创建命令
2)client/checkpoint_create.go
func (cli *Client) CheckpointCreate() error::docker客户端发起post请求
3)api/server/router/checkpoint/checkpoint.go
func (r *checkpointRouter) initRoutes():初始化route
4)api/server/router/checkpoint/checkpoint_routes.go
func (s *checkpointRouter) postContainerCheckpoint():处理post请求
5)daemon/checkpoint.go
func (daemon *Daemon) CheckpointCreate():封装一下相关参数,发送给libcontainerd模块
6)libcontainerd/client_linux.go
func (clnt *client) CreateCheckpoint():作为grpc的客户端apiClient调用Containerd服务端apiServer的函数完成快照
1)api/grpc/server/server.go
func (s *apiServer) CreateCheckpoint():作为grpc的服务端apiServer,创建一个新的Task
2)supervisor/supervisor.go
err = s.createCheckpoint(t):分发Task
3)supervisor/checkpoint.go
func (s *Supervisor) createCheckpoint():转发调用
4)runtime/container.go
func (c *container) Checkpoint():通过grpc调用CRIU程序完成快照
1)checkpoint.go
CRIU命令行参数
2)libcontainer/container_linux.go
func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error:criuSwrk调用CRIU
在分析了上述的checkpoint过程后,补充docker、containerd、runc的部分代码,将CRIU的预拷贝功能添加到docker里并重新编译docker,从而实现docker容器内部的预拷贝。
docker在github的仓库名为moby,对于moby的源码修改可看这里。
修改后,在原docker命令上增加了两个参数,如图所示:
预拷贝效果如下:
- # 第一次拷贝
- docker checkpoint create --pre-dump looper checkpoint1
- # 第二次拷贝
- docker checkpoint create --pre-dump –parent-path ../checkpoint1 looper checkpoint1_1
- # 停机拷贝
- docker checkpoint create --parent-path ../checkpoint1_1 looper checkpoint1_final
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。