暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Alpine Linux 网络延时事故

ProdanLabs 2020-04-25
1019


同事反映在容器环境通过phoenix操作HBASE时,返回的数据很慢,耗时25s左右,而在非容器环境只需2s, 于是勾引起我的求知欲....

容器环境,23.9秒

~ $ time python test.py 
1587781799.9128911
23.95860481262207
33667
0.6693758964538574
351
real    025.33s
user    024.46s
sys     00.47s
~ $ 

非容器环境,2.4秒

(base) [root@bigdata-dev03 ~]# time python test.py      
1587781936.8903282
2.4388413429260254
33667
0.6046943664550781
351

real    0m3.930s
user    0m3.003s
sys     0m0.244s
(base) [root@bigdata-dev03 ~]


本着能抄作业绝不写作业的原则,先Google,alpine因为没有/etc/nsswitch.conf文件,每次访问都去请求dns,没解析到再查的hosts,恰好碰到conntrack丢包问题导致dns延时,请求会因为conntrack丢包导致延时叠加,但是我们换成IP请求,依旧是25s左右





  抓包分析

在容器内,通过tcpdump抓包,发现内核有丢包

109 packets captured
2756 packets received by filter
2587 packets dropped by kernel

3.10核,Alpine Linux 3.11

NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.11.5
PRETTY_NAME="Alpine Linux v3.11"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
~ $ uname -r
3.10.0-1062.18.1.el7.x86_64

升级至5.6.7,抓包发现内核不再有丢包情况,耗时10s左右,但依旧有问题

~ $ uname -r
5.6.7-1.el7.elrepo.x86_64
~ $ time python test.py
1587781294.1356337
10.101239442825317
33667
0.367321252822876
351
real    010.86s
user    010.28s
sys     00.09s
~ $ 

好吧,继续截取的数据包分析,发现tcp报文有Out_of_Order和dup ack

2273    21.438452   192.168.1.72    172.16.0.199    TCP 7006    [TCP Out-Of-Order] 80 → 33258 [ACK] Seq=7098353 Ack=5443 Win=50304 Len=6940 TSval=991811317 TSecr=979000685
2274    21.438487   192.168.1.72    172.16.0.199    TCP 4230    [TCP Out-Of-Order] 80 → 33258 [ACK] Seq=7105293 Ack=5443 Win=50304 Len=4164 TSval=991811317 TSecr=979000685
2275    21.438632   172.16.0.199    192.168.1.72    TCP 78  [TCP Window Update] 33258 → 80 [ACK] Seq=5443 Ack=7098353 Win=332672 Len=0 TSval=979000685 TSecr=991811316 SLE=7109457 SRE=7116397
2276    21.438701   172.16.0.199    192.168.1.72    TCP 78  [TCP Dup ACK 2270#1] 33258 → 80 [ACK] Seq=5443 Ack=7098353 Win=332672 Len=0 TSval=979000685 TSecr=991811316 SLE=7109457 SRE=7123337

TCP Out_of_Order即TCP乱序队列,一般来是因为网络拥塞,导致顺序包抵达时间不同,延时太长,或者包丢失,需要重新组合数据单元;dup ack即重复应答,2270#1代表了数据段丢失TCP状态,2270代表数据丢失的位置,1代表第1次丢失。


通过翻阅文档,怀疑是libc库因为某个原因造成查询请求被丢弃与标准C库一样,musl和glibc是libc的两种实现,Alpine Linux其他Linux发行版使用的glibc不同,它的libc是musl libc. 

alpine小哥曾说,用了glibcAlpine Linux便不再是Alpine Linux!为了灵魂,换Debian容器测试,2.4s,到这里可以肯定是Alpine Linux的问题了

app@phoenix-runner-695d49bd7b-sslh8:~$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
app@phoenix-runner-695d49bd7b-sslh8:~$ time python test.py
1587790580.0386345
2.429395914077759
33667
0.7143592834472656
351

real    0m3.887s
user    0m4.264s
sys     0m3.328s
app@phoenix-runner-695d49bd7b-sslh8:~$


目前解决办法就是换掉Alpine Linux镜像,使用Debian。该问题我已在Alpine社区提Issues,期待有原因和解决方法......




往期回顾


由Docker BUG引起的Linux宕机事故

记一次Kubernetes网络排障

文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论