def*_*ect 8 rust docker windows-subsystem-for-linux
我在使用 Ubuntu 映像的 Windows 10 上使用 WSL2,以及使用 WSL 集成的 Docker for Desktop Windows (2.2.2.0)。
我有一个 Rust TCP 服务器。当我使用cargo run(或之后的二进制文件cargo install)运行它时,它会做正确的事情,我可以发送Ctrl-C到它终止。我没有在代码中做任何显式的信号处理。
我把它变成了一个 Docker 镜像。这是 Dockerfile。
FROM rust:1.40 as builder
COPY . .
RUN cargo install --path . --root .
FROM debian:buster-slim
COPY --from=builder ./bin/myserver ./myserver
EXPOSE 8080
ENTRYPOINT ["./myserver"]
Run Code Online (Sandbox Code Playgroud)
然后我做:
docker build -t myserver .
docker run -it --rm -p 8080:8080 myserver
Run Code Online (Sandbox Code Playgroud)
试图Ctrl-C进程^C在终端中显示字符,但信号似乎没有到达进程。我必须使用docker kill. 我读过其他像这样和这样的帖子。它表明组合-it和使用ENTRYPOINTor的数组参数版本CMD应该允许信号到达它,但是这些似乎对我没有帮助。
要查看它是否与我的设置(桌面版 Docker、WSL 等)或我的 Dockerfile 有关,我遵循了 docker -http-https-echo的自述文件,并且我能够Ctrl-C过程。检查 Dockerfile 并没有表明它做的事情与我不同,但显然我遗漏了一些东西。
小智 11
您的问题的原因是内核特别对待PID为1的进程,并且默认情况下在接收SIGTERM或SIGINT信号时不会终止该进程。
您有两个选择:
--init向docker run命令标志。这样,将创建一个 PID 为 1 的特殊进程,它将成为您的进程的父进程,并将代理所有信号并正确获取您的进程。好的做法是将这两种方法结合起来。
我希望不要迟到,Nikscorp 提供了您的容器无法停止的可能原因之一,但在其他情况下也可能会发生这种情况,如下所示:
您ENTRYPOINT是一个 shell 脚本,并且您没有使用 Exec:通常,当您从 shell 脚本运行容器时,您的容器在新进程上运行,导致您的容器不会收到任何信号,这可以使用 exec 命令来解决
不要在 Exec 入口点中使用 Pipeline:在某些情况下,这可能会生成在子 shell 中运行的应用程序,从而导致无信号(SIGINT、SIGTERM、SIGKILL)
使用不正确的入口点形式:推荐的入口点形式是 exec 形式,就像这个(这发生在我身上并解决了我的问题)
ENTRYPOINT ["/app/bin/your-app", "arg1", "arg2"]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |