当前位置:   article > 正文

docker容器热迁移实现,checkpoint预拷贝实现_error response from daemon: cannot checkpoint cont

error response from daemon: cannot checkpoint container looper: runc did not

checkpoint 和 restore 命令

docker 目前集成了CRIU工具,可以在用户空间中冻结以及恢复容器,其中checkpoint是冻结命令,将容器当前运行状态冻结并保存为镜像文件;restore命令则可以根据这些镜像文件重新恢复容器运行。

通过这种方式,可以简单地实现docker容器的热迁移,热迁移示例如下:

  1. # 在源节点上创建示例容器,容器内每隔1s打印数字
  2. $ docker run -d --name looper --security-opt seccomp:unconfined busybox \
  3. /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
  4. # 创建检查点checkpoint1
  5. $ docker checkpoint create looper checkpoint1
  6. # 查看已打印的数字
  7. $ docker logs looper
  8. # 在目的节点上创建与源节点相同的容器,但不用运行
  9. $ docker create --name looper-clone --security-opt seccomp:unconfined busybox \
  10. /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
  11. # 根据源节点上已保存的检查点文件,在目的节点上重新恢复容器运行
  12. $ docker start --checkpoint=checkpoint2 looper-clone
  13. # 在目的节点上查看容器内数字打印,新容器将会接着上次中断的数字继续打印
  14. $ docker logs looper-clone

以上步骤可以将容器looper迁移到looper-clone,但需要将源节点下 /var/lib/docker/{docker id}/checnkpoints/ 下面与检查点同名的文件迁移到目的节点下的同样位置。

容器预拷贝迁移

尽管CRIU工具可以实现预拷贝,但docker 官方目前还未集成预拷贝,因此需要修改docker的部分源代码。

docker组件主要包含dockerd、containerd、runc等,各组件之间的关系可看这里

docker checkpoint分析

docker方面

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的函数完成快照

Containerd方面

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程序完成快照

Runc方面

1)checkpoint.go

CRIU命令行参数

2)libcontainer/container_linux.go

func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error:criuSwrk调用CRIU

docker源代码修改

在分析了上述的checkpoint过程后,补充docker、containerd、runc的部分代码,将CRIU的预拷贝功能添加到docker里并重新编译docker,从而实现docker容器内部的预拷贝。

docker在github的仓库名为moby,对于moby的源码修改可看这里

修改后,在原docker命令上增加了两个参数,如图所示:

预拷贝效果如下:

  1. # 第一次拷贝
  2. docker checkpoint create --pre-dump looper checkpoint1

  1. # 第二次拷贝
  2. docker checkpoint create --pre-dump –parent-path ../checkpoint1 looper checkpoint1_1

  1. # 停机拷贝
  2. docker checkpoint create --parent-path ../checkpoint1_1 looper checkpoint1_final

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/461387
推荐阅读
相关标签
  

闽ICP备14008679号