本文翻译自:How to upgrade docker container after its image changed

Let's say I have pulled the official mysql:5.6.21 image . 假设我已经取消了正式的mysql:5.6.21图像

I have deployed this image by creating several docker containers. 我通过创建几个docker容器来部署此映像。

These containers have been running for some time until MySQL 5.6.22 is released. 这些容器已运行一段时间,直到MySQL 5.6.22发布。 The official image of mysql:5.6 gets updated with the new release, but my containers still run 5.6.21. mysql的官方形象:5.6使用新版本更新,但我的容器仍然运行5.6.21。

How do I propagate the changes in the image (ie upgrade MySQL distro) to all my existing containers? 如何将图像中的更改(即升级MySQL发行版)传播到我现有的所有容器? What is the proper Docker way of doing this? Docker的正确方法是什么?


#1楼

参考:https://stackoom.com/question/1oAq2/如何在映像更改后升级docker容器


#2楼

You need to either rebuild all the images and restart all the containers, or somehow yum update the software and restart the database. 您需要重建所有映像并重新启动所有容器,或者以某种方式yum更新软件并重新启动数据库。 There is no upgrade path but that you design yourself. 没有升级路径,但您自己设计。


#3楼

This is something I've also been struggling with for my own images. 这也是我为自己的图像而苦苦挣扎的事情。 I have a server environment from which I create a Docker image. 我有一个服务器环境,我可以从中创建一个Docker镜像。 When I update the server, I'd like all users who are running containers based on my Docker image to be able to upgrade to the latest server. 当我更新服务器时,我希望所有基于我的Docker镜像运行容器的用户都能够升级到最新的服务器。

Ideally, I'd prefer to generate a new version of the Docker image and have all containers based on a previous version of that image automagically update to the new image "in place." 理想情况下,我更愿意生成新版本的Docker镜像,并让所有基于该图像的先前版本的容器自动更新到新图像“就位”。 But this mechanism doesn't seem to exist. 但这种机制似乎并不存在。

So the next best design I've been able to come up with so far is to provide a way to have the container update itself--similar to how a desktop application checks for updates and then upgrades itself. 因此,到目前为止,我能够提出的下一个最好的设计是提供一种让容器更新的方法 - 类似于桌面应用程序检查更新然后自我升级的方式。 In my case, this will probably mean crafting a script that involves Git pulls from a well-known tag. 在我的情况下,这可能意味着制作一个涉及Git拉从一个着名标签的脚本。

The image/container doesn't actually change, but the "internals" of that container change. 图像/容器实际上没有改变,但是该容器的“内部”发生了变化。 You could imagine doing the same with apt-get, yum, or whatever is appropriate for you environment. 您可以想象使用apt-get,yum或任何适合您环境的方法。 Along with this, I'd update the myserver:latest image in the registry so any new containers would be based on the latest image. 除此之外,我还会在注册表中更新myserver:最新图像,以便任何新容器都基于最新图像。

I'd be interested in hearing whether there is any prior art that addresses this scenario. 我有兴趣听听是否有任何现有技术可以解决这个问题。


#4楼

I had the same issue so I created docker-run , a very simple command-line tool that runs inside a docker container to update packages in other running containers. 我有同样的问题所以我创建了docker-run ,这是一个非常简单的命令行工具,它在docker容器内运行,以更新其他正在运行的容器中的包。

It uses docker-py to communicate with running docker containers and update packages or run any arbitrary single command 它使用docker-py与正在运行的docker容器进行通信并更新包或运行任意单个命令

Examples: 例子:

docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec

by default this will run date command in all running containers and return results but you can issue any command eg docker-run exec "uname -a" 默认情况下,这将在所有正在运行的容器中运行date命令并返回结果但您可以发出任何命令,例如docker-run exec "uname -a"

To update packages (currently only using apt-get): 要更新包(目前只使用apt-get):

docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run update

You can create and alias and use it as a regular command line eg 您可以创建和别名并将其用作常规命令行,例如

alias docker-run='docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run'


#5楼

After evaluating the answers and studying the topic I'd like to summarize. 在评估答案并研究我想总结的主题之后。

The Docker way to upgrade containers seems to be the following: Docker升级容器的方式似乎如下:

Application containers should not store application data . 应用程序容器不应存储应用程序数据 This way you can replace app container with its newer version at any time by executing something like this: 这样,您可以通过执行以下操作随时将app容器替换为其较新版本:

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

You can store data either on host (in directory mounted as volume) or in special data-only container(s) . 您可以将数据存储在主机(作为卷安装的目录中)或特殊的仅数据容器中 Read more about it 阅读更多相关信息

Upgrading applications (eg. with yum/apt-get upgrade) within containers is considered to be an anti-pattern . 在容器内升级应用程序(例如,使用yum / apt-get升级)被认为是反模式 Application containers are supposed to be immutable , which shall guarantee reproducible behavior. 应用程序容器应该是不可变的 ,这应该保证可重现的行为。 Some official application images (mysql:5.6 in particular) are not even designed to self-update (apt-get upgrade won't work). 一些官方应用程序映像(特别是mysql:5.6)甚至没有设计为自我更新(apt-get升级不起作用)。

I'd like to thank everybody who gave their answers, so we could see all different approaches. 我要感谢所有给出答案的人,所以我们可以看到所有不同的方法。


#6楼

Taking from http://blog.stefanxo.com/2014/08/update-all-docker-images-at-once/ 来自http://blog.stefanxo.com/2014/08/update-all-docker-images-at-once/

You can update all your existing images using the following command pipeline: 您可以使用以下命令管道更新所有现有图像:

docker images | awk '/^REPOSITORY|\<none\>/ {next} {print $1}' | xargs -n 1 docker pull
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