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

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


当前回答

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

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

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

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

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

其他回答

你试过这个吗:https://github.com/v2tec/watchtower。 它是一个简单的工具,运行在docker容器中,监视其他容器,如果它们的基本映像改变了,它将拉出并重新部署。

Docker映像的依赖管理是一个真正的问题。我所在的团队开发了一个名为MicroBadger的工具,通过监视容器图像和检查元数据来帮助解决这个问题。它的功能之一是让你设置一个通知网络钩子,当你感兴趣的图像(例如基本图像)发生变化时,它会被调用。

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

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

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

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

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

更新:使用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.

我也遇到过同样的问题,我认为可以通过cron作业每天调用无人值机升级来简单解决。

我的意图是将其作为一种自动和快速的解决方案,以确保生产容器是安全和更新的,因为更新映像和部署具有最新安全更新的新docker映像需要花费一些时间。

也可以使用Github钩子自动化映像的构建和部署

我已经创建了一个基本的docker映像,每天自动检查和安装安全更新(可以通过docker run itech/docker- unattentedupgrade直接运行)。

我还发现了另一种检查容器是否需要更新的方法。

我的完整实现:

Dockerfile

FROM ubuntu:14.04   

RUN apt-get update \
&& apt-get install -y supervisor unattended-upgrades \
&& rm -rf /var/lib/apt/lists/*

COPY install /install
RUN chmod 755 install
RUN /install

COPY start /start
RUN chmod 755 /start

辅助脚本

安装

#!/bin/bash
set -e

cat > /etc/supervisor/conf.d/cron.conf <<EOF
[program:cron]
priority=20
directory=/tmp
command=/usr/sbin/cron -f
user=root
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
EOF

rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["/start"]

开始

#!/bin/bash

set -e

echo "Adding crontab for unattended-upgrade ..."
echo "0 0 * * * root /usr/bin/unattended-upgrade" >> /etc/crontab

# can also use @daily syntax or use /etc/cron.daily

echo "Starting supervisord ..."
exec /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Edit

我开发了一个小工具docker-run,它作为docker容器运行,可以用来更新所有或选定的运行容器中的包,它也可以用来运行任何任意命令。

可以使用以下命令轻松测试:

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

默认情况下,它将在所有运行的容器中执行date命令并显示结果。如果你传递update而不是exec,它将在所有运行的容器中执行apt-get update和apt-get upgrade -y