假设我有一个基于ubuntu:latest的普通容器。现在有一个安全更新和ubuntu:latest更新在docker repo。
我如何知道我的本地映像及其容器运行落后? 是否有一些最佳实践来自动更新本地映像和容器来跟踪docker回购更新,这在实践中会给你同样的好处,让无人值守的升级运行在传统的ubuntu机器上
假设我有一个基于ubuntu:latest的普通容器。现在有一个安全更新和ubuntu:latest更新在docker repo。
我如何知道我的本地映像及其容器运行落后? 是否有一些最佳实践来自动更新本地映像和容器来跟踪docker回购更新,这在实践中会给你同样的好处,让无人值守的升级运行在传统的ubuntu机器上
当前回答
下面是一种自动更新docker容器的最简单方法
通过$ crontab -e放置作业:
0 * * * * sh ~/.docker/cron.sh
创建目录~/。Docker与文件cron.sh:
#!/bin/sh
if grep -Fqe "Image is up to date" << EOF
`docker pull ubuntu:latest`
EOF
then
echo "no update, just do cleaning"
docker system prune --force
else
echo "newest exist, recompose!"
cd /path/to/your/compose/file
docker-compose down --volumes
docker-compose up -d
fi
其他回答
你不会知道你的集装箱在后面没有运行码头拉。然后,您需要重新构建或重组您的映像。
docker pull image:tag
docker-compose -f docker-compose.yml -f production.yml up -d --build
这些命令可以与完成升级所需的任何其他东西一起放在脚本中,尽管一个合适的容器不需要任何额外的东西。
我回答的前提是:
容器使用标签运行。 相同的标签可以指向不同的图像UUID,因为我们喜欢/觉得合适。 对图像的更新可以提交到新的图像层
方法
首先使用安全补丁更新脚本构建所有容器 为以下内容构建一个自动化流程 使用安全补丁脚本将现有映像运行到新容器 提交对映像的更改为 现有标记->,然后逐个重新启动容器 新版本标签->用新标签替换少数容器->验证->将所有容器移动到新标签
此外,可以升级基本映像/可以定期构建具有完整的新基本映像的容器,这是维护者认为必要的
优势
我们在创建新的安全补丁映像时保留映像的旧版本,因此如果需要,我们可以回滚到以前正在运行的映像 我们保留了docker缓存,从而减少了网络传输(只有被更改的层连接到网络上) 升级过程可以在过渡到产品化之前在阶段中进行验证 这可以是一个受控的过程,因此只有在必要/被认为重要时才可以推送安全补丁。
一种“docker方式”是使用docker hub自动构建。当上游容器被重建时,Repository Links特性将重建你的容器,Webhooks特性将向你发送通知。
看起来webhooks仅限于HTTP POST调用。您需要设置一个服务来捕获它们,或者可能使用其中一个POST发送电子邮件服务。
我还没有深入研究,但是新的Docker通用控制平面可能有一个检测更新容器和重新部署的功能。
我也遇到过同样的问题,我认为可以通过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
One of the ways to do it is to drive this through your CI/CD systems. Once your parent image is built, have something that scans your git repos for images using that parent. If found, you'd then send a pull request to bump to new versions of the image. The pull request, if all tests pass, would be merged and you'd have a new child image based on updated parent. An example of a tool that takes this approach can be found here: https://engineering.salesforce.com/open-sourcing-dockerfile-image-update-6400121c1a75 .
如果你不控制你的父映像,就像你依赖于官方ubuntu映像的情况一样,你可以写一些工具来检测父映像标记或校验和(不是一回事,标记是可变的)的变化,并相应地调用子映像构建。