在Docker容器中运行sshd

6

我在这里找到了这个Dockerfile示例:

// version 1
FROM ubuntu:latest
RUN apt update && apt install ssh  -y
RUN service ssh start
CMD ["/usr/sbin/sshd","-D"]

当我构建和运行这个 Dockerfile时,它会在前台运行一个 SSH 服务器,这很好。

但如果我使用以下 Dockerfile

// version 2
FROM ubuntu:latest
RUN apt update && apt install ssh -y
RUN service ssh start
# CMD ["/usr/sbin/sshd","-D"] // without this line

然后运行容器:

~$ docker run -p 2222:22 -it ssh_server

同时,如果我只是在Dockerfile文件中安装SSH:

当尝试从另一个终端连接时,它将无法正常工作。看起来需要调用sshd。

// version 3
FROM ubuntu:latest
RUN apt-get update && apt-get install -y ssh

使用以下方式运行容器:

~$ docker run -p 2222:22 -it ssh:test
~$ service ssh start
* Starting OpenBSD Secure Shell server sshd 

现在我可以连接到容器了。所以我想知道:如果版本1中的 RUN ssh service start 这一行是必需的,那么为什么版本3中不需要呢?

更加混乱的是,如果我构建并运行版本4:

// version 4
FROM ubuntu:latest
RUN apt update && apt install ssh  -y
#RUN service ssh start // without this line
CMD ["/usr/sbin/sshd","-D"] 

这也不起作用。

请有人解释一下这些行为吗?service ssh start/usr/sbin/sshd之间的关系是什么?


2
你为什么要在容器内运行sshd?这似乎是一种反模式。我建议不要将容器视为虚拟机。如果你想进入正在运行的容器,最好使用docker exec - John Kugelman
"RUN" 是在构建时执行的步骤,而不是在实际运行容器时执行的步骤。此外,在运行Ubuntu容器时,它只会启动其中的一个CMD进程,init/systemd 不会运行。 - Tobias K.
1
RUN 命令实际上是一个完全的空操作。 - larsks
3个回答

7

现在一切都清楚了:

/usr/sbin/sshd 是运行ssh服务器的方法。它不能自行运行(版本4)是因为当您运行 service ssh start 时,脚本/etc/init.d/ssh 会创建目录 /run/sshd,这是运行sshd所必需的。

该脚本还调用可执行文件/usr/sbin/sshd,但由于它作为构建的一部分而运行,并不能持续超过临时容器的生命周期。

可以持续的是目录/run/sshd!这就是为什么我们以CMD方式运行/usr/sbin/sshd就能成功的原因!

谢谢大家!


你的答案是正确的:/etc/init.d/ssh 在调用 /usr/bin/sshd 之前会执行一些操作,并且对文件系统所做的任何更改都将保存到 Docker 镜像中。除了创建 /run/sshd 外,启动脚本还将生成 SSH 主机密钥(/etc/ssh/ssh_host_*),如果它们不存在的话。 - Gordon Hopper

2

在@YoavKlein的回答基础上,service ssh start可以接受传递给sshd的参数,因此不必像这样:

# Incidentally creates /run/sshd
RUN service ssh start
# Run the service in the foreground when starting the container
CMD ["/usr/sbin/sshd", "-D"]

您只需执行以下操作

# Run the service in the foreground when starting the container
CMD ["service", "ssh", "start", "-D"]

这将通过 service 启动 SSH 服务器,但在前台运行,避免需要单独使用 RUN 进行第一次设置。


0
我从 @mark-raymond 那里得到了这个想法 :)
以下带有 -D 标志的 docker run 命令对我有效!:
docker run -itd -p 2222:22 <dockerImageName:Tag> /usr/sbin/sshd -D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接