linux - 对 docker build 永远保持运行 docker 容器感到困惑

标签 linux docker

所以,我第一次接触到了 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 中的 CMDENTRYPOINT 指令,帮助我们指定镜像启动时应该运行什么命令,以及它应该接收什么参数。

通常您要做的是让 ENTRYPOINT 指定应调用的可执行文件或脚本。通常的做法是在此处放置一个 entrypoint.shdocker-entrypoint.sh 脚本。

然后使用 CMD 命令为入口点脚本指定参数。

因此,使用 ENTRYPOINT ["ping"]CMD ["localhost"],容器将以命令 ping localhost 启动。

来自docker documentation :

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/

相关文章:

python - 如何测试处理设置文件所有权而不是 root 的函数

linux - 使用 grep 查找两个 's' 由空格分隔的单词

docker - 部署 Azure 容器实例的奇怪错误

docker拉查找index.docker.io : no such host

docker - Google Kubernetes集群上的待处理Spark Pod:CPU不足

docker - 拉动图像时设备上没有剩余空间

docker - 如何使用 NGINX 入口 Controller 从 Cloudflare 恢复原始客户端 IP

php - 使用 PHP 和 SSL 更新 svn

c - 反调试 : gdb does not write 0xcc byte for breakpoints. 知道为什么吗?

c++ - 如何在 Eclipse CDT 的共享库项目中使用静态库