在用于周期性任务时保持 docker 容器启动的正确方法

Kor*_*van 62 docker

我有安装和配置软件的 docker 容器。

没有任何程序应该一直启动/运行。

我想要什么 - 它能够根据外部事件启动一些命令。喜欢:

docker exec mysupercont /path/to/mycommand -bla -for
Run Code Online (Sandbox Code Playgroud)

docker exec mysupercont /path/to/myothercommand 
Run Code Online (Sandbox Code Playgroud)

但是当容器停止时“exec”是不可能的,而且这个容器里面有一些“工作”数据,用于该命令,所以我不能使用

docker run ...
Run Code Online (Sandbox Code Playgroud)

每次,因为它从图像重新创建容器并破坏我的数据。

保持此类容器运行的“正确”和“最佳”方法是什么?我可以在里面启动哪个命令?

小智 63

您不需要每次都执行docker run

docker run 实际上是两个命令的序列:“create”和“start”。

运行容器时,必须指定“ -it”:

-i, --interactive=false 即使没有附加也保持 STDIN 打开
-t, --tty=false 分配一个伪 TTY

例子:

docker run -it debian:stable bash
Run Code Online (Sandbox Code Playgroud)

在启动时指定的工作完成后(在我的示例 bash 中)。例如,您执行“退出”。集装箱停靠点:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen
Run Code Online (Sandbox Code Playgroud)

现在你可以重新开始

docker start 1329c99a831b
Run Code Online (Sandbox Code Playgroud)

容器启动并再次执行命令“bash”。
使用命令连接到此会话“bash”

docker attach 1329c99a831b
Run Code Online (Sandbox Code Playgroud)

总结一下:您必须了解容器runstart容器之间的区别。
此外,查看“运行”参数“ ”和“ ”的作用的文档-i t-d


小智 25

既然你提到了周期性任务,并且你可能因为你想要使用的方式而使用 cron 之类的东西docker exec,我只是为你准备了药。至少我最终做了这样的事情。

  1. 文件

    FROM <some base>
    CMD tail -f /dev/null
    
    Run Code Online (Sandbox Code Playgroud)
  2. 以通常的方式运行docker run -d ....(我使用过docker-compose

  3. 设置主机crontab,例如:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    
    Run Code Online (Sandbox Code Playgroud)

我发现这个解决方案很好,因为我们在一个非常默认的 linux 环境中依赖古老且经过验证的 crontab,而 Docker 处理您的业务逻辑的更奇特的 deps 和环境变量。如果您的定期任务卡住并出现内存泄漏或其他任何问题,您还可以设置一些限制。


小智 9

是否可以启动已停止的容器的整个业务取决于容器最初的创建方式,即运行方式。如果您运行了一个结束的命令,或者您退出了一个交互式命令,例如 bash,您将无法启动、重新启动或执行已停止的容器。你所能做的就是删除它。是垃圾。

但是 taranaki 的最后一条评论,使用 '-itd',似乎是 docker 的命令。

容器一直在运行,你可以执行任何你想要的,你可以停止、启动或重新启动容器。当然,这只是基于高山图像的初步发现。请注意,如果您附加到容器,它会在您退出时停止,但您可以再次启动它。

  • +1“似乎是码头工人订购的”:-) (5认同)

qoo*_*mon 9

Tail 仍然会时不时地引起一些文件操作。

永眠,无任何副作用

# Ah, ha, ha, ha, stayin' alive...
while :; do :; done & kill -STOP $! && wait $!
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

while :;           # Run an endless loop,
do :;              # of do nothing,
done &             # as background task.
kill -STOP $!      # Stop the background task.
wait $!            # Wait forever, because background task process has been stopped.
Run Code Online (Sandbox Code Playgroud)

  • 哈哈,这个黑客有效:p (2认同)