如何升级 Docker 容器并保留之前的网络和卷?
介绍
本文重点介绍容器镜像的升级机制。有多种方法可以将容器升级到最新的镜像。这里我们使用了一些简单易用的方法。首先,我们讨论了用于快速测试的手动方法。然后我们尝试了一些自动方法。这些方法将监控镜像,如果存在任何新更新,它们将使用更新的镜像创建一个新容器。
方法
手动方式,使用 CLI
自动方式,使用 CLI
自动方式,使用 Docker Compose
手动方式,使用 CLI
我们将按照以下步骤来实现镜像升级的目标。
使用旧镜像创建一个容器
下载本地系统上的更新后的镜像
使用更新后的镜像创建一个新容器,但使用旧的卷和网络
删除旧容器
步骤 1:创建旧镜像的 Docker 容器
使用以下命令创建 busybox 容器。
示例
$ docker run -itd --name old_cont --volume myvolume:/volumes --network mynetwork busybox:unstable
输出
eb08fe5971190abc85aa7ca8ed44d1d85e6ea0fafeda26bb59785897bbd056ae
进入此镜像并在卷目录内创建一个文件。
$ docker exec -it old_cont sh / # cd volumes/ /volumes # touch myfile.txt /volumes # ls myfile.txt /volumes # exit
步骤 2:使用新镜像创建容器
此容器具有 busybox 的最新镜像。
示例
$ docker run -itd --name new_cont --volume myvolume:/volumes --network mynetwork busybox:latest
输出
ab15dea992f46c27dfdb4a290e2dec3fbb10b3821694dbc12f18935d9e651c20
进入新容器并检查数据是否存在。
$ docker exec -it new_cont sh / # cd volumes/ /volumes # ls myfile.txt /volumes # exit
因此,卷和网络保持不变。只有容器的镜像更改为最新版本。
步骤 3:删除旧容器
示例
$ docker rm -f old_cont
输出
old_cont
在下一种方法中,我们将借助“watchtower”镜像来自动化上述过程。
自动方式,使用 CLI
这里我们将借助一个名为“watchtower”的额外镜像。“watchtower”将检查存储库中是否有任何更新的镜像。只要任何更新被推送到存储库,watchtower 就会自动下载更新后的镜像,并创建一个新的更新容器,其中包含链接到旧容器的所有旧数据。
步骤 1:创建容器
首先,我们需要使用旧镜像创建一个容器。
docker run -itd --name old_cont busybox:unstable unstable: Pulling from library/busybox 2461e8255644: Pull complete Digest: sha256:f4ed5f2163110c26d42741fdc92bd1710e118aed4edb19212548e8ca4e5fca22 Status: Downloaded newer image for busybox:unstable 81470b0f373557b3cb057e86113f6e11ce0baec23844e1370f519e043ff3db53
容器已创建并正在运行。
步骤 2:现在创建 watchtower 容器
在这里创建“watchtower”容器,并添加上述要升级的容器的名称。
示例
$ docker run -itd --name watch_container -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower old_cont
输出
Unable to find image 'containrrr/watchtower:latest' locally latest: Pulling from containrrr/watchtower 560f024ada32: Pull complete 03aa1c411c91: Pull complete 4e2295fcaa5d: Pull complete Digest: sha256:897304ffb41533954deda3ca9dd140fa1ca41e5d7e0bc6d6352606931145779c Status: Downloaded newer image for containrrr/watchtower:latest db82aafdb60ed17b3faf8d6df138aead91f9483257febc02af96ba4ed53d225d
现在,这将处理所有事情,每当 busybox:unstable 在 docker hub 上更新时,watchtower 将自动将此容器升级到更新后的镜像。
自动方式,使用 Docker Compose
我们将创建一个 Docker Compose 文件。此 compose 文件将包含需要监控的多个容器。“watchtower”的一个容器将监控所有这些容器。每当任何容器的镜像更新时,它都会为该镜像创建一个新容器。
步骤 1:创建 Docker Compose 文件
Docker compose 包含总共三个服务或容器。两个容器“old_cont”和“test_cont”由第三个容器“watch_cont”监控。
version: "3" services: old_cont: image: busybox:latest container_name: busybox_container command: sleep infinity test_cont: image: busybox:unstable container_name: testing_container command: sleep infinity watch_cont: image: containrrr/watchtower container_name: watchtower_container volumes: - /var/run/docker.sock:/var/run/docker.sock command: --interval 60 busybox_container testing_container
watchtower 将等待 60 秒,检查 docker hub 存储库中是否存在任何更新的镜像。如果我们不提供 --interval 选项,它将等待 24 小时。
步骤 2:启动容器
要启动所有这些容器,请使用以下命令。
$docker compose up -d
这将在分离模式下创建并运行所有这些容器。
结论
我们成功地为容器创建了一个升级周期。尽管这些方法未在生产环境中使用,因为我们为此任务有专用的软件。一些高级工具用于更新和升级任务。