我使用下面的Dockerfile创建了docker镜像。
FROM ubuntu
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
net-tools \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
netcat \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 1234
ENTRYPOINT bin/bash
CMD ["nc", "-l", "1234"]
我从aboce docker文件创建了图像,并通过运行以下命令使用图像运行docker容器。
docker run -d -i -p 1234:1234 --name daemon nc-ubuntu nc -l 1234
在另一个终端中,我运行以下命令。
telnet localhost 1234
我得到了以下输出。
$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
我正在尝试这个,因为这是第2章实践中的书籍泊坞机的样本,通过配置将docker作为守护进程运行。
根据作者的说法,我应该得到以下结果。
$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello daemon
知道为什么我没有得到预期的输出。
答案 0 :(得分:5)
那永远无法奏效。您的Dockerfile有几个问题。
将ENTRYPOINT
设置为/bin/bash
意味着docker run ...
只是开始bash
。阅读关于ENTRYPOINT
和CMD
的{{3}}。
由于您处于非交互模式,bash
将立即退出。考虑:
host$ docker run nc-ubuntu
host$
Vs的:
host$ docker run -it nc-ubuntu
root@e3e1a1f4e453:/#
后者,因为-it
(分配tty设备,bash在交互模式下需要),会得到bash
提示符。
两次调用都不会导致容器运行netcat
...即使这样做,Dockerfile中的任何内容都不会生成您期望的hello daemon
响应。
nc
命令行不正确。语法是:
nc -l -p <port>
所以你需要:
CMD ["nc", "-l", "-p", "1234"]
如果您确实希望nc
为您提供hello daemon
响应,则需要在-c
命令行中添加适当的nc
命令,如下所示:
CMD ["nc", "-l", "-p", "1234", "-c", "echo hello daemon"]
这使最终的Dockerfile看起来像:
FROM ubuntu
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
net-tools \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
netcat \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 1234
CMD ["nc", "-l", "-p", "1234", "-c", "echo hello daemon"]
如果我构建它:
docker build -t nc-ubuntu .
然后运行:
docker run -d -i -p 1234:1234 --name daemon nc-ubuntu
然后我可以telnet到我的主机上的端口1234
并看到预期的响应:
host$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello daemon
Connection closed by foreign host.
此时,容器将退出,因为nc
在接受单个连接后退出(没有其他参数),并且Docker在前台进程退出时包含退出。
我无法访问该书,所以我无法判断这是否与本书的问题有关,或者您是否在实施中犯了错误,但我建议有一些在线Docker教程可能至少同样好。
答案 1 :(得分:1)
一个对我有用的简单解决方案-
docker run -p 1234:1234 -it --rm alpine /bin/sh -c "nc -l -p 1234"
从另一个终端运行nc localhost 1234