一个疑难故障,坑了我半年青春
副标题[/!--empirenews.page--]
《一个疑难故障,坑了我半年青春》要点: 作者介绍 林伟壕,网易游戏资深运维工程师.现任职于网易游戏,从事游戏运维相关工作;曾就职于中国电信,负责数据网络维护、网络安全防御等工作.深入研究Linux运维、虚拟化等,现致力于企业级网络安全防护自动化体系构建. 相对物理环境,虚拟化环境更加错综复杂.之前弄KVM虚拟化时经常遇到好多次莫名其妙的网络故障,查出来的原因要么是操作系统内核bug,要么是KVM与操作系统内核版本不兼容,最后是通过升级操作系统内核或者KVM版本修复了.没想到,转型到Docker后,又重蹈覆辙了. 本文将介绍一个困扰笔者近半年的虚拟化环境下的疑难故障,最后排查出来的故障原因和修复手段也让人啼笑皆非.并非因为这个过程有多复杂,而是分享一个心理历程,思考在遇到故障时如何兼顾业务和技术,如何正确使用搜索引擎. 故障现象我们有一套高性能代理集群,之前内测阶段运行稳定,结果等正式上线后不到半个月,提供代理服务的宿主突然接二连三死机,导致宿主上的所有服务全部中断. 故障分析故障时宿主直接死机,无法远程登录,机房现场敲键盘业务反应.由于宿主syslog已接入ELK,所以我们采集了当时死机前后的各种syslog. 报错日志通过查看死机宿主的syslog发现机器死机前有以下kernel报错:
显示访问了内核空指针后触发系统bug,然后引起一系列调用栈报错,最后死机. 为进一步分析故障现象,首先需要理解这套高性能代理集群的架构. 架构介绍单个节点,是在万兆网卡的宿主机上跑Docker容器,然后在容器中跑Haproxy实例,每个节点、实例的配置信息、业务信息都托管在调度器上. 特别之处在于:宿主使用Linux Bridge直接给Docker容器配置IP地址,所有对外服务的IP,包括宿主自己的外网IP都绑在Linux Bridge上. 应用介绍每台宿主的操作系统、硬件、Docker版本全部一致,其中操作系统和Docker版本如下:
初步分析该集群的宿主配置一致,故障现象也一致,疑点有三个: 1、Docker版本与宿主内核版本不兼容 三台宿主的环境本来一致,但1台稳定跑服务2个月才死机,1台跑服务1个月后死机,另外1台上线跑服务一周便会死机.
根据上面提示,应该是操作系统内核版本对该版本的Docker不支持某些功能所导致.不过在搜索引擎上搜索这并不影响Docker的功能,更不加影响系统稳定性. 比如:
是Docker 1.9以来就有的问题,1.12.3修复了.参考https://github.com/docker/docker/?issues/24211 比如Github上有人回复:
但这里所说的都只是v1.12.2版本就能修复的问题,我们升级Docker版本后发现死机依旧. 于是,我们接着通过各种Google确认了很多与我们存在相同故障现象的问题,初步确认故障与Docker的相关性:
又根据以下官方issue初步确认Docker版本与系统内核版本不兼容可引发宕机的关联性:
接着,通过官方的changelog和issue确认宿主所使用Docker版本与系统内核版本不兼容问题:
出于尝试心理,我们把Docker版本升级到1.12.2后,未出意外仍出现死机. 2.使用Linux bridge方式改造宿主网卡可能触发bug 找了那台宿主跑服务一周就会死机的宿主,停止运行Docker,只改造网络,稳定跑了一周未发现异常. 3.使用pipework给Docker容器配置IP可能触发bug 由于给容器分配IP时我们采用了开源的pipework脚本,因此怀疑pipework的工作原理存在bug,所以尝试不使用pipework分配IP地址,发现宿主仍出现死机. 于是初步排查陷入困境,眼看着宿主每月至少死机一次,非常郁闷. 故障定位因为还有线上业务在跑,所以没有贸然升级所有宿主内核,而是期望能通过升级Docker或者其它热更新的方式修复问题.但是不断的尝试并没有带来理想中的效果. 直到有一天,在跟一位对Linux内核颇有研究的老司机聊起这个问题时,他三下五除二,Google到了几篇文章,然后提醒我们如果是这个 bug,那是在 Linux 3.18 内核才能修复的. (编辑:西双版纳站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |