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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 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留下的日志

问题解决!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
2月前
|
运维 Kubernetes 监控
Kubernetes详解(十九)——Kubernetes Pod控制器
Kubernetes详解(十九)——Kubernetes Pod控制器
49 3
|
6天前
|
Kubernetes Java 应用服务中间件
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
7 0
|
10天前
|
Kubernetes Shell API
技术笔记:K8s中大量Pod是Evicted状态,这是咋回事?
技术笔记:K8s中大量Pod是Evicted状态,这是咋回事?
18 0
|
19天前
|
Kubernetes API 调度
Pod无法调度到可用的节点上(K8s)
完成k8s单节点部署后,创建了一个pod进行测试,后续该pod出现以下报错: Warning FailedScheduling 3h7m (x3 over 3h18m) default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
68 0
|
2月前
|
运维 Kubernetes 网络协议
Kubernetes详解(十八)——Pod就绪性探针实战
Kubernetes详解(十八)——Pod就绪性探针实战
68 5
|
2月前
|
Kubernetes 算法 调度
k8s群集调度之 pod亲和 node亲和 标签指定
k8s群集调度之 pod亲和 node亲和 标签指定
|
2月前
|
Kubernetes Go Perl
k8s 怎么精准获取deployment关联的pods?
该内容是关于Kubernetes中通过标签获取Deployment管理的Pod的流程和代码示例。首先,Deployment创建ReplicaSets,然后ReplicaSets创建Pod。获取Pod的步骤包括:1) 使用标签选择器获取ReplicaSets;2) 过滤出属于特定Deployment的ReplicaSets;3) 通过标签选择器获取Pod;4) 过滤出属于特定ReplicaSets的Pod。提供的Go代码展示了如何实现这一过程。
|
1月前
|
Kubernetes 微服务 容器
Aspire项目发布到远程k8s集群
Aspire项目发布到远程k8s集群
397 2
Aspire项目发布到远程k8s集群
|
24天前
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
211 3
|
9天前
|
Kubernetes 网络协议 Docker
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船
k8s 开船记-故障公告:自建 k8s 集群在阿里云上大翻船

相关产品

  • 容器服务Kubernetes版