网络安全检测|网络安全服务|网络安全扫描-香港墨客投资移动版

主页 > 业界资讯 > 网络安全预防措施

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

林伟壕网易游戏资深运维工程师。现任职于网易游戏,从事游戏运维相关工作;曾就职于中国电信,负责数据网络维护、网络安全防御等工作。深入研究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)