K8S避坑指南 - Deployment更新POD内容器无法收到SIGTERM信号

简介: POD删除,应用进程收不到SIGTERM信号,导致应用注册的JVM关闭钩子失效,问题排查与分析总结

简述

容器化后,在应用发布时,某个服务重启,导致该服务调用方大量报错,直到服务重启完成。报错的内容是RPC调用失败,我们的RPC这块是有优雅关闭的,也就是说,在进程收到SIGTERM信号后,我们通过JVM的ShutdownHook机制,注册了RPC服务的反注册钩子,在进程收到SIGTERM时应用会主动从注册中心摘除自身防止调用方大量报错。但是为什么容器化后会导致这个问题呢?

问题排查

应用正常启动

查看容器内进程

# yum install psmisc
# pstree -p
bash(1)───java(22)─┬─{java}(23)
                   ├─{java}(24)
                   ├─{java}(25)
                   ├─{java}(26)
                   ├─{java}(27)
                   ├─{java}(28)
                   ├─{java}(29)
                   ├─{java}(30)
                    ...
# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:50 ?        00:00:00 /bin/bash run.sh start
root        22     1 15 09:50 ?        00:01:20 /app/3rd/jdk/default/bin/java -Xmx512m -Xms512m ...
root        49     0  0 09:51 pts/0    00:00:00 bash
root       263    49  0 09:59 pts/0    00:00:00 ps -ef

在容器内正常kill 22子进程,可见我们应用的shutdown钩子可以正确处理善后工作

但是,在实际生产中,我们的deploy滚动更新时,通过查看被删除pod的日志,发现pod被terminate的时候,应用进程并未正确处理SIGTERM信号,问题产生。

问题分析

根据对Kubernetes机制的调研,如图:
https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods

因为我们的容器是通过run.sh脚本启动,这个在前面截图可以看到,java进程是1号run.sh进程的子进程,对应Kubernetes原理,可知22号java进程在POD删除时不一定会收到SIGTERM,所以导致了我们的shutdown hook不生效。

问题解决

既然已经定位问题,那么解决问题的方法就有了思路,run.sh执行java进程后,将进程上下文让给java进程,java进程接管,java进程变为容器内的1号进程。
我们参考了这篇文章受到启发
https://yeasy.gitbooks.io/docker_practice/content/image/dockerfile/entrypoint.html
在run.sh执行java前面增加exec命令即可

然后,重新build镜像,发布,查看进程,发现我们的java进程已经是1号进程

然后重启,再查看重启前POD留下的日志

问题解决!

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
11月前
|
Kubernetes Docker 容器
Kubernetes与Docker参数对照:理解Pod中的command、args与Dockerfile中的CMD、ENTRYPOINT。
需要明确的是,理解这些都需要对Docker和Kubernetes有一定深度的理解,才能把握二者的区别和联系。虽然它们都是容器技术的二个重要组成部分,但各有其特性和适用场景,理解它们的本质和工作方式,才能更好的使用这些工具,将各自的优点整合到生产环境中,实现软件的快速开发和部署。
446 25
|
Prometheus Kubernetes 监控
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
|
11月前
|
Kubernetes Shell Windows
【Azure K8S | AKS】在AKS的节点中抓取目标POD的网络包方法分享
在AKS中遇到复杂网络问题时,可通过以下步骤进入特定POD抓取网络包进行分析:1. 使用`kubectl get pods`确认Pod所在Node;2. 通过`kubectl node-shell`登录Node;3. 使用`crictl ps`找到Pod的Container ID;4. 获取PID并使用`nsenter`进入Pod的网络空间;5. 在`/var/tmp`目录下使用`tcpdump`抓包。完成后按Ctrl+C停止抓包。
432 13
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
266 1
【赵渝强老师】Kubernetes中Pod的基础容器
|
Kubernetes 应用服务中间件 nginx
【赵渝强老师】K8s中的Deployment控制器
Kubernetes中的Deployment用于部署无状态应用程序,管理Pod的数量、更新方式和资源限制。通过创建和管理ReplicaSet,Deployment可以实现Pod的自动扩缩容、滚动更新和回滚。本文介绍了Deployment的基本概念,并通过一个具体的示例演示了如何使用Deployment创建、更新和管理Pod。
275 1
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
277 1
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Pod中的业务容器
Pod 是 Kubernetes 中的基本调度单元,由一个或多个容器组成。除了业务容器,Pod 还包括基础容器、初始化容器和临时容器。本文通过示例介绍如何创建包含业务容器的 Pod,并提供了一个视频讲解。示例中创建了一个名为 "busybox-container" 的业务容器,并使用 `kubectl create -f firstpod.yaml` 命令部署 Pod。
222 1
|
存储 Kubernetes 调度
【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别
K8s中的Deployment控制器用于管理无状态应用程序,关注Pod数量、更新方式等;而StatefulSets控制器则管理有状态应用程序,提供持久存储和唯一标识符,适用于需要稳定网络标识符和持久化存储的场景。两者的主要区别在于是否维护状态和顺序。
529 0
|
4月前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
440 2
|
4月前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
305 89

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多