解决kubernetes中pod连接外部Redis速度慢的问题

解决kubernetes中pod连接外部Redis速度慢的问题

问题描述 #

用户反应, 在kubernetes中部署的pod去访问外部的redis时, 速度很慢.
redis地址: 10.193.96.73:20100,10.193.96.73:20101,10.193.96.188:20100,10.193.96.188:20101,10.193.96.189:20100,10.193.96.189:20101

已知:

  • pod ip: 10.194.43.122
  • pod所在机器ip: 10.193.40.57

tcpdump抓包 #

我们选择一个redis端点(10.193.96.188:20101)抓包, 登录pod所在node(10.193.40.57)执行抓包:

tcpdump -n -i eth0 'host 10.193.96.188 and port 20101'

在redis所在服务器上抓包:

tcpdump on pod node

我们分析一下结果:

包含多个 SYN 包[S](TCP 握手的第一个步骤, 同一主机10.193.40.57多次尝试与目标主机建立连接:

  • 首次尝试:09:36:45.205732
  • 再次尝试:09:36:47.285717
  • 第三次尝试:09:37:03.820543
  • 第四次尝试:09:37:04.885753

表明目标主机可能没有响应(例如服务未运行、网络问题或防火墙阻止)。

于是我想在目标服务器上, 也就是redis主机上使用同样的端口抓包.

tcpdump -n -i eth0 'host 10.193.40.57 and port 20101'

tcpdump on redis host

发现并没有任何包. 怀疑是不是端口根本不通啊.

telnet测试端口 #

在pod所在node上测试redis服务器上20101端口是不是不通.

telnet 10.193.96.188 20101

telnet test port

还真是, 端口不通.

于是去排查虚拟机所在安全组, 发现安全组没有开放该端口. 安全组添加该端口之后发现问题解决.

总结 #

因为redis暴露了很多端点, 有三台服务器, 每一台服务器暴露了两个端口20100和20101. 所以pod服务在连接redis时, 遇到20101端口失败之后, 尝试重传, 也就是TCP Retransmission. 重传也不行, 然后切换使用了20100端口, 然后完成redis读写. 这样的现象就是, redis没有完全无法使用, 只是读写速度慢.
因为有使用20101端口重试的过程, 和切换端口20100的过程, 所以这个过程很慢. 这就解释了为什么用户反映连接redis速度慢.

其实很简单的一个问题, 遇到这样的问题, 完全可以通过telnet测试一下端口就能解决的. 抓了半天包, 浪费时间. 可见解决问题的思路非常重要. 先了解整个通讯的流程和原理, 要逐层分析, 渐渐的深入才可以.