ansible部署k8s时,跑到docker相关剧本,在reload docker卡住了,然后去到对应机器查看systemctl status docker
,报错Failed to get properties: Connection timed out
.
然后发现systemctl不好用了,网上找的重启dbus什么的,都不好用,只能重启服务器。
然后在messages日志里看到有如下报错
主要是这个问题hung_task_timeout_secs,然后在docker官网找到了这个System unresponsive with 'kernel: INFO: task systemd:1 blocked for more than 120 seconds.' following Docker daemon shutdown
这个问题是怎么出现的,怎么解决请参考下面链接
https://www.aikaiyuan.com/11829.html
一般情况下Linux写磁盘时会用到缓存,这个缓存大概是内存的40%,只有当这个缓存差不多用光时,系统才会将缓存中的内容同步写到磁盘中。但是操作系统对这个同步过程有一个时间限制,就是120秒。如果系统IO比较慢,在120秒内搞不定,那就会出现这个异常。这通常发生在内存很大的系统上。
原因找到了,怎么解决呢?网上也有一些方案,比如
- /sbin/sysctl -w vm.dirty_ratio=10
- echo noop > /sys/block/sda/queue/scheduler
- /sbin/sysctl -w kernel.hung_task_timeout_secs = 0
第一个方案是调整缓存占内存的比例,降到10%,这样的话较少的缓存内容会被比较频繁地写到硬盘上,IO写会比较平稳
第二个方案是修改系统的IO调度策略,使用noop的方式,这是一种基于FIFO的最简单的调度方式
第三个方案是不让系统有那个120秒的时间限制,希望就是我慢就慢点,你等着吧,实际上操作系统是将这个变量设为长整形的最大值。
这三个方案好像都很有道理,应该能搞定这个吧?但是,往往事与愿违,这三种方案经QA验证后一个也没发挥作用,问题依旧偶尔出现。
1、内核hung task检测机制由来
我们知道进程等待IO时,经常处于D状态,即TASK_UNINTERRUPTIBLE状态,处于这种状态的进程不处理信号,所以kill不掉,如果进程长期处于D状态,那么肯定不正常,原因可能有二:
1)IO路径上的硬件出问题了,比如硬盘坏了(只有少数情况会导致长期D,通常会返回错误);
2)内核自己出问题了。
这种问题不好定位,而且一旦出现就通常不可恢复,kill不掉,通常只能重启恢复了。
内核针对这种开发了一种hung task的检测机制,基本原理是:定时检测系统中处于D状态的进程,如果其处于D状态的时间超过了指定时间(默认120s,可以配置),则打印相关堆栈信息,也可以通过proc参数配置使其直接panic。
2、hung task相关配置
1)设置timeout时间:
echo xx > /proc/sys/kernel/hung_task_timeout_secs
xx单位为s。
2)设置hung task后是否触发panic
echo 1 > /proc/sys/kernel/hung_task_panic