一个疑难故障,坑了我半年青春……
时间:2018-12-10 19:44 来源:网络整理 作者:墨客科技 点击:次
林伟壕,网易游戏资深运维工程师。现任职于网易游戏,从事游戏运维相关工作;曾就职于中国电信,负责数据网络维护、网络安全防御等工作。深入研究Linux运维、虚拟化等,现致力于企业级网络安全防护自动化体系构建。 相对物理环境,虚拟化环境更加错综复杂。之前弄KVM虚拟化时经常遇到好多次莫名其妙的网络故障,查出来的原因要么是操作系统内核bug,要么是KVM与操作系统内核版本不兼容,最后是通过升级操作系统内核或者KVM版本修复了。没想到,转型到Docker后,又重蹈覆辙了。 本文将介绍一个困扰笔者近半年的虚拟化环境下的疑难故障,最后排查出来的故障原因和修复手段也让人啼笑皆非。并非因为这个过程有多复杂,而是分享一个心理历程,思考在遇到故障时如何兼顾业务和技术,如何正确使用搜索引擎。 故障现象 我们有一套高性能代理集群,之前内测阶段运行稳定,结果等正式上线后不到半个月,提供代理服务的宿主突然接二连三死机,导致宿主上的所有服务全部中断。 故障分析 故障时宿主直接死机,无法远程登录,机房现场敲键盘业务反应。由于宿主syslog已接入ELK,所以我们采集了当时死机前后的各种syslog。 报错日志 通过查看死机宿主的syslog发现机器死机前有以下kernel报错: Nov 12 15:06:31 hello-worldkernel: [6373724.634681] BUG: unable to handle kernel NULL pointer dereferenceat 0000000000000078 Nov 12 15:06:31 hello-world kernel: [6373724.634718] IP: []pick_next_task_fair+0x6b8/0x820 Nov 12 15:06:31 hello-world kernel: [6373724.634749] PGD 10561e4067 PUDffdb46067 PMD 0 Nov 12 15:06:31 hello-world kernel: [6373724.634780] Oops: 0000 [#1] SMP 显示访问了内核空指针后触发系统bug,然后引起一系列调用栈报错,最后死机。 为进一步分析故障现象,首先需要理解这套高性能代理集群的架构。 架构介绍
单个节点,是在万兆网卡的宿主机上跑Docker容器,然后在容器中跑Haproxy实例,每个节点、实例的配置信息、业务信息都托管在调度器上。 特别之处在于:宿主使用Linux Bridge直接给Docker容器配置IP地址,所有对外服务的IP,包括宿主自己的外网IP都绑在Linux Bridge上。 应用介绍 每台宿主的操作系统、硬件、Docker版本全部一致,其中操作系统和Docker版本如下: [操作系统] System : Linux Kernel : 3.16.0-4-amd64 Version : 8.5 Arch : x86_64 [Docker版本] Docker version 1.12.1, build 6b644ec 初步分析 该集群的宿主配置一致,故障现象也一致,疑点有三个: 1、Docker版本与宿主内核版本不兼容 三台宿主的环境本来一致,但1台稳定跑服务2个月才死机,1台跑服务1个月后死机,另外1台上线跑服务一周便会死机。 发现每台宿主除了死机的异常日志,平时也有相同报错日志: time="2016-09-07T20:22:19.450573015+08:00"level=warning msg="Your kernel does not support cgroup memory limit" time="2016-09-07T20:22:19.450618295+08:00" level=warningmsg="Your kernel does not support cgroup cfs period" time="2016-09-07T20:22:19.450640785+08:00" level=warningmsg="Your kernel does not support cgroup cfs quotas" time="2016-09-07T20:22:19.450769672+08:00" level=warningmsg="mountpoint for pids not found" 根据上面提示,应该是操作系统内核版本对该版本的Docker不支持某些功能所导致。不过在搜索引擎上搜索这并不影响Docker的功能,更不加影响系统稳定性。 比如: time="2017-01-19T18:16:30+08:00"level=error msg="containerd: notify OOM events" error="openmemory.oom_control: no such file or directory" time="2017-01-19T18:22:41.368392532+08:00"level=error msg="Handler for POST /v1.23/containers/338016c68da6/stopreturned error: No such container: 338016c68da6" 是Docker 1.9以来就有的问题,1.12.3修复了。参考https://github.com/docker/docker/ issues/24211 比如Github上有人回复: “I have been update my docker from 1.11.2 to 1.12.3, This issue is fixed. BTW, this error message can be ignored, it should really just be a warning.” 但这里所说的都只是v1.12.2版本就能修复的问题,我们升级Docker版本后发现死机依旧。 于是,我们接着通过各种Google确认了很多与我们存在相同故障现象的问题,初步确认故障与Docker的相关性: https://support.mayfirst.org/ticket/10872 又根据以下官方issue初步确认Docker版本与系统内核版本不兼容可引发宕机的关联性: https://github.com/docker/docker/issues/19910 接着,通过官方的changelog和issue确认宿主所使用Docker版本与系统内核版本不兼容问题: https://github.com/docker/docker/blob/v1.12.2-rc1/CHANGELOG.md 出于尝试心理,我们把Docker版本升级到1.12.2后,未出意外仍出现死机。 2.使用Linux bridge方式改造宿主网卡可能触发bug 找了那台宿主跑服务一周就会死机的宿主,停止运行Docker,只改造网络,稳定跑了一周未发现异常。 3.使用pipework给Docker容器配置IP可能触发bug 由于给容器分配IP时我们采用了开源的pipework脚本,因此怀疑pipework的工作原理存在bug,所以尝试不使用pipework分配IP地址,发现宿主仍出现死机。 于是初步排查陷入困境,眼看着宿主每月至少死机一次,非常郁闷。 故障定位 (责任编辑:admin) |
