看这个c程序:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int stop = 0;
void handle_signal(int sig)
{
stop = 1;
}
void main() {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
while (stop==0) {
printf("Hello\n");
sleep(1);
}
}
我正在静态编译这个程序:
gcc -static test.c -o test
我正在创建这个 Dockerfile:
FROM scratch
COPY test /test
ENTRYPOINT ["/test"]
我正在构建 docker 镜像:
docker build -t myimage .
最后,我从此图像运行一个容器:
docker run --name mycontainer myimage
我有一个问题:不可能停止这个容器。
我已经尝试过:
我在 kali Linux 下运行 Docker 版本 20.10.25。海湾合作委员会版本:13.3.0
当我尝试运行时出现此错误:
docker kill --signal=SIGINT mycontainer
无法杀死容器 xxxx:杀死后出现未知错误:runc 没有 成功终止:退出状态 1:无法向 init 发出信号: 权限被拒绝。
请注意,我的容器中只有 1 个文件。我没有别的东西(bash,sh,...)
我的目标是理解为什么程序没有退出以及为什么容器没有停止。 你有什么想法吗?我所做的有什么问题吗?
谢谢
也许程序没有退出,容器也没有停止,因为在 Linux 中以 PID 1 运行的进程会忽略像
SIGTERM
和 SIGINT
这样的默认信号,除非明确处理。
如果是这个问题,解决方案是使用像 tini 这样的最小初始化系统来正确转发信号。
修改您的 Dockerfile 以包含
tini
:
FROM scratch
COPY --from=busybox /sbin/tini /tini
COPY test /test
ENTRYPOINT ["/tini", "--", "/test"]
这可确保信号正确转发到您的程序,并且容器将按预期停止。