【问题标题】:Mandatory command or entrypoint in docker-composedocker-compose 中的强制命令或入口点
【发布时间】:2021-12-31 18:21:55
【问题描述】:

我们刚刚开始将我们的应用程序迁移到容器中,所以我对容器世界非常陌生。 在我们的容器镜像中,我们只有安装了一些 rpm 和一些脚本复制到容器的基本 linux 镜像。我们当时认为我们不会在图像本身中有任何命令/入口点。当容器启动时,我们的部署作业将在容器内运行一个脚本来启动服务(jetty/hbase/..)。即容器启动和服务启动是部署作业中的两个不同步骤。 这一直有效,直到我使用 docker run/podman run 命令启动容器。 现在,我们考虑转向 docker-compose 方式。但是,当我说“docker-compose up”时,它会抱怨“错误:没有在命令行上指定命令或在此图像中指定为 CMD 或 ENTRYPOINT”。即在使用 run 命令启动容器时,没有任何 CMD 或 ENTRYPOINT 是可以的,但是在使用 docker-compose 启动容器时,必须提供一个,为什么会这样?

为了克服该错误,我们尝试将一些简单的 CMD 放入 compose 文件中,例如 /bin/bash。但是,使用这种方法,容器会立即退出。我发现许多 stackoverflow 链接解释了为什么会发生这种情况,例如:Why docker container exits immediately。如果我将 CMD 作为 tail -f /dev/null 放在撰写文件中,那么容器就会保持不变。

请您帮助澄清什么是正确的做法。如前所述,我们的要求是我们要在没有任何服务的情况下启动容器,然后单独启动服务。因此,我们没有 CMD/ENTRYPOINT 的任何用例。

【问题讨论】:

  • 为什么要把容器的启动和包含的服务的启动分开呢?这听起来像XY problem
  • 您可能想查看初始化系统和解决方法,例如哑初始化 github.com/Yelp/dumb-init 。我认为没有默认的初始化系统,因此轻量级容器可以成为一个东西,但我不太确定
  • 另外,通常你不需要在容器中运行命令之前“启动”容器,因为在它空闲时你没有任何东西可以运行。
  • 一个容器运行一个进程; Dockerfile CMD 说明了它是什么。您通常不会在容器中“启动服务”。容器要运行的单个进程是什么?您是否需要多个容器来运行您的每个组件(这将是一个非常正常的设置)?
  • 感谢您到目前为止的回答。我们的应用程序本质上包含 Jetty 和 Hbase。我们计划在同一个容器中运行它们。您能否澄清一下这种行为:当我像这样运行图像时: docker run -d bash --> 我的图像没有任何 CMD 或 ENTRYPOINT,因此“bash”成为此处的 cmd。在这种情况下,我的容器会出现并保持不变。但是,如果我将相同的内容放入 compose 文件 CMD: ["bash"] 并说 docker-compose up,那么容器会立即退出。我的问题是如何确保容器在使用 docker-compose 时保持运行。

标签: docker docker-compose podman


【解决方案1】:

容器(图像)应该是你部署的东西不是你部署代码的东西;拥有不可变的基础架构(容器、VM 等)被认为是一种很好的做法。

您的构建过程可能应该(!?)生成容器图像。容器映像经过 (sha-256) 哈希处理以唯一标识它。

每当您的来源发生变化时,您都应该考虑生成新的容器映像。标记容器图像是个好主意,这样您就可以将特定图像(不是图像名称,而是标记版本)绑定到特定构建,以便您始终可以确定哪个,例如提交导致哪个图像版本。

推论:更改容器图像被认为是不好的做法。

首选不可变基础架构的一个原因是您将拥有可重现的部署。如果您在容器版本中遇到问题,您知道您没有更改它,您知道生成它的版本以及使用的源...

容器还有其他最佳实践,包括它们不应该包含状态等。它很旧但似乎很全面10 thinks to avoid in containers 并且有许多类似物The Twelve-Factor App

(太!?)容器通常使用CMD 来启动它们的进程,但根据我的经验,最好使用ENTRYPOINT。两者都可以被覆盖,但CMD 被简单地覆盖,而ENTRYPOINT 需要一个特定的--entrypoint 标志。本质上,如果您使用CMD,您的用户必须记住,如果他们想使用命令行参数,也必须运行您的进程。而ENTRYPOINT 容器的行为更像是运行常规的旧二进制文件。

【讨论】:

  • 如果您想将容器视为您在其中运行服务的主机,您可能需要搜索“系统容器”以及“lxc”和“lxd”以用于 linux。如果根据您当前的设置将您的设置打包为 DazWilkin 所描述的“应用程序容器”很棘手,这可能是一种明智的方法。
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2020-03-19
  • 2020-04-28
  • 1970-01-01
  • 2021-10-09
  • 2021-06-12
相关资源
最近更新 更多