Pulumi 不执行 Kubernetes Pod 的优雅关闭

Posted

技术标签:

【中文标题】Pulumi 不执行 Kubernetes Pod 的优雅关闭【英文标题】:Pulumi does not perform graceful shutdown of kubernetes pods 【发布时间】:2021-09-02 13:54:33 【问题描述】:

我正在使用 pulumi 来管理 Kubernetes 部署。其中一个部署运行一个图像,该图像截获 SIGINT 和 SIGTERM 信号以执行正常关闭,如下所示(此示例在我的 IDE 中运行):

"level":"info","msg":"trying to activate gcloud service account","time":"2021-06-17T12:19:25-05:00"
"level":"info","msg":"env var not found","time":"2021-06-17T12:19:25-05:00"
"Namespace":"default","TaskQueue":"main-task-queue","WorkerID":"37574@Paymahns-Air@","level":"error","msg":"Started Worker","time":"2021-06-17T12:19:25-05:00"
"Namespace":"default","Signal":"interrupt","TaskQueue":"main-task-queue","WorkerID":"37574@Paymahns-Air@","level":"error","msg":"Worker has been stopped.","time":"2021-06-17T12:19:27-05:00"
"Namespace":"default","TaskQueue":"main-task-queue","WorkerID":"37574@Paymahns-Air@","level":"error","msg":"Stopped Worker","time":"2021-06-17T12:19:27-05:00"

注意"Signal":"interrupt"Worker has been stopped 的消息。

我发现当我更改源代码(这会更改 docker 映像)并运行 pulumi up 时,Pod 不会根据 this blog post 中的描述正常终止。以下是 GCP 的日志截图:

上图中突出显示的日志行是应用发出的第一条日志行。请注意,关闭消息没有记录在突出显示的行上方,这向我表明该 pod 没有机会执行正常关闭。

为什么 pod 不能通过 kubernetes 提供的优雅关闭机制?这可能是pulumi 执行部署更新的错误吗?


编辑:在进行更多调查后,我发现这个问题正在发生,因为使用 go run /path/to/main.go 启动一个 docker 容器实际上最终会创建两个类似这样的进程(在 exec 进入容器之后):

root@worker-ffzpxpdm-78b9797dcd-xsfwr:/gadic# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.3  0.3 2046200 30828 ?       Ssl  18:04   0:12 go run src/cmd/worker/main.go --temporal-host temporal-server.temporal.svc.cluster.local --temporal-port 7233 --grpc-port 6789 --grpc-hos
root        3782  0.0  0.5 1640772 43232 ?       Sl   18:06   0:00 /tmp/go-build2661472711/b001/exe/main --temporal-host temporal-server.temporal.svc.cluster.local --temporal-port 7233 --grpc-port 6789 --
root        3808  0.1  0.0   4244  3468 pts/0    Ss   19:07   0:00 /bin/bash
root        3817  0.0  0.0   5900  2792 pts/0    R+   19:07   0:00 ps aux

如果运行kill -TERM 1,则信号不会转发到底层二进制文件/tmp/go-build2661472711/b001/exe/main,这意味着不会执行应用程序的正常关闭。但是,如果我运行kill -TERM 3782,则执行正常关闭逻辑

似乎go run 产生了一个子进程,this blog post 暗示信号只转发到 PID 1。除此之外,不幸的是 go run 没有将信号转发到它产生的子进程。

【问题讨论】:

【参考方案1】:

我找到的解决方案是在我的 dockerfile 中添加 RUN go build -o worker /path/to/main.go,然后使用 ./worker --arg1 --arg2 而不是 go run /path/to/main.go --arg1 --arg2 启动 docker 容器。

这样做可以确保go 不会产生任何子进程,并确保在 docker 容器中正确处理信号。

【讨论】:

以上是关于Pulumi 不执行 Kubernetes Pod 的优雅关闭的主要内容,如果未能解决你的问题,请参考以下文章

Pulumi kubernetes ConfigGroup 需要字符串,我只有输出

Docker&Kubernetes ❀ Kubernetes集群Pod控制器 - Horizontal Pod Autoscaler(HPA)

Docker&Kubernetes ❀ Kubernetes集群Pod控制器 - Horizontal Pod Autoscaler(HPA)

3.Kubernetes权威指南 --- 深入掌握Pod

3.Kubernetes权威指南 --- 深入掌握Pod

kubernetes Pod 异常排错