【Linux】Sudo的隐晦bug引发的一次业务问题排查
Sudo的隐晦bug引发的一次业务问题排查
- 写在前面
- 问题描述
- 问题排查
- 高负载现象排查
- 日志排查
- 跟踪任务调度过程
- Sudo引发的问题
- 手动复现
- 问题分析
- 处理方案
写在前面
记录一次生产环境sudo启动进程频繁被Kill且不报错的异常处理过程,如果遇到同样的问题只想要解决方案,直接跳到处理方案部分即可。
问题描述
这次记录一个比较特殊的问题,先说一下这次的环境情况,大数据底座使用的是Ambari管理的HDP-3.1.5.0-152,在上面部署的二开后的Dolphinscheduler调度服务,操作系统版本是Centos7(对应版本7.6.1810)。
接下来说下问题现象,运维日常巡检应该是没有去查看任务运行的情况,只是看看数据的输入输出,然后前两天客户投诉了项目,项目上也一直没查到问题,运维这个时候去看了任务执行的情况,发现存在大量任务的状态为Kill:

这个表现,第一印象就是是不是任务上Yarn被干掉了,但是同时期去查了Yarn的任务记录,并没有任何被Kill的任务:

于是就怀疑是Dolphinscheduler自己杀的任务,项目就安排调度的二开团队上来排查;查了一段时间,开发人员看到日志有大量报负载高的日志,所以认为是服务器负载过高导致的问题,关键日志如下:
[WARN] 2023-03-07 00:31:38.841 org.apache.dolphinscheduler.server.master.dispatch.host.LowerWeightHostManager:[163] - load is too high or availablePhysicalMemorySize(G) is too low, it's availablePhysicalMemorySize(G):247.3,loadAvg:100.42
[WARN] 2023-03-07 00:31:43.842 org.apache.dolphinscheduler.server.master.dispatch.host.LowerWeightHostManager:[163] - load is too high or availablePhysicalMemorySize(G) is too low, it's availablePhysicalMemorySize(G):247.3,loadAvg:100.42
[WARN] 2023-03-07 00:31:48.843 org.apache.dolphinscheduler.server.master.dispatch.host.LowerWeightHostManager:[163] - load is too high or availablePhysicalMemorySize(G) is too low, it's availablePhysicalMemorySize(G):247.46,loadAvg:125.33
这确实也是怀疑方向,随后项目上的维护人员也尝试降低机器负载,减少资源占用之类的方法,不过都没改观这个问题,同事就来找我,看看我有什么头绪。
问题排查
高负载现象排查
接下来说说我的整体排查和定位过程,首先是针对开发人员推断的负载高导致的问题进行了排查,确实存在负载很高的问题,但是和Kill的发生时间无法吻合,不过既然存在这个问题也要稍微排查和处理下,经过定位,发现是客户部署的监控agent有问题,启动大量的线程并且挂死,把负载拉高了,那么先把这部分僵尸进程干掉:

随着负载降低下来,问题依旧存在:

