K8S集群中Mysql问题 Got timeout reading communication packets

出现的一个问题,记录一下,以及给出解决方案,具体是什么导致的,暂未可知

前提:

在MYSQL的内部约束中有个表,叫做host_cache表,该表记录了连接到mysql的连接的信息,有个字段 **max_connect_errors **定义了某个ip的中断连接错误的上限,某个ip超过了这个上限就会被mysql拉入黑名单,拒绝连接。这个机制mysql用来保护自己不受攻击。

详细的表字段可以在官方文档中查看:https://dev.mysql.com/doc/refman/8.0/en/performance-schema-host-cache-table.html

这里只说三个字段:

  • IP:每个连接的ip地址,主键
  • HOST:DNS解析后的域名或HOSTNAME
  • SUM_CONNECT_ERRORS:已经连续出现中断错误的次数,如果在 max_connect_errors以内连接成功,该字段会被清零,每个IP都有对应的错误个数,单独计数。

操作以及现象

问题发生在K8S集群中部署的mysql服务,但是该问题不局限于容器化的mysql。
现象:mysql的host_cache表中的错误链接次数会增加,然后查看mysql日志会发现有Got timeout reading communication packets 类似错误。

我们把集群中的mysql的svc类型设置为nodeport,

  1. 我们自己的容器化服务使用mysql的域名访问,解析出来的IP就是对应的服务的podIP,域名就是该服务的域名。没出现中断错误超过最大错误连接数的

  2. 我们自己的不能容器化的服务,只有keystone通过私网的节点IP+nodeport来访问数据库。阿里云的DBS备份也是通过该形式来访问。mysql将该连接解析为某张虚拟网卡的IP,没有域名,出问题的环境解析的网卡ip都是以0 结尾。该形式出现中断错误数超过最大错误连接数的情况,导致通过此种方式的连接全部被mysql拒绝。

  3. 以集群的公网IP+mysql nodeport去访问,此为navicat访问形式,mysql解析为节点的私网ip,其实也是某张网卡的IP。该连接没出现问题。

  4. 昨晚在预升级环境,我们把keystone、阿里的DBS以及我们容器化的与mysql有交互的服务全部卸载后,出现了一个现象,有一个未知服务每隔10分钟就对mysql发起tcp连接以及关闭连接。访问形式就是nodeip+port,此时mysql的错误数+1。当把mysql的svc改为clusterip时,十分钟两次的访问未出现。

探讨的一些结论

  1. MYSQL IP解析问题
    通过nodeip+mysqlport形式访问mysql,mysql反dns解析会解析成某个网卡的ip 20.201.38.0
    通过公网IP+mysqlport形式访问mysql,mysqlfan反dns解析会解析成主机的网卡ip
    原因应该是,解析的dns服务不认识,不知道最开始来源的连接ip,就将该连接的ip解析成转发到mysql服务的网卡ip
  2. mysql中断错误类型,什么时候才会+1
    网络波动;程序被突然中断,之前的连接还保留着(因为占用的文件或者连接被锁),可能会造成中断连接
  3. 十分钟两次的是什么东西,什么原因
    可以肯定是通过nodeip+mysqlport访问的形式,第一种可能是某个应用程序在循环跑,第二个可能是我们自己的某个程序没有被卸载干净,或者是卸载后某个类似读取文件建立连接的进程突然被杀死但是这个文件或者连接还是被锁着占用着,所以会定时的维护这个状态。

疑问点

  1. K8S对于服务的网络调用链路是如何转发的,在mysql svc不同形式以及外部访问的不同形式访问时,网络链路是怎么走的?
  2. K8S的DNS解析问题,对于IP是如何解析的
  3. 如何复现网络波动,以造成错误+1
  4. 我们的环境的错误连接数是什么原因造成的,是网络波动还是,某个应用程序连接总出错
  5. 预生产环境的十分钟2次,是哪个程序引起的,还是某个残余的进程,或文件,连接占用,有没有那个程序能对应上10分钟这个频率。
  6. 预生产环境如何能把十分种2次复现

相关参考

telnet ip port 可以复现mysql错误,此时的mysql错误日志是:Got timeout reading communication packets

十分钟两次的mysql错误日志: Got an error reading communication packets

  1. https://dev.mysql.com/doc/refman/8.0/en/host-cache.html#blocked-host------mysql官方解释DNS和缓存
  2. https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html-----------mysql官方解释连接状态变量
  3. https://dev.mysql.com/doc/refman/8.0/en/performance-schema-host-cache-table.html----mysql官方host_cache表
  4. https://dev.mysql.com/doc/refman/8.0/en/communication-errors.html--------------------通讯错误和连接中断

解决方案

  1. 手动刷新cache表将错误数归零
  2. 将最大错误数调到最大
  3. 跳过DNS解析的验证,此种方式也可以增强mysql性能。也就是将cache表的大小调到0 --skip-name-resovle=on
  4. 禁用最大错误数
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