TiDB 如何在 LVS FULL NAT 模式下显示客户端真实 IP
【是否原创】是
【首发渠道】TiDB 社区
【正文】
作者:
靳献旗 汽车之家 DBA,TUG 2021 MVA
1. 背景
公司 TiDB 集群前端负载均衡器使用的是 LVS,FULL NAT 模式, 这种模式最大的一个问题是:RealServer 无法获得用户 IP ,即在 TiDB 数据库中无法显示客户端真实 IP,显示的是 LVS 服务器上的一个 IP。很多时候,在排查 TiDB 问题时,需要获取客户端真实 IP,这给我们带来了一定困难。本文简单讲述下如何在 TiDB-Server 端显示客户端真实 IP 的方法和工作原理。
2.FULL NAT 概述
本文主要针对 LVS FULL NAT 场景,所以本节简单介绍下其工作原理、优缺点及解决办法。本文中使用到的 IP 均已脱敏处理。
2.1 工作原理
如图所示,FULLNAT 模式是 NAT 的一种扩展,不仅仅将目的 IP 地址进行替换,同时还将源 IP 地址进行了替换,这样做的好处是将 real server 从 virtual server 的后端网络中解放出来,不再要求与 virtual server 位于同一子网内。工作过程如下:
(1) 当客户端发出一个请求的数据包到达负载均衡器后,负载均衡器会对请求数据包同时做 SNAT 和 DNAT,将请求数据包修改为:{ LVS 出口 IP 地址 192.168.2.101、LVS 端口号、LVS 的 MAC 地址 } -> { 某台 Tidb-Server 的 IP 地址、某台 Tidb-Server 的端口号、某台 Tidb-Server 的 MAC 地址 }。
(2) 这样负载均衡器就可以独立的和真实服务器进行数据包的传送。
(3) 真实服务器收到请求的数据包,返回响应的数据包:{ 某台 Tidb-Server 的 IP 地址、某台 Tidb-Server 的端口号、某台 Tidb-Server 的 MAC 地址 } -> { LVS 的入口 IP 地址、LVS 端口号、LVS 的 MAC 地址 } 。此时在真实服务器上查看 TCP 连接为:DIP -> RIP。
(4) 当返回的数据包到达负载均衡器后,负载均衡器将返回数据包再次同时做 DNAT 和 SNAT。
(5) 负载均衡器返回数据包给客户端。
FULL NAT 模式下报文变化:
说明:
2.2 优缺点
优点
扩展性好,负载均衡器和真实服务器可以跨 VLAN 部署
缺点
真实服务器无法获取客户端真实 IP
2.3 解决办法
针对上一小节中提到的 FULL NAT 模式无法获取客户端真实 IP 的问题有没有解决办法?答案是有。
TOA 名字全称是 tcp option address,是 FULL NAT 模式下能够让后端服务器获取 ClientIP 的一种实现方式,它的基本原理比较简单:
(1) 客户端用户请求数据包到达 LVS 时,LVS 在数据包的 tcp option 中插入 src ip 和 src port 信息
(2) 数据包到达后端服务器(装有 toa 模块)后,应用程序正常调用 getpeername 系统函数来获取连接的源端 IP 地址
(3) 由于在 toa 代码中 hook(修改)了 inet_getname 函数(getpeername 系统调用对应的内核处理函数),该函数会从 tcp option 中获取 LVS 填充的 src 信息
(4) 这样后端服务器应用程序就获取到了真实客户端的 ClientIP,而且对应用程序来说是透明的。
3. 实战
3.1 测试环境
3.2 部署步骤
(1) 升级 TiDB 到 5.0 版本
因为参数 enable-tcp4-only 是从 5.0 开始引入的,因此,如果集群版本低于 5.0 ,需要先升级集群,本文测试使用的版本是 5.1.3。
(2) 开启 enable-tcp4-only
所有 TiDB Server 节点需要开启 enable-tcp4-only,参考步骤如下
a) 编辑集群拓扑文件
tiup cluster edit-config stale_read_test
server_configs:
tidb:
b) 重新加载配置
tiup cluster reload stale_read_test -R tidb
c) 检查配置是否生效
select * from information_schema.cluster_config where TYPE=‘tidb’ and key
=‘enable-tcp4-only’;
参数说明
(3) 安装 ip_vs_ca 模块
需要在所有 TiDB Server 服务器上安装 ip_vs_ca 模块
从 git 上 (https://github.com/yubo/ip_vs_ca) 下载安装包 ip_vs_ca-master.zip
yum -y install cmake
unzip ip_vs_ca-master.zip
cd ip_vs_ca-master
cmake .
cd src/
make
insmod ./ip_vs_ca.ko
cp -fr /root/ip_vs_ca-master /usr/local/src/
echo insmod /usr/local/src/ip_vs_ca*/src/ip_vs_ca.ko >> /etc/rc.local
查看计数器和版本信息
cat /proc/net/ip_vs_ca_stats
(4) 测试
客户端通过 LVS VIP 连接到 TiDB 集群后,在 TiDB 端通过 show processlist 查看客户端 IP。
3.3 实际效果
未开启 enable-tcp4-only 的效果
开启 enable-tcp4-only 的效果
show processlist;
慢日志
general log
从以上信息可以看到,无论是 show processlist,还是慢日志,还是 general log ,都可以看到客户端真实 IP 地址,为排查问题提供了很大便利。
4. 总结
公司私有云提供统一的 LVS 服务,为了减少维护成本,TiDB 集群统一使用之家云 LVS 作为负载均衡器。由于 LVS FULL NAT 模式的工作原理决定了在 TiDB 端无法看到客户端真实 IP,本文主要讲解了 TiDB 在这种工作模式下如何查看客户端真实 IP 的解决方法,希望能够帮助需要的同学。
参考资料
https://docs.pingcap.com/zh/tidb/v5.1/tidb-configuration-file/
https://github.com/pingcap/tidb/pull/21552
https://www.jianshu.com/p/e770a11481e9
https://github.com/yubo/ip_vs_ca
https://zhuanlan.zhihu.com/p/364703954
https://github.com/alibaba/LVS/tree/master/docs
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/6ef86c2616685e1230ee9d9a7】。文章转载请联系作者。
评论