所以,我第一次接触到了 Docker。我所做的是在容器上运行一个 Open SSH 服务器,这样我就可以从任何地方登录它。当我将以下内容用于 docker build 时,它工作正常。开放式 SSH 服务器已安装在基本镜像中。
#Download base image
FROM BaseImage
RUN mkdir /var/run/sshd
CMD ["/usr/sbin/sshd", "-D"]
如果我使用以下命令运行容器
docker run -p 52022:22 -dit <MyContainerID>
然后从外部登录到它,就像这样,
ssh -p 52022 <userName>@<IPAddress>
我可以正常登录。
但后来我将我的 docker 文件更改为更通用的文件,将最后一个命令替换为如下所示,因为我从互联网上读到 CMD tail -f/dev/null
是一种保持 docker 容器运行的方法。
CMD service ssh start
CMD tail -f /dev/null
但是,现在如果我尝试从外部登录,我会收到以下错误。
ssh_exchange_identification: Connection closed by remote host
这是什么原因?为什么这不起作用。命令 service ssh start
应该已经在后台启动了 SSH 服务器,不是吗?
最佳答案
我想我只是稍微澄清一下这里的情况。关于如何使用 CMD
指令以及关于 ENTRYPOINT
,我认为你应该考虑在这里使用。
Dockerfile 中的 CMD
和 ENTRYPOINT
指令,帮助我们指定镜像启动时应该运行什么命令,以及它应该接收什么参数。
通常您要做的是让 ENTRYPOINT
指定应调用的可执行文件或脚本。通常的做法是在此处放置一个 entrypoint.sh
或 docker-entrypoint.sh
脚本。
然后使用 CMD
命令为入口点脚本指定参数。
因此,使用 ENTRYPOINT ["ping"]
和 CMD ["localhost"]
,容器将以命令 ping localhost
启动。
The main purpose of a
CMD
is to provide defaults for an executing container
因此对于您的实例,我会使用:CMD ["/usr/sbin/sshd", "-D"]
- 如果您需要在启动时向容器发送任何其他内容,请使采用这些参数的入口点脚本,将脚本设置为 ENTYPOINT
并在它结束时启动进程 /usr/sbin/sshd -D
。
我相信您可能试图在此处跟踪您的 sshd 日志,以便将其通过管道传输到 stdout 和 stderr。使用 sshd 的 -D
标志,您的进程将不会成为守护进程,而是停留在执行它的 session 的前台。使用 docker,这正是您想要的。 Docker 已经准备好记录发送到 stdout 和 stderr 的所有内容,而您想利用它。如果您的 sshd 进程尚未记录到 stdout 和 stderr,那么您可以在 Dockerfile 中对其进行配置。
我建议您阅读这篇文章,因为您正在做的事情:Dockerize an SSH service
关于linux - 对 docker build 永远保持运行 docker 容器感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50099349/