日志排查
基本可以确认开发所说的机器负载导致的问题是站不住脚的,Worker日志中还是大量任务被Kill的记录:
[INFO] 2023-03-07 00:35:14.961 org.apache.dolphinscheduler.server.worker.runner.TaskExecuteThread:[151] - task instance id : 1707926,task final status : KILL,exitStatusCode:137
[INFO] 2023-03-07 00:35:14.961 org.apache.dolphinscheduler.server.worker.runner.TaskExecuteThread:[163] - ========任务执行完成,准备发送任务状态,退出状态码137
这里从日志出发,KILL任务的退出码是137,在这一点的认知上,很多人存在误区,这个状态码是由128+9的来的,含义就是程序接受到了一个信号,信号值为9,而9我们都知道代表的信号是SIGKILL。
退出码137很多人以为就代表内存OOM,由内核Kill,这个是误区,一个进程被内核oomkill他的退出状态码确实是137,但是其他发送SIGKILL信号的行为也会表现为退出状态码137,这个Reddit上有个老哥说过:
Article needs correcting. 137 isn't some magic shorthand for out of memory. An exit code of 128+n means the process received signal number n and exited because of it. 137=128+9, signal 9 is SIGKILL. SIGKILL can be sent due to failing liveness probes.
OK,言归正传,这里我去和研发也核实了Dolphinscheduler的逻辑,他们确认不会是Dolphinscheduler自己发动的kill动作,那么我也就不再Dolphinscheduler上继续深入,我去操作系统日志找找头绪,很遗憾,在/var/log/message中也没找到什么有价值的东西;
跟踪任务调度过程
现在因为没有头绪,我决定找一个失败任务来看看执行了哪些命令,以及失败的命令是什么,这个可以在Dolphinscheduler的任务提交日志里找到相关信息:
[INFO] 2023-03-07 10:30:14.824 - [taskAppId=TASK-20230307-228-321408-1714904]:[299] - task run command:
sudo -u root sh /tmp/dolphinscheduler/exec/process/20230307/44/228/321408/1714904/228_321408_1714904.command
[INFO] 2023-03-07 10:30:14.826 - [taskAppId=TASK-20230307-228-321408-1714904]:[193] - process start, process id is: 11958
[INFO] 2023-03-07 10:30:15.562 - [taskAppId=TASK-20230307-228-321408-1714904]:[204] - process has exited, execute path:/tmp/dolphinscheduler/exec/process/20230307/44/228/321408/1714904, processId:11958 ,exitStatusCode:137
[INFO] 2023-03-07 10:30:16.533 - [taskAppId=TASK-20230307-228-321408-1714904]:[138] - -> ${SPARK_HOME2}/bin/spark-submit --name fact_pm_nr_cellcu_v2_h .....
这里其实可以看到 ,进程启动后,不到一秒的时间久退出了,并且没有任何提交的信息,正常来说,至少会有打印一些Yarn任务的提交信息,比如相关文件的上传,kerberos认证后的连接信息等,这里都没有,也就是说进程已启动就被干掉了,这基本也能排除是Dolphinscheduler自己把它干掉的情况。
接下来我把相关的执行命令粘出来,自己手动跑了一遍,任务不光能执行,还能成功:

实际上到这里问题已经陷入了僵局,直到研发哥们阴差阳错做的一个操作帮我找到了新的契机。
Sudo引发的问题
接近晚上19点的时候,我由上环境看了下,任务依旧被Kill,没啥变化貌似:

不对,我又仔细翻看了几页,在16:40以后,图中标记的226服务器就没有任务被Kill了,难道研发已经找到问题了?本着学习的态度,去和他们团队的维护人员沟通了解情况,但他们说只改了堆内存,没有动别的东西:

我之前已经说过这个和资源没有关系,所以我当即是认为肯定有别的东西发生改动,这个时候我想到,Dolphinscheduler在提交任务的时候,使用的是sudo -u切换root进行的,会不会是和这个有关系,于是我马上去查看了sudo的记录日志,默认一般在/var/log/secure,这下我终于找到了一些端倪,首先这是16:40以及之前的sudo记录:
Mar 7 16:40:32 sudo: dolphinscheduler : PWD=/tmp/dolphinscheduler/exec/process/20230307/43/377/322266/1721369 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/377/322266/1721369/377_322266_1721369.command
Mar 7 16:40:33 sudo: dolphinscheduler : PWD=/tmp/dolphinscheduler/exec/process/20230307/43/377/322261/1721374 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/377/322261/1721374/377_322261_1721374.command
Mar 7 16:40:34 sudo: dolphinscheduler : PWD=/tmp/dolphinscheduler/exec/process/20230307/43/377/322278/1721383 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/377/322278/1721383/377_322278_1721383.command
Mar 7 16:40:34 sudo: dolphinscheduler : PWD=/tmp/dolphinscheduler/exec/process/20230307/43/377/322255/1721380 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/377/322255/1721380/377_322255_1721380.command
这是16:40之后的sudo记录日志:
Mar 7 16:49:46 sudo: root : TTY=pts/6 ; PWD=/tmp/dolphinscheduler/exec/process/20230307/43/381/322310/1721636 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/381/322310/1721636/381_322310_1721636.command
Mar 7 16:49:46 sudo: root : TTY=pts/6 ; PWD=/tmp/dolphinscheduler/exec/process/20230307/43/381/322322/1721648 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/381/322322/1721648/381_322322_1721648.command
Mar 7 16:49:47 sudo: root : TTY=pts/6 ; PWD=/tmp/dolphinscheduler/exec/process/20230307/43/381/322312/1721638 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/381/322312/1721638/381_322312_1721638.command
Mar 7 16:49:47 sudo: root : TTY=pts/6 ; PWD=/tmp/dolphinscheduler/exec/process/20230307/43/381/322324/1721650 ; USER=root ; COMMAND=/bin/sh /tmp/dolphinscheduler/exec/process/20230307/43/381/322324/1721650/381_322324_1721650.command
执行sudo的用户变了,由原先的dolphinscheduler用户变成了root,这个区别就大了,root直接执行sudo并不会发生任何多余的事情,也就相当于直接使用root执行命令。
为了确认我的推测,我继续去核实研发人员是否改过执行用户等配置,才知道他们调整过配置以后,是通过后台启动的服务,而没有使用Ambari重启,这就导致启动用户变成了root,所以sudo用户变成了root,至此我大概确认问题是由sudo导致的,接下来就是佐证。
手动复现
主要目的是为了捕捉sudo的问题,也要尽可能模拟生产环境的操作,那么久手动写一个command的命令集:
#!/bin/sh
BASEDIR=$(cd `dirname $0`; pwd)
cd $BASEDIR
source ${DOLPHINSCHEDULER_HOME}/bin/dolphinscheduler_env.sh
kinit -k -t /etc/security/keytabs/hdfs.headless.keytab user@BIGDATA.COM || true
${SPARK_HOME2}/bin/spark-submit --version
尝试循环去运行这个命令:
for i in {1..10};do sudo -u root sh /tmp/test.command ;done
很快就看见了sudo启动的命令被Killed了:

