如何在镜像更改后升级Docker容器

比方说,我已经拉到了官方的mysql:5.6.21映像。

我已经通过创建几个码头容器来部署此映像。

这些容器已经运行了一段时间,直到MySQL 5.6.22发布。 mysql:5.6的官方映像在新版本中得到更新,但我的容器仍然运行5.6.21。

如何将图像中的更改(即升级MySQL发行版)传播到所有现有的容器? 什么是正确的Docker这样做的方式?


在评估答案并研究我想要总结的主题后。

Docker升级容器的方式似乎如下:

应用程序容器不应存储应用程序数据 通过这种方式,您可以随时通过执行类似下面的操作来替换应用容器和更新的版本:

docker pull mysql
docker stop my-mysql-container
docker rm my-mysql-container
docker run --name=my-mysql-container --restart=always 
  -e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql

您可以将数据存储在主机上(在以卷装载的目录中)或存储在特定的仅限数据的容器中。 在这里,这里和这里阅读更多关于它的信息。

在容器中升级应用程序(例如使用yum / apt-get升级)被认为是反模式 。 应用程序容器应该是不可变的,这将保证可重现的行为。 某些官方应用程序映像(特别是MySQL:5.6)甚至没有设计为自我更新(apt-get升级不起作用)。

我想感谢所有给出答案的人,所以我们可以看到所有不同的方法。


我不喜欢将卷挂载为主机目录的链接,因此我想出了一个模式,用于完全使用docker托管容器升级docker容器。 使用--volumes-from <container>创建一个新的--volumes-from <container>将为新容器提供更新的映像共享Docker管理卷的所有权。

docker pull mysql
docker create --volumes-from my_mysql_container [...] --name my_mysql_container_tmp mysql

通过不立即删除原始的my_mysql_container ,如果升级后的容器没有正确的数据,或者无法进行完整性测试,则可以恢复到已知的工作容器。

在这一点上,我通常会运行任何备份脚本来为容器提供一个安全网络,以防出现问题

docker stop my_mysql_container
docker start my_mysql_container_tmp

现在您有机会确保您希望在新容器中的数据在那里,并执行完整性检查。

docker rm my_mysql_container
docker rename my_mysql_container_tmp my_mysql_container

只要任何容器正在使用它们,码头的容积就会一直存在,因此您可以安全地删除原来的容器。 一旦原始容器被移除,新的容器可以采用原始的同名器件,以使所有事情都像开始时一样美丽。

使用这种模式升级Docker容器有两大好处。 首先,它不需要通过允许卷直接传输到升级的容器来将卷装载到主机目录。 其次,你永远不会处于没有工作码头集装箱的位置; 所以如果升级失败,您可以通过再次旋转原始码头集装箱容易地恢复到之前的工作状态。


我想补充一点,如果您想自动执行此过程(下载,停止并重新启动具有与@Yaroslav所述相同设置的新容器),则可以使用WatchTower。 一个程序,当它们被更改时自动更新容器https://github.com/v2tec/watchtower

链接地址: http://www.djcxy.com/p/5109.html

上一篇: How to upgrade docker container after its image changed

下一篇: Isolation in Vagrant vs. Docker