假设我有一个基于ubuntu:latest的普通容器。现在有一个安全更新和ubuntu:latest更新在docker repo。

我如何知道我的本地映像及其容器运行落后? 是否有一些最佳实践来自动更新本地映像和容器来跟踪docker回购更新,这在实践中会给你同样的好处,让无人值守的升级运行在传统的ubuntu机器上


当前回答

另一种方法是假设您的基本映像很快就会落后(这很可能发生),并定期强制应用程序构建另一个映像(例如每周),如果它发生了更改,则重新部署它。

据我所知,像官方Debian或Java这样的流行基础镜像会更新它们的标记来满足安全修复,所以标记不是不可变的(如果你想要更强的保证,你需要使用参考[image:@digest],在最新的Docker版本中可用)。因此,如果你要用docker build -pull构建你的映像,那么你的应用程序应该得到你引用的base image标签的最新和最好的。

由于可变标记可能令人困惑,所以最好每次都增加应用程序的版本号,这样至少在您的方面,事情会更清楚。

因此,我不确定在前面的答案之一中建议的脚本是否能完成工作,因为它不重新构建应用程序的映像——它只是更新基本映像标记,然后重新启动容器,但新的容器仍然引用旧的基本映像散列。

我不提倡在容器中运行cron类型的作业(或任何其他进程,除非真的有必要),因为这违背了每个容器只运行一个进程的原则(关于为什么这样更好有各种各样的争论,所以我不打算在这里讨论)。

其他回答

我不打算讨论您是否希望在生产中进行无人值守的更新(我认为不需要)。我只是把这个留在这里作为参考,以防有人觉得有用。在终端中使用以下命令将所有docker映像更新到最新版本:

# docker images | awk '(NR>1) && ($2!~/none/) {print $1":"$2}' | xargs -L1 docker pull

我们使用一个脚本来检查正在运行的容器是否以最新映像启动。我们还使用upstart init脚本来启动docker映像。

    #!/usr/bin/env bash
    set -e
    BASE_IMAGE="registry"
    REGISTRY="registry.hub.docker.com"
    IMAGE="$REGISTRY/$BASE_IMAGE"
    CID=$(docker ps | grep $IMAGE | awk '{print $1}')
    docker pull $IMAGE

    for im in $CID
    do
        LATEST=`docker inspect --format "{{.Id}}" $IMAGE`
        RUNNING=`docker inspect --format "{{.Image}}" $im`
        NAME=`docker inspect --format '{{.Name}}' $im | sed "s/\///g"`
        echo "Latest:" $LATEST
        echo "Running:" $RUNNING
        if [ "$RUNNING" != "$LATEST" ];then
            echo "upgrading $NAME"
            stop docker-$NAME
            docker rm -f $NAME
            start docker-$NAME
        else
            echo "$NAME up to date"
        fi
    done

init看起来像这样

docker run -t -i --name $NAME $im /bin/bash

更新:使用Dependabot - https://dependabot.com/docker/

BLUF:找到正确的插入点来监视容器的更改是一个挑战。如果DockerHub能解决这个问题,那就太好了。(存储库链接已经提到过,但注意在DockerHub上设置它们时-“每当在DockerHub上更新基本映像时,都会在此存储库中触发一个构建。只适用于非官方图片。”)

当我自己尝试解决这个问题时,我看到了几个webhook的建议,所以我想详细说明我使用过的几个解决方案。

Use microbadger.com to track changes in a container and use it's notification webhook feature to trigger an action. I set this up with zapier.com (but you can use any customizable webhook service) to create a new issue in my github repository that uses Alpine as a base image. Pros: You can review the changes reported by microbadger in github before taking action. Cons: Microbadger doesn't let you track a specific tag. Looks like it only tracks 'latest'. Track the RSS feed for git commits to an upstream container. ex. https://github.com/gliderlabs/docker-alpine/commits/rootfs/library-3.8/x86_64. I used zapier.com to monitor this feed and to trigger an automatic build of my container in Travis-CI anytime something is committed. This is a little extreme but you can change the trigger to do other things like open an issue in your git repository for manual intervention. Pros: Closer to an automated pipline. The Travis-CI build just checks to see if your container has issues with whatever was committed to the base image repository. It's up to you if your CI service takes any further action. Cons: Tracking the commit feed isn't perfect. Lots of things get committed to the repository that don't affect the build of the base image. Doesn't take in to account any issues with frequency/number of commits and any API throttling.

一个简单而伟大的解决方案是牧羊人

另一种方法是假设您的基本映像很快就会落后(这很可能发生),并定期强制应用程序构建另一个映像(例如每周),如果它发生了更改,则重新部署它。

据我所知,像官方Debian或Java这样的流行基础镜像会更新它们的标记来满足安全修复,所以标记不是不可变的(如果你想要更强的保证,你需要使用参考[image:@digest],在最新的Docker版本中可用)。因此,如果你要用docker build -pull构建你的映像,那么你的应用程序应该得到你引用的base image标签的最新和最好的。

由于可变标记可能令人困惑,所以最好每次都增加应用程序的版本号,这样至少在您的方面,事情会更清楚。

因此,我不确定在前面的答案之一中建议的脚本是否能完成工作,因为它不重新构建应用程序的映像——它只是更新基本映像标记,然后重新启动容器,但新的容器仍然引用旧的基本映像散列。

我不提倡在容器中运行cron类型的作业(或任何其他进程,除非真的有必要),因为这违背了每个容器只运行一个进程的原则(关于为什么这样更好有各种各样的争论,所以我不打算在这里讨论)。