如何使用 Minikube 在 pod 中捕获 SIGTERM

Ami*_*ler 4 bash termination kubernetes minikube

我使用的是有史以来最简单的 docker:

FROM ubuntu
COPY script.sh /script.sh
CMD /script.sh
Run Code Online (Sandbox Code Playgroud)

所有脚本的作用是:

#!/bin/bash

function sigterm() {
    echo "Got SIGTERM"
    exit
}

trap sigterm SIGTERM

i=1
while true; do
    echo "$(date +%H:%M:%S) | $((i++)) | $HOSTNAME"
    sleep 1
done
Run Code Online (Sandbox Code Playgroud)

我在 Minikube 中运行这个容器,但我无法让它从 kubernetes 捕获任何 SIGTERM。

我尝试删除 pod/deployment 或放大和缩小它。在任何情况下,它都不会在被删除之前得到 SIGTERM。它尊重terminationGracePeriodSecondspreStop在杀死 pod 之前似乎没有运行命令或发送 SIGTERM。

那是因为使用了 minikube 吗?还是我做错了什么?

(部署不是服务的一部分,它只是一个部署)(SSH 进入 pod 并手动 -kill使其按预期工作)

Jos*_*sto 6

在 CMD 上阅读Dockerfile 文档

CMD指令有三种形式:

  • CMD ["executable","param1","param2"] (exec 形式,这是首选形式)
  • CMD ["param1","param2"] (作为ENTRYPOINT的默认参数)
  • CMD 命令 param1 param2 (shell 形式)

如果你使用CMD的shell形式,那么会在/bin/sh -c中执行

所以你使用的是shell形式,这意味着你的命令是/bin/sh -c script.sh。然后,当 kubernetes 向容器发送 SIGTERM 时,接收信号的不是 script.sh 进程,而是 /bin/sh 进程。这就是为什么您看不到“Got SIGTERM”消息的原因。

创建 Dockerfile 时,请确保使用 exec 形式。否则,应用程序将作为 /bin/sh -c 的子命令启动,它不传递信号。容器的 PID1 将是外壳,您的应用程序将不会收到任何信号。

尝试更改您的 Dockerfile 以使用 exec 形式

FROM ubuntu
COPY script.sh /script.sh
CMD ["/script.sh"]
Run Code Online (Sandbox Code Playgroud)