如何使用传递给 ENTRYPOINT 的服务脚本启动单个进程

How to start single process using service script passed to ENTRYPOINT

我正在将服务脚本传递给 ENTRYPOINT。该服务已启动但已退出。 我必须使用来自 ENTRYPOINT 或 CMD 的服务脚本为每个容器启动一个进程。这样,我可以使用服务脚本重新加载容器内的配置。我也尝试使用 CMD 语句,但它启动服务但立即存在容器。

ENTRYPOINT ["/etc/init.d/elasticsearch", "start"]

/etc/init.d/elasticsearch 脚本具有以下代码以将服务作为守护进程启动。

cd $ES_HOME
echo -n $"Starting $prog: "
daemon --user elasticsearch --pidfile $pidfile $exec -p $pidfile -d
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval

难道不能使用启动脚本来启动服务并保持容器运行ning吗?

用于创建和运行容器的命令。

docker build -f Dockerfile -t="elk/elasticsearch" .
docker run -d elk/elasticsearch
docker run -it elk/elasticsearch bash

一般情况下,您不会将服务脚本与 Docker 一起使用。同样通常,您永远不会在容器内重新启动服务;相反,您停止现有容器,将其删除,然后启动一个新容器。

标准模式是将您尝试 运行 的任何服务作为前台进程直接启动。 (没有 /etc/init.dservicesystemctl 任何东西。)您可以从显示的初始化脚本中提取相关命令。我会将您的 ENTRYPOINT 命令替换为

CMD ["elasticsearch"]

(还有 double-check 和 Elasticsearch documentation,以防万一有其他重要的 command-line 选项。

第二部分是确保数据库数据存储在容器外部。通常您使用 docker run -v 选项将一些备用存储装入容器。例如:

docker run \
  --name elasticsearch \
  -p 9200:9200 \
  -v ./elasticsearch:/var/data/elasticsearch \
  imagename

完成此操作后,您可以随意停止、删除和重新创建容器,这是重新启动服务的正确方法。 (如果基础图像发生变化,您需要执行此操作;如果图像软件或基础 Linux 发行版中存在错误修复或安全问题,就会发生这种情况。)

docker stop elasticsearch
docker rm elasticsearch
docker run -- name elasticsearch ...

您可以编写一个简单的 shell 脚本来保存 docker run 命令,或者使用 Docker Compose 之类的编排工具来声明容器参数。

sysv 初始化脚本属于 "forking" 服务管理器类型。因此它将与启动脚本分离。然后容器需要 pid 1 上的一些初始化进程来控制后台进程。

如果您不想从 initscript 中提取相关命令,那么您仍然可以使用 docker-systemctl-replacement 为您完成这两件事。如果它是 运行 作为 CMD 那么它将启动启用的服务脚本,就像您在普通机器上使用的那样。