加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 电商 > 正文

一个疑难故障,坑了我半年青春

发布时间:2021-01-20 13:12:21 所属栏目:电商 来源:网络整理
导读:《一个疑难故障,坑了我半年青春》要点: 本文介绍了一个疑难故障,坑了我半年青春,希望对您有用。如果有疑问,可以联系我们。 作者介绍 林伟壕 ,网易游戏资深运维工程师.现任职于网易游戏,从事游戏运维相关工作;曾就职于中国电信,负责数据网络维护、网络

参考:

  • https://lists.gt.net/linux/kernel/2256803
  • https://lkml.org/lkml/2014/2/15/217
  • https://github.com/docker/docker/issues/21081
  • https://github.com/torvalds/linux/commit/eeb61e53ea19be0c4015b00b2e8b3b2185436f2b

原因:

从sched: Fix race between task_group and sched_task_group的解析来看,就是parent 进程改变了它的task_group,还没调用cgroup_post_fork()去同步给child,然后child还去访问原来的cgroup就会null.

不过这个问题发生在比较低版本的Docker,基本是Docker 1.9以下,而我们用的是Docker1.11.1/1.12.1.所以尽管报错现象比较相似,但我们还是没有100%把握.

但是,这个提醒却给我们打开了思路:去看内核代码,实在不行就下掉所有业务,然后全部升级操作系统内核,保持一个月观察期.

于是,我们开始啃Linux内核代码之路.先查看操作系统本地是否有源码,没有的话需要去Linux kernel官方网站搜索.

“`

apt-cache search linux-image-3.16.0-4-amd64

apt-get source linux-image-3.16.0-4-amd64

“`

下载了源码包后,根据报错syslog的内容进行关键字匹配,发现了以下内容.由于我们的机器是x86_64架构,所以那些avr32/m32r之类的可以跳过不看.结果看下来,完全没有可用信息.

/kernel/linux-3.16.39#grep -nri “unable to handle kernel NULL pointer dereference” *

arch/tile/mm/fault.c:530:????????????? pr_alert(“Unable to handlekernel NULL pointer dereferencen”);

arch/sparc/kernel/unaligned_32.c:221:??????????????? ? printk(KERN_ALERT “Unable to handle kernel NULL pointerdereference in mna handler”);

arch/sparc/mm/fault_32.c:44:??????? ???“Unable to handle kernel NULL pointer dereferencen”);

arch/m68k/mm/fault.c:47:?????????????????? pr_alert(“Unable tohandle kernel NULL pointer dereference”);

arch/ia64/mm/fault.c:292:??????????? printk(KERN_ALERT “Unable tohandle kernel NULL pointer dereference (address %016lx)n”,address);

debian/patches/bugfix/all/mpi-fix-null-ptr-dereference-in-mpi_powm-ver-3.patch:20:BUG:unable to handle kernel NULL pointer dereference at?????????? (null)

最后,我们还是下线了所有业务,将操作系统内核和Docker版本全部升级到最新版.这个过程有些艰难,当初推广这个系统时拉的广告历历在目,现在下线业务,回炉重造,挺考验勇气和决心的.

故障处理

下面是整个故障处理过程中,我们进行的一些操作.

升级操作系统内核

对于Docker 1.11.1与内核4.9不兼容的问题,可以删除原有的Docker配置,然后使用官方脚本重新安装最新版本Docker

“`

/proxy/bin#ls /var/lib/dpkg/info/docker-engine.

docker-engine.conffiles? docker-engine.md5sums??? docker-engine.postrm???? docker-engine.prerm

docker-engine.list?????? docker-engine.postinst?? docker-engine.preinst

#Getthe latest Docker package.

$curl -fsSL https://get.docker.com/ | sh

#启动

nohupdocker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock-s=devicemapper&

“`

这里需要注意的是,Docker安装方式在不同操作系统版本上不尽相同,甚至相同发行版上也有不同,比如原来我们使用以下方式安装Docker:

“`

apt-get install docker-engine

“`

然后在早些时候,还有使用下面的安装方式:

“`

apt-get install lxc-docker

“`

可能是基于原来安装方式的千奇百怪导致问题丛出,所以Docker官方提供了一个脚本用于适配不同系统、不同发行版本Docker安装的问题,这也是一个比较奇怪的地方,所以Docker生态还是蛮乱的.

验证

16:44:15 up 28 days,23:41,? 2 users,?load average: 0.10,0.13,0.15

docker????30320???? 1? 0 Jan11 ???????? 00:49:56 /usr/bin/docker daemon -p/var/run/docker.pid

Docker内核升级到1.19,Linux内核升级到3.19后,保持运行至今已经2个月多了,都是ok的.

总结

这个故障的处理时间跨度很大,都快半年了,想起今年除夕夜收到服务器死机报警的情景,心里像打破五味瓶一样五味杂陈.期间问过不少研究Docker和操作系统内核的同事,往操作系统内核版本等各个方向进行了测试,但总与正确答案背道而驰或差那么一点点.最后发现原来是处理得不够彻底,比如升级不彻底,环境被污染;比如升级的版本不够新,填的坑不够厚.回顾了整个故障处理过程,总结下来大概如下:

回归运维的本质

运维要具有预见性、长期规划,而不能仅仅满足于眼前:

  1. 应急预案:针对可能系统上线后可能发生的故障类型进行总结,并提供应急预案.
  2. 抢通业务:优先抢通业务,再处理故障.
  3. 应用版本选择等技术选型问题:在环境部署和应用选型时需要特别注意各种版本,最好采用社区通用或者公司其他同学已经测试或验证可行的版本.
  4. 操作系统内核:要合理升级内核,只有定位到确定版本存在的问题,才能有针对性的升级内核版本,不然一切徒劳.
  5. 在我们原来的设计中,不同用户调度器针对同一个容器同时操作没有加锁机制,也没有按照对源判断原则,也曾出现过迁移失败的情况.迁移时判断迁往的目的地址是否就是本地地址,如果是本地地址应该拒绝操作的.这个问题不知你是否觉得眼熟.我倒是发现,很多人程序开发过程中,就经常不对输入源或者操作的源状态进行判断,结果出现了各种bug.

Google的能力

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读