板上钉钉,sudo确实是概率性的触发这个进程被Kill的问题。
问题分析
现在我们找到了问题的诱因,但是sudo为什么会概率性的触发这个问题呢,我接下来查了很多资料,google、Bing都没找到,最后尝试去sudo的github页去搜issues,终于找到了:
Issue-117:Sudo responds with “killed”

提出者遇到的现象和我们一致,甚至sudo的版本都和我们的相近,我的是1.9.6p1,根据issue的描述,这个问题是sudo在低内核版本下导致的,centos7是3.10的内核,sudo调用到的一个getentropy方法是在3.17引入的,所以使用sudo的时候概率性的会触发这个问题:

调用的位置是arc4random.c:
static void
_rs_stir(void)
{unsigned char rnd[KEYSZ + IVSZ];if (getentropy(rnd, sizeof rnd) == -1)// 这里传递了SIGKILL信号raise(SIGKILL);if (!rs_initialized) {rs_initialized = 1;_rs_init(rnd, sizeof(rnd));} else_rs_rekey(rnd, sizeof(rnd));explicit_bzero(rnd, sizeof(rnd)); /* discard source seed *//* invalidate rs_buf */rs_have = 0;memset(rs_buf, 0, sizeof(rs_buf));rs_count = 1600000;
}
开发者提交了一个commit来规避这个低版本内核导致的问题,commit

