如何使用容器自动删除功能自动重启我的 Docker 容器?

如何使用容器自动删除功能自动重启我的 Docker 容器?

我有一个通用 VPS,正在 Docker 化上面的应用程序。上面大约有​​ 5-6 个容器,其他的就很少了,所以可以根据需要轻松重建这个盒子。

对于每个应用程序,我都有一个启动脚本。WordPress 容器如下所示:

#!/bin/bash

# Get the host IP address
export DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`
echo "Connecting to database on Docker host ${DOCKER_HOSTIP}"

docker run \
    --add-host=docker:${DOCKER_HOSTIP} \
    --network dockernet \
    --network-alias jonblog \
    --detach \
    --restart always \
    --rm \
    jonblog

但是,这会返回一个错误:

冲突的选项:--restart 和 --rm

有几张 Docker 票说这是合理的,但我不明白。我认为我的意思很清楚:如果容器未运行(例如在启动时),那么我想启动它。如果它死了,那么我希望删除该容器,并从基础映像创建一个新的容器。无论如何,容器应该是不可变的 - 我希望保留的任何状态,如媒体文件和日志,都将写入卷。

因此,我认为我应该放弃该--restart标志,然后使用进程管理器来停止和启动 Docker 容器。我可以在这里使用 Monit 吗?我希望能够做类似的事情:

CHECK PROCESS jonblog MATCHING jonblog
  START PROGRAM = "/root/docker/jonblog/host-start.sh"
  STOP PROGRAM = "docker stop jon-blog"

但是,这会检查系统进程表,而不是docker ps,因此它找不到与指定字符串匹配的内容。我可以让它docker ps定期执行,并匹配输出中的行吗?

如果其他工具足够强大,我很乐意使用它。例如,我发现 Supervisor 有点重,但如果它更适合与 Docker 配合使用,我愿意使用它。

关于 --rm 的澄清

我想要的原因--rm是,在 Dockerisation 过程中,我停止当前正在运行的容器、load新版本的映像,然后重新运行上述脚本。这意味着 Docker 会收到restart有关每个容器的策略的通知。我发现,重新启动机器后,我会同时运行 15 个左右略有不同的应用程序版本,这不是我想要的。

我想我可以docker update --restart never在旧容器上使用以防止这种情况发生,但是当我的容器停止时,它就被留在我身边,我很快就会让它自动删除。我可以使用某种 cron 作业定期清理旧容器,但考虑到 Docker 可以帮我做这件事,这感觉有点不合时宜。

寻求一系列答案

一个非常有用的评论建议我应该研究一下 Minikube,它显然简化了 Kubernetes 的设置,甚至一个具有适当技能的人可以在五分钟内启动并运行。

我仍然非常希望看到更多轻量级解决方案被提出,所以我有一系列的答案可供选择。正如所指出的,我想知道像 Monit 这样的流程监控器是否可行。

我首先想到的是,我可以编写一个 shell 循环,docker ps每五秒写入一个文件,持续一分钟,然后每分钟在 Cron 上运行一次。然后我可以使用grepMonitCHECK PROGRAM系统检查来扫描该文件。这有点不合时宜,但如果出现问题,我可以轻松理解。这个建议有什么进展吗?

答案1

我有一个适合我目前对 Docker 理解的答案。评论中建议我尝试 Minikube,虽然毫无疑问它可以快速启动,但我担心这将是一个学习的兔子洞,会让我在 tar 中呆上几个星期。我的工程原则之一是知道一个人何时达到了塞入新信息的认知极限!

因此,我开始用一种简单的方式解决这个问题。我有两个选择:

  1. 使用 Docker 中的容器自动删除功能,并设置我自己的重启系统
  2. 使用 Docker 重启策略,并设置我自己的容器删除系统

我开始使用第一个,认为进程管理器 Monit 很好用,部分原因是它很轻量,部分原因是我熟悉它。然而,我开始觉得它不是一个好的解决方案,因为我需要解决核心问题,即它无法干净地获取 Docker 容器进程列表。

事实上,第二种选择更简洁,而且停止容器清理实际上并不是优先事项,这只是为了保持整洁。当然,我为此使用了 Docker;以下是Dockerfile

# Docker build script for Docker Tidy

FROM alpine:3.6

RUN apk update
RUN apk add docker

# See this for BusyBox cron schedules
# https://gist.github.com/andyshinn/3ae01fa13cb64c9d36e7
COPY bin/docker-tidy.sh /etc/periodic/daily/
RUN chmod +x /etc/periodic/daily/docker-tidy.sh

# Start Cron in the foreground
ENTRYPOINT ["crond", "-l", "2", "-f"]

下面是bin/docker-tidy.sh

#!/bin/sh
#
# With thanks to:
# http://www.doublecloud.org/2015/05/simple-script-to-list-and-remove-all-stopped-docker-containers/

docker rm -v $(docker ps -a -q -f status=exited)

最后,我的解决方案的一个缺点是,如果在停止的容器清理之前重新启动主机,这些容器似乎也会重新启动。因此,我在启动新容器之前重置了这些容器的重启策略。

例如,下面是我在主机上启动 Docker Tidy 容器本身的方法。实际上,我将策略更改代码整理到其自己的脚本中,但这将给出一般思路:

#!/bin/bash

# Removes the restart policy from previous containers
CONTAINER_LABEL=docker-tidy-instance
docker ps --all --filter label=$CONTAINER_LABEL --quiet | xargs --no-run-if-empty docker update --restart no

docker run \
    --label $CONTAINER_LABEL \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --detach \
    --restart always \
    docker-tidy

相关内容