k8s pod 中的程序为啥服务优雅关闭不生效?收不到 sigterm 信号?

简介: 咱们工作的环境在不断的变好,我们也会思考去提升程序运行的环境,让我们的服务更加容易部署,极简维护,现在很多公司都在向着 devpos 发展,殊不知已经被某些大企玩剩下了

咱们工作的环境在不断的变好,我们也会思考去提升程序运行的环境,让我们的服务更加容易部署,极简维护,现在很多公司都在向着 devpos 发展,殊不知已经被某些大企玩剩下了

不过没关系,路得一步一步的走,饭得一口一口的吃,这样我们才会走的稳,长的好

情况描述:

起初我们还是主机环境的时候,使用 ansible 来一键部署我们主机环境上的服务,对于我们的服务自然也是做无状态的

对于服务我们有做优雅关闭,简单来说,就是当程序收到 sigterm 等关闭信号的时候,咱们的服务不会一下子断掉,服务会将当前手里的事情迅速做完再关闭咱们的服务

例如咱们一般在 golang 里面会这样来实现:

stopChan := make(chan os.Signal)
// bind OS events to the signal channel
signal.Notify(stopChan,  syscall.SIGTERM)
// 优雅关闭咱们的服务
defer func() {
       log.Println("closing....")
       // xxxx 做关闭的动作
       // TODO ...
}()
// 阻塞等待关闭信号
select {
case <-stopChan:
}

相信对于熟悉 golang 的兄弟对于这个已经不再陌生了,这个会有啥问题呢?

当然,对于在主机环境里面我们过去都跑了很久了,优雅关闭的功能都是正常运行的,久而久之,就没有人关注他了


开始应用 k8s 来部署我们的服务

慢慢的我们过渡到了容器化的方式来部署我们的服务

一般使用容器化,我们回去编写 Dockerfile ,写我们的启动脚本,做成镜像,进而做成 helm 包,推到 helm 仓库中,在环境中我们就可以使用 helm 工具来高效的部署咱们的服务了,此处就过多赘述了,感兴趣的可以查看如下 2 篇历史文章:

实际情况上,服务在线上跑了一年多了,最近要做一个需求,涉及到服务被 kill 的时候,要到优雅关闭中做一些事情,例如清空某些过程数据

万万没想到,正是优雅关闭在 k8s 部署的时候出了问题,还记当刚才我们说到的在 k8s 中部署的时候,咱们会写启动脚本吗?,例如启动脚本是这样的:

start.sh

#!/bin/bash
./my_demo_svr

例如我们的 Dockerfile 是这样的(仅做示例):

FROM centos
ADD my_demo_svr /
ADD start.sh /
ENTRYPOINT ["sh", "start.sh"]

正是因为咱们在容器中是通过 shell 脚本来启动咱们的 my_demo_svr 服务,那么实际情况是这样来的

bash(xxxpid) --- shell(xxpid) --- my_demo_svr(xxxpid)

那就相当于 my_demo_svr 是 shell 的子进程,shell 收到 k8s 发送的 sigterm 信号的时候,是不会传递给子进程 my_demo_svr 的,因此 my_demo_svr 是不会进行优雅关闭的

看到这里,实际上我们处理的思路就是:

  • 如何让 shell 收到 sigterm 信号的时候,可以传递给他的子进程

实际应用了两种方式

  • 在脚本中,实际启动程序的时候 我们加上 exec 命令exec 命令可以用于调用并执行命令,我们可以这样来修改
#!/bin/bash
exec ./my_demo_svr

简单的修改了这个脚本之后,咱们的 my_demo_svr 程序会替换 shell,并且不会出现子进程,此时 k8s 发送 sigterm 信号的时候,那么接收信号的直接就是 my_demo_svr 服务,此时的优雅关闭就可以正常触发了

  • 使用 linux 中的 trap 命令

trap 命令,可以用来传递信号,我们正好就可以应用它来解决我们的实际问题

例如我们就可以这样来写

此处要注意,咱们的服务启动后面是有 & 的,让我们的 my_demo_svr 在后台运行

#!/bin/sh
./my_demo_svr &
pid="$!"
_kill() {
  echo "start closing ..."
  kill $pid 
  wait $pid
  exit 0
}
trap _kill SIGTERM 
wait

这个时候,当我们的 k8s 中的 pod 被 delete 或者被 rollout restart 的时候,会给咱们容器中的 shell 发送 sigterm 信号,脚本中由于我们使用 trap 命令来传递信号给到 my_demo_svr 程序中,进而触发 my_demo_svr 优雅关闭

至此,请大家引以为鉴,尽量减少踩坑吧,如果有相同经历的欢迎评论交流哦

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
23天前
|
前端开发 编解码 数据格式
浅谈响应式编程在企业级前端应用 UI 开发中的实践
浅谈响应式编程在企业级前端应用 UI 开发中的实践
20 0
浅谈响应式编程在企业级前端应用 UI 开发中的实践
|
1月前
|
Prometheus Kubernetes 监控
容器服务ACK常见问题之pod设置securityContext调整参数失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
14天前
|
存储 Kubernetes 调度
Kubernetes Pod生命周期
Kubernetes Pod生命周期
25 0
Kubernetes Pod生命周期
|
14天前
|
存储 Kubernetes 应用服务中间件
Kubernetes Pod
Kubernetes Pod
47 0
Kubernetes Pod
|
26天前
|
存储 Kubernetes 调度
K8s Pod亲和性、污点、容忍度、生命周期与健康探测详解(下)
本文全面探讨了Kubernetes集群中Pod的四种关键机制——Pod亲和性、污点(Taints)、容忍度(Tolerations)、生命周期以及健康探测,为读者提供了深入理解并有效应用这些特性的指南。
|
26天前
|
Kubernetes 网络协议 Perl
k8s Failed to create pod sandbox: open /run/systemd/resolve/resolv.conf: no such file or directory
k8s Failed to create pod sandbox: open /run/systemd/resolve/resolv.conf: no such file or directory
25 0
|
28天前
|
人工智能 监控 Serverless
如何基于ACK Serverless快速部署AI推理服务
通过上述步骤,可以在ACK Serverless上快速部署AI推理服务,实现高可用、弹性扩展的服务架构。
21 1
|
28天前
|
Kubernetes 网络协议 Docker
K8S核心插件-coredns服务
K8S核心插件-coredns服务
15 0
|
1月前
|
Kubernetes Nacos 微服务
nacos常见问题之v2.2.3 k8s 微服务注册nacos强制删除 pod不消失如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
24 1
nacos常见问题之v2.2.3 k8s 微服务注册nacos强制删除 pod不消失如何解决
|
1月前
|
域名解析 Kubernetes Linux
Kubernetes 外部 HTTP 请求到达 Pod 容器的全过程
Kubernetes 外部 HTTP 请求到达 Pod 容器的全过程
42 4