docker live-restore

来源:互联网 发布:桔子影音软件 编辑:程序博客网 时间:2024/05/24 04:38
docker 1.12 开始支持live restore,就是关闭docker daemon ,而不关闭容器
有两种方式开启:
  • 如果docker daemon正在运行并且你不想停止它,你可以添加配置到docker daemon的配置文件。例如:在linux系统上默认的配置文件是/etc/docker/daemon.json
{"live-restore": true}
你必须传递一个SIGHUP信号给daemon进程来重载配置。更多有关使用config.json来配置docker daemon的信息,可以参考daemon configuration file
  • 在使用dockerd启动时指定--live-restore选项
$sudo dockerd --live-restore

root@btsci-cloud-server-1:~# ps -ef|grep docker
root 5773 1 1 14:09 ? 00:00:00 /usr/bin/dockerd -H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock --bip=192.168.2.1/24 --mtu=1450
root 5785 5773 0 14:09 ? 00:00:00 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
root 5982 5785 0 14:09 ? 00:00:00 docker-containerd-shim e4b6cbd3ea87347a8f6e8d640ea0350b5a35424905633b08a374e0433251f02c /var/run/docker/libcontainerd/e4b6cbd3ea87347a8f6e8d640ea0350b5a35424905633b08a374e0433251f02c docker-runc
root 6087 5699 0 14:09 pts/2 00:00:00 grep --color=auto docker
root@btsci-cloud-server-1:~#
root@btsci-cloud-server-1:~# ps -ef|grep docker
root 5982 1 0 14:09 ? 00:00:00 docker-containerd-shim e4b6cbd3ea87347a8f6e8d640ea0350b5a35424905633b08a374e0433251f02c /var/run/docker/libcontainerd/e4b6cbd3ea87347a8f6e8d640ea0350b5a35424905633b08a374e0433251f02c docker-runc
root 6166 5699 0 14:10 pts/2 00:00:00 grep --color=auto docker
可见docker daemon关闭后,容器进程变孤儿进程,父进程号变为1

实现机制如下(1.13版本)
func (daemon *Daemon) Shutdown() error {daemon.shutdown = true// Keep mounts and networking running on daemon shutdown if// we are to keep containers running and restore them.        //即设置live-restore后,damon不关闭容器,自己直接退出if daemon.configStore.LiveRestoreEnabled && daemon.containers != nil {// check if there are any running containers, if none we should do some cleanupif ls, err := daemon.Containers(&types.ContainerListOptions{}); len(ls) != 0 || err != nil {return nil}}if daemon.containers != nil {logrus.Debugf("start clean shutdown of all containers with a %d seconds timeout...", daemon.configStore.ShutdownTimeout)daemon.containers.ApplyAll(func(c *container.Container) {if !c.IsRunning() {return}logrus.Debugf("stopping %s", c.ID)if err := daemon.shutdownContainer(c); err != nil {logrus.Errorf("Stop container error: %v", err)return}if mountid, err := daemon.layerStore.GetMountID(c.ID); err == nil {daemon.cleanupMountsByID(mountid)}logrus.Debugf("container stopped %s", c.ID)})}


而daemon恢复时候,还是从文件列表获取容器信息,把容器信息重新加入到Daemon对象的containers字典里
func (daemon *Daemon) restore() error {var (currentDriver = daemon.GraphDriverName()containers    = make(map[string]*container.Container))logrus.Info("Loading containers: start.")dir, err := ioutil.ReadDir(daemon.repository)if err != nil {return err}for _, v := range dir {id := v.Name()                                //获取文件列表container, err := daemon.load(id)if err != nil {logrus.Errorf("Failed to load container %v: %v", id, err)continue}// Ignore the container if it does not support the current driver being used by the graphif (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {rwlayer, err := daemon.layerStore.GetRWLayer(container.ID)if err != nil {logrus.Errorf("Failed to load container mount %v: %v", id, err)continue}container.RWLayer = rwlayerlogrus.Debugf("Loaded container %v", container.ID)containers[container.ID] = container} else {logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)}}