在Docker容器中安装计划任务或安装计划任务在容器中

61次阅读
没有评论

问题描述

有一个关于在Docker容器中安排计划任务的问题。他在一个虚拟机上有一个包含入口点(jar)的Docker镜像。他面临一个困境,不知道如何安排任务来运行这个jar文件。他有两个选项:
1. 如果在虚拟机上运行cron,然后调用docker run命令来生成一个容器,并对jar文件运行不同的任务。问题在于,一旦运行了一个任务,容器就会自动终止,并且第二个任务没有前面运行任务的历史记录。他相信有一种方法可以通过入口点使容器永远运行,但他还没有探索/测试过。
2. 他可以在容器内部安装cron,并通过Dockerfile提供cron。然而,问题在于如何启动容器并保持其运行以运行cron任务?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

你不需要使用cron。大多数服务器操作系统(如CoreOS、RedHat、CentOS、Ubuntu等)现在都使用systemd,systemd单元文件可以运行你的容器来执行任务。以下是一个示例:
1. 创建两个单元文件:mytimedstuff.service和mytimedstuff.timer。.timer文件定义了服务应该何时执行。
2. 在mytimedstuff.service中,添加以下内容:

[Unit]
Description=Executes mystuff
After=default.target docker_network_apps.service
Requires=default.target docker_network_apps.service

[Service]
Type=oneshot
User=root
ExecStartPre=/usr/bin/docker pull mystuff:stable
ExecStartPre=-/bin/bash -c "/usr/bin/docker rm -f mystuffcontainer 2>/dev/null"
ExecStart=/bin/bash -c "/usr/bin/docker run --name mystuffcontainer mystuff:stable mystuff"
  1. 在mytimedstuff.timer中,添加以下内容:
[Unit]
Description=My stuff runs at 00:10 sharp.

[Timer]
OnCalendar=00:10:00

[Install]
WantedBy=multi-user.target

在上面的示例中,我们定义了两个单元文件:mytimedstuff.service和mytimedstuff.timer。mytimedstuff.service文件定义了容器的启动和停止命令,mytimedstuff.timer文件定义了服务应该在何时执行。你可以根据自己的需求修改这些文件。

方案2

在Docker中,最佳实践是为不同的进程创建多个容器,并通过docker-compose管理它们。这样可以在一个文件中定义应用程序所需的所有容器,并通过一个命令启动它们。
另一种方法是使用ENTRYPOINT来运行一个管理进程的脚本,或者使用像supervisord这样的进程管理器。以下是两种简单的解决方案:
1. 使用ENTRYPOINT运行一个脚本来管理多个进程。你可以在Docker文档中找到一个示例。
2. 使用进程管理器supervisord,你可以在这篇文章中找到关于如何在Docker中使用supervisor的详细说明。

需要注意的是,在使用Docker时,一个容器只应该运行一个服务。

总结

在本文中,我们讨论了如何在Docker容器中安排计划任务。我们提供了两种解决方案:使用systemd单元文件或使用进程管理器。你可以根据自己的需求选择适合你的解决方案。

请注意,这些解决方案可能会因版本差异而有所不同。在实施之前,请确保备份你的数据并仔细阅读相关文档。

希望这些解决方案对你有帮助!如果你有任何进一步的问题,请随时提问。

正文完