如何在线升级Docker?


Docker升级时,Docker Daemon stop了,容器就没了!有没好方法能在线升级或恢复容器?这个问题简单有趣,欢迎探讨。
已邀请:

william - cSphere CEO

赞同来自: sharon山哥 hydRAnger tsing 浩瀚 cSphere


目前docker daemon升级是生产环境的一大痛点。运行关键任务的用户很为之苦恼。

最好能做到daemon升级不影响容器运行。

xiaolunsanguo - 京东商城-南京研发中心-JDOS团队

赞同来自:


首先说一点,docker stop了,但是容器并不一定“没了”。
我理解的所谓的“没了”,就是指容器的进程不存在的。
所有的容器进程,都是docker daemon的子进程。当docker daemon直接挂了,容器的主进程(就是由Entrypoint或者CMD生成的那个进程),会有两种情况:
1. 直接消失。这种情况常见于CMD是/bin/bash的情形。直接消失的原因据我猜测是因为这是个有pty的进程,需要跟父进程(docker daemon)保持一定的联系。父进程挂了,这个子进程就直接没了。
2. 被1号进程托管(父进程变成了1号进程)。这种情况应该常见于CMD是sshd -D或者sleep 99999d的情况。
但是无论哪种情况,当docker daemon再次start时候,会直接去检查容器进程是不是running。如果running,那么清理容器遗留进程。这也就是为什么启动起来docker daemon,所有的容器都是关闭的原因了。
docker为什么要在启动时候关闭这些进程呢?他们running不好么?
根据我对docker源码的理解,docker不放心其他进程来管理。他一定要亲自管理这些容器,他是所有容器的父进程。这样有很多好处。最大的好处就是实时监控,一旦容器挂了,他立即可以知道,并重启(如果容器设置了restart=always的话)。
-----------------------------华丽的分割线-----------------------------------------
上面的只是铺垫,现在说正题:
我们的意愿是良好的。希望能够docker在线升级。我看来一个可能的解决方法就是,在docker daemon start的时候,去检查容器是不是running,如果running,那么清理容器遗留进程,接着再重新start容器。以保证仍然作为容器的父进程进行管理。当然,这就要求给docker新增这么一段代码以实现该功能。

xds2000 - 数人科技CTO

赞同来自:


实际上这不是一个问题。比如coreos的做法,起两个docker daemon,然后默默升级。然后再不忙的时候在重启一下就切换了。对于普通客户,一定要把程序做成分布式的,随意停一台docker daemon没问题。这样升级不就简单了嘛?

Denicks - 吊死技术难!

赞同来自:


如果daemon不是父进程,也可以做很好的监控container,不过这部分可能需要docker来监控,但是子进程异常或者退出的时候父进程会收到一个信号,来回收资源。我猜是不是docker想偷个懒做这个事情。这样我觉得会把daemon和container之间的依赖性放大(个人觉得daemon只要做到可以很好的管理container就好,没必要我挂掉重启,你也得重启)。

coffemaker - 70 咖啡男

赞同来自:


如果是在生产升级docker daemon, 那应该部署新服务器,等确认完服务都正常运行时,将老服务关掉。 如果在aws 上,这可以用terraform + 新base image + "Auto Scaling Groups" 来实现。

关键是将系统部署和应用部署分开。

要回复问题请先登录注册