Kubernetes删除Deployment时Python应用未捕获SIGINT/SIGTERM信号的问题咨询
先看你的Python代码里的致命语法错误:在Stopper.safe_stop方法里,你写了Stopper.stop = true,但Python里布尔值的正确写法是True(首字母大写)。这个错误会导致信号处理函数执行时抛出NameError,根本没法把Stopper.stop设为True,所以你的循环会一直跑下去,自然不会执行后续创建文件和打印"Done"的逻辑——这是最核心的代码问题。
除了代码错误,还要考虑Kubernetes容器里的信号传递逻辑问题:
1. 修正代码中的布尔值错误
把小写的true改成Python规范的True,修正后的信号处理函数如下:
@staticmethod def safe_stop(*args): Stopper.stop = True
2. 确保Python进程是容器的PID 1
如果你的Docker镜像用了shell形式的CMD/ENTRYPOINT(比如CMD python app.py),那么shell进程会成为容器的PID 1。PID 1进程有特殊的信号处理行为:它不会自动把信号转发给子进程,所以Kubernetes发送的SIGINT/SIGTERM会被shell吃掉,你的Python进程根本收不到。
解决方法是用exec形式的CMD/ENTRYPOINT,让Python进程直接成为PID 1:
# 正确的exec形式写法 CMD ["python", "/path/to/your/app.py"] # 或者用ENTRYPOINT ENTRYPOINT ["python", "/path/to/your/app.py"]
3. 配置Kubernetes优雅终止参数(可选但推荐)
默认情况下Kubernetes给容器30秒的终止宽限期,如果你的进程在收到信号后需要更多时间完成清理逻辑,可以在Deployment的Pod模板里设置terminationGracePeriodSeconds:
apiVersion: apps/v1 kind: Deployment metadata: name: your-app spec: replicas: 1 template: metadata: labels: app: your-app spec: terminationGracePeriodSeconds: 60 # 调整为适合你的清理时间 containers: - name: your-app-container image: your-image:tag volumeMounts: - name: pod-mount mountPath: /mnt/pod volumes: - name: pod-mount # 这里填你的卷配置,比如emptyDir或者PersistentVolumeClaim
验证方法
修正代码和Dockerfile后重新构建镜像,更新Deployment:
kubectl apply -f sig.yaml
然后删除Deployment时,你应该能看到Pod里的Python进程收到信号,退出循环,创建/mnt/pod/sig文件并打印"Done"。你可以用kubectl logs <pod-name>查看日志,或者进入运行中的Pod验证文件是否创建。
内容的提问来源于stack exchange,提问作者Mar Teen

