原文来源: https://tidb.net/blog/1d65166f

【是否原创】是
【首发渠道】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 模式下报文变化:

发送端 接收端 备注
192.168.1.1 (CIP) 192.168.2.100 (VIP)
192.168.2.101 (DIP) 192.168.3.1 (RIP) SNAT+DNAT
192.168.3.1 (RIP) 192.168.2.101 (DIP)
192.168.2.100 (VIP) 192.168.1.1 (CIP) DNAT+SNAT

说明:

缩写 说明
CIP 客户端的地址
VIP LVS虚拟地址
RIP 真实服务器,即TiDB Server节点的地址
DIP LVS出口地址
SNAT 来源地址转换
DNAT 目的地址转换

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测试环境

组件名 版本
CentOS CentOS Linux release 7.4.1708 (Core)
TiDB 5.1.3

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:

enable-tcp4-only: true     # 添加或者修改这一行配置为 true

b) 重新加载配置

tiup cluster reload stale_read_test -R tidb

c) 检查配置是否生效

select * from information_schema.cluster_config where TYPE=‘tidb’ and key =‘enable-tcp4-only’;

参数说明

enable-tcp4-only 从 v5.0 版本开始引入
控制是否只监听 TCP4。
默认值:false
当使用 LVS 为 TiDB 做负载均衡时,可开启此配置项。这是因为 LVS 的 TOA 模块可以通过 TCP4 协议从 TCP 头部信息中解析出客户端的真实 IP。

