使用 pkill 的新 --require-handler 标志来防止中断

主要观点:

  • 尽可能不在生产环境中使用信号,可用更安全的替代方案如套接字或varlink,详见早期文章
  • 若必须使用信号,需注意移除信号处理程序(如 SIGHUP)时未移除信号发送者会导致生产中断,许多信号默认会终止进程。
  • pkill --require-handler(-H)和kill --require-handler标志可仅向已注册对应信号处理程序的进程发送信号,防止此类问题。
  • 使用pkill -H -F pidfile可防止中断,将全范围事件变为更易控制的情况,且未找到匹配进程时pkill -H返回代码 1,便于管理员监控。

关键信息:

  • Meta 生产中因移除 SIGHUP 处理程序导致 LogDevice 服务中断,数千服务器同时终止,带来复杂问题。
  • 信号问题根源是许多信号默认终止进程,如 SIGHUP 既有“挂断”原意又被用于请求重新加载配置或旋转日志,导致含义混淆。
  • pkill -H通过读取/proc/[pid]/status中的信号处理程序信息来检测进程是否有信号处理程序,避免向无处理程序的进程发送信号。
  • 在系统管理中,pkill -H可用于更新postrotate脚本中的信号发送方式,当无信号处理程序时pkill命令返回非零状态码,便于发现和处理。
  • 移除应用程序中的信号处理程序时,应检查可能发送该信号的代码或配置,可使用bpftrace程序查找发送的信号。
  • 最好结合使用pkill -H作为安全网、通过 eBPF 监控信号使用情况以及改进进程弹性和 IPC 策略来消除生产环境中的残留信号发送者。

重要细节:

  • LogDevice 服务有 SIGHUP 处理程序用于旋转日志,代码清理时移除了该处理程序但未移除发送 SIGHUP 的调用站点,导致日志轮转配置仍发送 SIGHUP 而使进程终止。
  • pkill -H在检测信号处理程序时,通过解码/proc/[pid]/status中的SigCgt字段来判断进程是否有对应信号的处理程序。
  • 示例中展示了安装 SIGHUP 处理程序的程序和无处理程序的程序在pkill -H测试中的不同结果。
  • /etc/logrotate.d/目录中的postrotate脚本可使用pkill -H更新信号发送方式,未注册处理程序时pkill命令会失败。
  • bpftrace程序可用于查找发送给指定进程的信号及发送者。pkill -H已作为 procps-ng 4.0.3 的一部分发布,在大多数发行版中可用。对于新应用,优先使用更明确的 IPC 机制,对于无法避免使用信号的系统,pkill -H是有效的保护措施。
阅读 41
0 条评论