版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuliuzi_hz/article/details/78531817
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 cleanup
if 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 graph
if (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 = rwlayer
logrus.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)
}
}