Pulumi 不执行 kubernetes 的正常关闭 pods
Pulumi does not perform graceful shutdown of kubernetes pods
我正在使用 pulumi 来管理 kubernetes 部署。其中一个部署 运行 是一个图像,它拦截 SIGINT 和 SIGTERM 信号以像这样执行正常关闭(这个例子是 运行ning 在我的 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 不会根据 [=] 中描述的内容正常终止24=]。这是 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
没有转发信号到它产生的子进程。
我找到的解决方案是在我的 docker 文件中添加 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 部署。其中一个部署 运行 是一个图像,它拦截 SIGINT 和 SIGTERM 信号以像这样执行正常关闭(这个例子是 运行ning 在我的 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 不会根据 [=] 中描述的内容正常终止24=]。这是 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
没有转发信号到它产生的子进程。
我找到的解决方案是在我的 docker 文件中添加 RUN go build -o worker /path/to/main.go
,然后使用 ./worker --arg1 --arg2
而不是 go run /path/to/main.go --arg1 --arg2
启动 docker 容器。
这样做可确保 go
不会产生任何子进程,并确保信号在 docker 容器内得到正确处理。