处理方案
现在问题已经明朗,具体的解决方案大致有3中:
- 不使用其他用户sudo,直接root,这对于很多生产环境显然不允许;
- 重新编译安装sudo命令,1.8.31-1.9.8的版本在编译的时候需要增加
ac_cv_func_getentropy=no环境变量; - 升级sudo命令到1.9.9及以上版本;
相关文章:
【Linux】Sudo的隐晦bug引发的一次业务问题排查
Sudo的隐晦bug引发的一次业务问题排查写在前面问题描述问题排查高负载现象排查日志排查跟踪任务调度过程Sudo引发的问题手动复现问题分析处理方案写在前面 记录一次生产环境sudo启动进程频繁被Kill且不报错的异常处理过程,如果遇到同样的问题只想要解决方案&#x…...
Java VisualVM 安装 Visual GC 插件图文教程
文章目录1. 通过运行打开 Java VisualVM 监控工具2. 菜单栏初始视图说明3. 工具插件菜单说明4. 手工安装插件5. 重启监控工具查看 Visual GC1. 通过运行打开 Java VisualVM 监控工具 首先确保已安装 Java 环境,如此处安装版本 JDK 1.8.0_161 C:\Users\niaonao>j…...
【C语言】详解静态变量static
关键字static 在C语言中:static是用来修饰变量和函数的static主要作用为:1. 修饰局部变量-静态局部变量 2. 修饰全局变量-静态全局变量3. 修饰函数-静态函数在讲解静态变量之前,我们应该了解静态变量和其他变量的区别: 修饰局部变量 //代码1 #include &l…...
SpringBoot整合ElasticSearch实现模糊查询,排序,分页,高亮
目录 前言 1.框架集成-SpringData-整体介绍 1.1Spring Data Elasticsearch 介绍 2.框架集成Spring Data Elasticsearch 2.1版本说明 2.2.idea创建一个springboot项目 2.3.导入依懒 2.3.增加配置文件 2.4Spring Boot 主程序。 2.5.数据实体类 2.6.配置类 2.7.DAO 数据…...
YARN基本架构
主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成,如图所YA示。 ResourceManager(RM) RM是全局资源管理器,负责整个系统的资源管理和分配 主要由两个组件构成:Scheduler调度器和应用程序…...
【C++复习】类和对象全知识点总结
类和对象写在前面类和对象面向对象类类的定义类的访问限定符类的作用域类的实例化类对象大小this指针类的默认成员函数构造函数析构函数拷贝构造函数运算符重载赋值运算符重载前置后置重载取地址及const取地址操作符重载const 成员static 成员友元友元函数有元类内部类匿名对象…...
基于轻量级YOLOv5开发构建汉字检测识别分析系统
汉字检测、字母检测、手写数字检测、藏文检测、甲骨文检测在我之前的文章中都有做过了,今天主要是因为实际项目的需要,之前的汉字检测模型较为古老了还使用的yolov3时期的模型,检测精度和推理速度都有不小的滞后了,这里要基于yolo…...
leetcode-每日一题-66(简单题,数组)
这道题其实还没那么简单,中间还是有的绕的。。。。给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会…...
LeetCode295之数据流的中位数(相关话题:优先队列)
题目描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 Media…...
助你加速开发效率!告别IDEA卡顿困扰的性能优化技巧
在现代软件开发中,IDE(集成开发环境)是一个必不可少的工具。IntelliJ IDEA是一个广受欢迎的IDE,但有时候IDE的性能可能会受到影响,导致开发人员的工作效率降低。本文将介绍一些可以提高IDE性能的技巧,帮助开…...
Java设计模式-适配器模式
1、简介 适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。 2、适配器模式分类 目标接口(Target&#x…...
Linux 练习六 (IPC 管道)
文章目录1 标准管道流2 无名管道(PIPE)3 命名管道(FIFO)3.1 创建删除管道文件3.2 打开和关闭FIFO文件3.3 管道案例:基于管道的客服端服务器程序使用环境:Ubuntu18.04 使用工具:VMWare workstati…...
合并两个有序链表(精美图示详解哦)
全文目录引言合并两个有序链表题目描述方法一:将第二个链表合并到第一个思路实现方法二:尾插到哨兵位的头节点思路实现总结引言 在前面两篇文章中,我们介绍了几道链表的习题:反转链表、链表的中间结点、链表的倒数第k个结点&…...
33 JSON操作
目录 一、介绍 二、JSON的特点 三、JSON语法 1、json中的数据类型 四、JSON文件的定义 五、读取JSON文件 1、读取json文件的两种方式 (1)read、write (2)json.load 2、使用json.load读取json文件的步骤 3、练习读取json文件 六、练…...
三八妇女节快乐----IT女神活动随笔
献丑了,一首小小散文诗,请大家轻喷 O(≧口≦)O 我的答案 天下芸芸众生,好似夜幕漫天繁星。 与你相识,只是偶然。 简单的一个招呼,于是开始了一段故事。 我们或是诉说,或是分享; 我们彼此倾听&…...
【PSO-PID】使用粒子群算法整定PID参数控制起动机入口压力值
最近在学优化算法,接触到了经典寻优算法之粒子群PSO,然后就想使用PSO算法来调节PID参数,在试验成功之后将此控制算法应用到了空气起动系统上,同时与之前的控制器进行对比看看哪种控制效果最好。 0 引言 PID参数整定主要有两种&…...
当代数据分析指南:激发商业洞见的七个方法(上)
如果说眼下的发生的事能证明什么,那就是基于实时可信的数据分析正在变得越来越重要。但是要是想要在需要的时候准确地获取中肯的洞察,我们所需要的可不只是漂亮的可视化。 如何让你的员工都有能力和机会都做出最好的决策,不管这个决策会有多…...
javaWeb核心02-JSP、EL、JSTL、MVC
文章目录JSP1,JSP 概述2,JSP 快速入门2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3,JSP 原理4,JSP 脚本4.1 JSP 脚本分类4.2 案例4.2.1 需求4.2.2 实现4.2.3 成品代码4.2.4 测试4.3 JSP 缺点5࿰…...
spring-boot+mybatis-plus连接Oracle数据库,及查询相关数据
配置java 略(这里我用的是jdk1.8) 配置maven 环境变量: M2_HOME:D:\LJ\software\java\maven\apache-maven-3.6.3 Path:%M2_HOME%\bin 仓库/jdk/镜像云设置(./config/sitting) 仓库 <localRepository> D:/…...
电商使用CRM系统有什么好处,如何选择
数据显示,使用电商CRM客户管理系统后,企业销售额提高了87%,客户满意度提高了74%,业务效率提高了73%。要在竞争激烈的电商市场取得成功,与目标受众的有效沟通是有效的方法。下面说说什么是电商CRM系统?电商C…...
Clawdbot网关配置教程:实现Qwen3-VL:30B与飞书的无缝对接
Clawdbot网关配置教程:实现Qwen3-VL:30B与飞书的无缝对接 1. 准备工作与环境概述 在开始配置前,请确保已完成以下准备工作: 已在CSDN星图AI云平台完成Qwen3-VL:30B的私有化部署(参考上篇教程)拥有飞书开放平台的企业…...
ADS 2025瞬态仿真实战:手把手教你搞定PCB微带线串扰分析(含变量单位避坑指南)
ADS 2025瞬态仿真实战:手把手教你搞定PCB微带线串扰分析(含变量单位避坑指南) 作为一名硬件工程师,在高速PCB设计中遇到串扰问题就像在迷宫里寻找出口——看似简单却处处暗藏陷阱。特别是当你在ADS 2025中按照教程一步步设置参数&…...
告别网络依赖:用这个开源工具+高德离线包,5步搞定前端地图离线展示
前端开发者的离线地图解决方案:5步实现高德地图本地化部署 在紧急演示、内网开发或网络不稳定的环境中,依赖在线地图服务往往成为前端开发的痛点。我曾参与过一个政府内网项目,现场演示时因网络权限问题导致地图无法加载,最后不得…...
PHPMailer OAuth2认证终极指南:安全挑战与架构实践深度解析
PHPMailer OAuth2认证终极指南:安全挑战与架构实践深度解析 【免费下载链接】PHPMailer The classic email sending library for PHP 项目地址: https://gitcode.com/GitHub_Trending/ph/PHPMailer PHPMailer作为PHP领域最经典的邮件发送库,其OAu…...
Simulink与Plecs联合仿真实现三相桥式电路能量双向流动
simulinkplecs联合仿真源件,三相桥式电路,采用母线电压外环与电流内环控制,可整流也可逆变并网,实现能量双向流动,采用SVPWM调制方式。 1.plecssimulink 2.SVPWM 3.双闭环 支持simulink2022以下版本,联系跟…...
GIS小白必看!Global Mapper处理正射影像的5个高频问题解答(含奥维地图导入避坑指南)
GIS新手实战指南:Global Mapper正射影像处理全解析 第一次打开Global Mapper时,那些密密麻麻的工具栏和复杂的参数设置确实让人望而生畏。去年我刚接触GIS时,处理无人机航拍的正射影像就踩了不少坑——坐标系选错导致影像偏移几百米、导出分幅…...
tcc-g15: 开源散热管理工具实战指南
tcc-g15: 开源散热管理工具实战指南 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 Thermal Control Center(tcc-g15)是一款专为Dell G…...
agent实习面经(十一)
来自网络,侵删 先完成,再完美 某东,某节1.LLM 为什么有幻觉,如何减少 LLM 幻觉?1.1概率生成机制:LLM 本质是基于统计概率预测下一个 token,而非检索事实数据库。当训练数据中缺乏确切信息或模…...
Mojo项目无法import本地.py模块?工程师连夜修复的6种路径/环境变量/Loader级配置错误
第一章:Mojo项目无法import本地.py模块的根本原因剖析Mojo 语言虽兼容 Python 语法,但其运行时环境与 CPython 截然不同——它基于 LLVM 编译为原生机器码,并通过 Mojo Runtime 执行,**不依赖 Python 解释器进程**。因此ÿ…...
OpenClaw终端整合:QwQ-32B命令行操作增强方案
OpenClaw终端整合:QwQ-32B命令行操作增强方案 1. 为什么需要终端智能助手 作为开发者,我们每天要处理大量命令行操作。从简单的目录跳转、文件操作,到复杂的管道命令组合,再到调试报错信息,这些重复性工作消耗了大量…...
