如何升级 Docker 容器以应用镜像更新

c2ef15c914e173b

Docker 容器是一次性的,易于更换。当容器基础镜像的新版本发布时,您应该拉取新镜像并启动一个新的容器实例。以下是如何在您的容器队列中管理映像更新。

拉取新镜像

应用镜像更新的基本方法是拉取新镜像,销毁基于旧版本运行的容器,然后在它们的位置启动新容器。

以下是使用nginx:latest图像的容器示例:

# Pull new image
docker pull nginx:latest

# Delete old container by name
docker rm example-nginx

# Start a new container
docker run -d -p 80:80 --name example-nginx nginx:latest

Docker 缺乏检测图像更新和替换正在运行的容器的内置方法。结果是一个复杂的手动更换过程。可以通过使用Docker Compose来启动容器而不是普通docker run命令来简化它。

用 Docker Compose 替换容器

Docker Compose允许您使用docker-compose.yml文件创建容器堆栈的声明性表示。堆栈以 开头docker-compose up,使用文件中包含的配置。这取代了通常提供给 的长长的标志列表docker run

Docker Compose 有一个内置pull命令,可以拉取堆栈中所有镜像的更新版本。它仍然是一个两阶段的过程,因为您必须在docker-compose up之后再次手动运行。

# Pull all images in the stack
docker-compose pull

# Restart the stack
# If a new image version has been pulled, containers 
# using the old tag will be replaced with new instances.
docker-compose up -d

Docker Compose 提供了一种更简单、更令人难忘的体验,您无需键入图像名称或记住传递给 的标志docker run。这两个命令可以很容易地缩短为单个 shell 别名:

alias composePullUp="docker-compose pull && docker-compose up -d"

管理图像标签

手动拉取镜像时需要引用正确的标签。Docker Compose 将为您处理此问题并选择您的docker-compose.yml.

拉取标签的新版本不一定与使用最新版本的镜像相同。如果您想在容器使用最新版本的软件,请注意图像作者的标记做法。

例如,拉取新版本node:14将为您node:latest提供Node.js 14 的最新补丁版本。拉取将提供最新的 Node.js 版本,当前为 16。如果旧容器正在使用此映像,则执行拉取和替换过程将触发容器内 Node 二进制文件的主要版本碰撞。

重建图像

到目前为止,我们已经看到了如何处理从直接从 Docker Hub 或其他注册表中拉取的镜像启动的容器。您自己构建的镜像需要在其基础镜像更改时重新构建。

首先重建镜像:

docker build --pull -t my-image:latest .

然后更换你的容器:

# Delete old container by name
docker rm my-container

# Start a new container
docker run -d --name my-container my-image:latest

--pull给出的标志docker build指示 Docker 拉取在您的Dockerfile. 如果没有这个标志,如果镜像已经存在于系统中,Docker 将重用现有的标签引用。

Docker Compose 用户可以使用相应的docker-compose命令获得相同的结果:

docker-compose build --pull

docker-compose up -d

Compose 再次提供了一个更简单的过程,尽管仍然是两个阶段。您可以忘记特定的图像名称和标签,而是相信 Compose 会提取更改的基础图像,在它们之上重建您的图层,然后重新创建您的容器。

容器内的软件

有时,手动更新容器的软件可能很诱人。这应该避免,因为它再次遵循 Docker 的原则。

apt-get update && apt get upgrade -y在管理裸机 Linux 服务器时,按计划运行(或您的包管理器的对应项)是标准做法。这些命令通常不在 Docker 容器中运行,尽管它们可能作为 a 的一部分包含Dockerfile在映像构建期间获取最新的安全补丁。

定期拉取基础镜像并重新创建容器是保持它们更新的首选方式。这为您提供了所有上游安全修复并缩短了单个容器的寿命。容器环境不应在创建实例后进行修改;文件系统更改应仅限于写入临时路径和比容器寿命更长的专用 Docker 卷

自动化容器更新

您可以使用第三方项目自动执行检查更新镜像标签和重启容器的过程。Watchtower是一种流行的选择,它监视正在运行的容器并在其 Docker Hub 映像更改时替换它们。

Watchtower 本身被部署为一个容器:

docker run -d -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower

现在您已经安装了一个正常运行的 Watchtower。您主机的 Docker 套接字已挂载到 Watchtower 容器中,允许它运行 Docker 命令来创建和删除容器。

Watchtower 将自动检测 Docker Hub 上的新镜像发布,将它们拉到您的机器上,并使用该镜像替换容器。现有容器将被关闭,并在其位置创建新的相同容器。您提供的相同标志docker run将提供给替换容器。

默认情况下,Watchtower 仅适用于 Docker Hub。您可以通过在配置文件中提供凭据将其与私有映像注册表一起使用。

创建一个包含以下内容的 JSON 文件:

{
    "auths": {
        "example.com": {
            "auth": "credentials"
        }
    }
}

替换example.com为您的注册表路径。

接下来从您的注册表用户名和密码生成凭据字符串:

echo -n 'username:password' | base64

将生成的 Base64 编码字符串粘贴到配置文件中,替换credentials占位符文本。

将配置文件挂载到 Watchtower 容器中以启用对注册表的访问:

docker run -d \
    -v config.json:/config.json
    -v /var/run/docker.sock:/var/run/docker.sock \
    containrrr/watchtower

Docker 缺乏检测上游镜像更新并将其应用到正在运行的容器的任何机制。您可以按顺序使用 Docker CLI 命令docker-compose作为更高级别的抽象,也可以使用像 Watchtower 这样的第三方工具在新镜像版本发布时替换您的容器。

根据您的情况,您可能根本不需要以这种方式升级容器。如果您的团队使用 CI 管道在每次提交时构建 Docker 镜像,您可能已经每天多次生成和部署更新的镜像。在这种情况下,请确保您使用该--pull标志,docker build以便上游修复包含在您的图像中。

未经允许不得转载:表盘吧 » 如何升级 Docker 容器以应用镜像更新