(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 的效果

dba@192.168.2.100:4000 : (none) > select * FROM information_schema.cluster_processlist\"G
*************************** 1. row ***************************
INSTANCE: 192.168.3.1:10080ID: 15USER: dbaHOST: 192.168.2.101:5394 #LVS DIPDB: NULLCOMMAND: QueryTIME: 0STATE: autocommitINFO: select * FROM information_schema.cluster_processlistDIGEST: b1e38e59fbbc3e2b35546db5c8053040db989a497ac6cd71ff8dd4394395701aMEM: 4DISK: 0
TxnStart: 01-19 11:25:30.423(430587964404006913)
1 row in set (0.00 sec)

开启 enable-tcp4-only 的效果
show processlist;

dba@192.168.2.100:4000 : (none) > select * FROM information_schema.cluster_processlist\"G
*************************** 1. row ***************************
INSTANCE: 192.168.3.1:10080ID: 190927USER: dbaHOST: 192.168.1.1:13557   #客户端真实IP DB: NULLCOMMAND: QueryTIME: 0STATE: autocommitINFO: select * FROM information_schema.cluster_processlistDIGEST: b1e38e59fbbc3e2b35546db5c8053040db989a497ac6cd71ff8dd4394395701aMEM: 0DISK: 0
TxnStart: 01-19 08:53:36.472(430585575236435969)
1 row in set (0.00 sec)

慢日志

# Time: 2022-01-19T09:04:18.429228693+08:00
# Txn_start_ts: 0
# User@Host: dba[dba] @ 192.168.1.1 [192.168.1.1] #客户端真实IP
# Conn_ID: 190927
# Query_time: 10.00093258
# Parse_time: 0.000098847
# Compile_time: 0.000132781
# Rewrite_time: 0.000073525
# Optimize_time: 0.00001867
# Wait_TS: 0.000006643
# Is_internal: false
# Digest: a0adeeb79b71315ac13a77f3f11162106b5ec7b48212cf17c20c754263ab9228
# Num_cop_tasks: 0
# Prepared: false
# Plan_from_cache: false
# Plan_from_binding: false
# Has_more_results: false
# KV_total: 0
# PD_total: 0.000004254
# Backoff_total: 0
# Write_sql_response_total: 0.000003211
# Succ: true
# Plan: tidb_decode_plan('gQHwVTAJM18zCTAJMQlzbGVlcCgxMCktPkNvbHVtbiMxCTEJdGltZToxMHMsIGxvb3BzOjIsIENvbmN1cnJlbmN5Ok9GRgkwIEJ5dGVzCU4vQQoxCTI1XzQJAVAQcm93czoZQxAuMDTCtRlHIAlOL0EJTi9BCg==')
# Plan_digest: a55eaee1d30304ad05500afbbfff1409ce22376e0f062c0d06ff34b8ed9c2b47
select sleep(10);

general log

[2022/01/19 11:04:42.863 +08:00] [INFO] [session.go:2796] [GENERAL_LOG] [conn=219317] [user=dba@192.168.1.1] [schemaVersion=1007] [txnStartTS=0] [forUpdateTS=0] [isReadConsistency=false] [current_db=db23] [txn_mode=PESSIMISTIC] [sql="select * from t1"]

从以上信息可以看到,无论是 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

TiDB 如何在 LVS FULL NAT 模式下显示客户端真实 IP相关推荐

  1. 如何在VMWare的NAT模式下使用traceroute(解析vmnat的行为)

    前面写过一篇< 为什么在VMWare的NAT模式下无法使用traceroute>,本文来破除这个结论,展示一种让你在VMWare的NAT模式下可以使用traceroute的方法. 可能很多 ...

  2. virtualBox使用nat模式下ssh连接

    virtualBox本地虚拟机通过ssh连接一般可通过桥接模式和Nat模式 桥接模式下,共享本地主机网卡,在同一个局域网之下,直接获取Ip地址就可以进行连接了. Nat模式下,获取的Ip与本地主机不是 ...

  3. 基于c语言256色转16色,在16色模式下显示256色及全彩色

    摘 要 该文描述了在vga16色图形模式下显示256色及全彩色图像的抖动算法,并给出了显示bitmap图像的c语言程序. 在编写有关图像显示的软件时,有时为了软件的兼容性和通用性,不得不采用vga标准 ...

  4. 配置lvs nat模式下real server服务器端lvsrs脚本

    因为lvs nat模式下,只有入站方向的流量经过lvs服务器,出站流量直接由Real server服务器响应,所以Real Server服务器必须做相应的配置才能响应客户数据包,即修改Real ser ...

  5. LVS (DR, NAT)模式应用

    OS:   Redhat AS4U4 内核:2.6.9-42 Server1: 192.168.1.91 (负载服务器) 虚拟服务IP: 192.168.1.99 Realserver: 192.16 ...

  6. kali-linux nat模式下无法联网问题

    出现kali-linux nat模式下无法联网问题可以做以下尝试: 键入ifconfig -a 查看网卡 ,是否存在 键入 leafpad /etc/network/interfaces 查看其中是否 ...

  7. ACT5.6 动手实验手册 如何在工作组模式下对客户端进行数据收集 如何在AD域环境下对...

    ACT5.6 动手实验手册 实验的目标 这个实验的目的是: · 了解如何部署ACT5.6 · 了解如何在工作组模式下对客户端进行数据收集 · 了解如何在AD域环境下对客户端进行数据收集 本次试验大约6 ...

  8. VMWare虚拟机NAT模式下static IP

    为什么80%的码农都做不了架构师?>>>    采用NAT模式后,发现guest的IP经常变化,网上找到的解决办法如下:  来源:http://my.oschina.net/aigu ...

  9. vmware中NAT模式下,虚拟机与主机能ping通 为什么虚拟机不能上网

    vmware中NAT模式下,虚拟机与主机能ping通 为什么虚拟机不能上网? 方案一: 1.把虚拟机的网络连接设置为桥接或NAT都可以的 2.把虚拟机和主机设置为同一网段 主机 网络邻居属性 3.双击 ...

最新文章

  1. ACMNO.48 01字串
  2. PHP二分法查找,MYSQL索引即为用了此查找
  3. so调用so 编译 android,android-5分钟入门-CMake方式使用JNI(.so调用篇)
  4. java cookbook 3_CookBook/Java核心/3-Java反射.md at master · zhgdbut/CookBook · GitHub
  5. dj鲜生-20-模版的抽离-base父模板的生产
  6. 数据结构学习笔记:利用栈实现进制转换
  7. java 魔数_Java 字节码结构解析
  8. Android 源码编译过程
  9. Java 求一段代码运行所需要的时间——模板方法设计模式
  10. Hbase权威指南(含目录,高清,免费)
  11. 产品体系建模工具软件
  12. BT601和BT709的区别最简洁的描述
  13. 微信发布2018年各年龄段用户使用数据报告
  14. x86 x64 x86_64 AMD64 区别
  15. 一位大牛对于写技术博客的一些建议
  16. 如何取悦自己或者增加自己幸福感的方式
  17. c语言五子棋毕业设计,基于c语言五子棋小游戏--本科生毕业设计.doc
  18. 7-1 房屋分拆 (25 分)(C语言版)
  19. JAVA实现分治法的合并排序及解析
  20. 计算机音乐丑八怪乐谱,薛之谦《丑八怪》五线乐谱

热门文章

  1. CSU 1726:你经历过绝望吗?两次! (BFS+优先队列)
  2. 计算机可以不需要显卡吗,显卡有什么用 电脑不装显卡影响大吗
  3. Mathcad tips_3D绘图
  4. 发布半年之后,QQ 物联做得到底怎么样了?
  5. Flink专题四:Flink DataStream 窗口介绍及使用
  6. Python easyOCR图像文本提取 初识
  7. GAMS系列分享14——综合能源系统——CHP机组运行区域
  8. 计算机主机是啥意思,pc是什么_pc是什么意思
  9. 【LeetCode】606.根据二叉树创建字符串
  10. h5 video标签属性及方法