前置条件
DPIP配置
通过dpip命令检查对应网卡是否已存在测试iP及路由。
本文以100.96.122.212为测试SIP为例。
# 检查网卡IP
/usr/local/dpvs/bin/dpip addr show
# 将SIP添加至dpdk0网卡上
# 正常情况下,通过keepalived配置文件启动后,会自动调用dpip添加至网卡,无需手动添加
/usr/local/dpvs/bin/dpip addr add 100.96.122.212 dev dpdk0
添加sip的同时,也会自动生成对应路由
# 查看路由
/usr/local/dpvs/bin/dpip route show
>>>
inet 100.96.122.212/32 via 0.0.0.0 src 0.0.0.0 dev dpdk0 mtu 1500 tos 0
scope host metric 0 proto auto
测试服务端说明
本次服务端为Nginx,通过内置变量来响应客户端请求信息。
参考配置
server {
listen 80;
server_name test.nestealin.com;
charset utf-8;
access_log logs/test.nestealin.com.access.main.log main;
error_log logs/test.nestealin.com.error.log error;
location / {
add_header Content-Type application/json ;
return 200 '{"remote_addr":"$remote_addr","remote_port":"$remote_port","clientRealIp":"$clientRealIp","time_local":"$time_local"}';
}
}
最佳实践
1. 添加SIP(Service iP / Service-Address)
如下参数解读: rr 模式,支持 synproxy 的 SIP 100.96.122.212 监听 80 端口
# 支持synproxy的rr模式
/usr/local/dpvs/bin/ipvsadm -A -t 100.96.122.212:80 -s rr -j enable
# wrr模式
# 支持synproxy的rr模式,不支持synproxy
/usr/local/dpvs/bin/ipvsadm -A -t 100.96.122.212:80 -s wrr
- 注意: SIP监听端口必须与RS端口保持一致,无法差异映射。
- synproxy模式管理:
- 参数:
-j
|--synproxy
- FLAG: enable | disable ( default: disable )
- 参数:
2. 添加RS(Real Server)
# 监听80端口,权重20
/usr/local/dpvs/bin/ipvsadm -a -t 100.96.122.212:80 -r 192.168.7.27:80 -w 20 -b
# 监听443端口,权重10
/usr/local/dpvs/bin/ipvsadm -a -t 100.96.122.212:443 -r 192.168.10.2:443 -w 10 -b
- FULLNAT模式管理:
- 参数:
-b
|--fullnat
- 参数:
3. 添加LIP(Local iP/Local-Address)
即SNAT-iP,用于向RS转发时用的ip。
注意,LIP需要与RS在同一通信子网中,否则会造成转发失败。
由于 RS 的 CIDR 为 192.168.7.0/24 ,所以本次实验采用统一子网iP作为LiP。
# 语法
ipvsadm -P -t service-address:port -z local-address:port
# 例如
/usr/local/dpvs/bin/ipvsadm -P -t 100.96.122.212:80 -z 192.168.7.233 -F dpdk0
/usr/local/dpvs/bin/ipvsadm -P -t 100.96.122.212:80 -z 192.168.7.234 -F dpdk0
# 确认当前LIP
/usr/local/dpvs/bin/ipvsadm -G -t 100.96.122.212:80
VIP:VPORT TOTAL SNAT_IP CONFLICTS CONNS
100.96.122.212:80 2
192.168.7.233 0 0
192.168.7.234 0 0
以上,添加了两个转发IP。
4. 测试验证
本次实验采取静态路由方式验证,线上可考虑ospf、bgp等方式宣告SIP。
登陆客户端机器,配置静态路由,并验证请求。
# 添加静态路由
route add -host 100.96.122.210 gw 192.168.7.82 dev eth0
# 验证请求
# curl 100.96.122.212
{"remote_addr":"192.168.7.233","remote_port":"1037","clientRealIp":"192.168.7.233","time_local":"25/Nov/2022:22:40:42 +0800"}
# curl 100.96.122.212
{"remote_addr":"192.168.7.234","remote_port":"1037","clientRealIp":"192.168.7.234","time_local":"25/Nov/2022:22:40:45 +0800"}
# curl 100.96.122.212
{"remote_addr":"192.168.7.233","remote_port":"1034","clientRealIp":"192.168.7.233","time_local":"25/Nov/2022:22:40:47 +0800"}
可以看出,分别使用了192.168.7.233、192.168.7.234两个LiP进行转发,请求Nginx。
如果需要获取源客户端IP信息,则需要在Nginx侧安装并启用TOA插件。
ipvsadm-常用命令说明
连接管理
查看SIP连接、转发状态
/usr/local/dpvs/bin/ipvsadm -Ln
>>>
IP Virtual Server version 0.0.0 (size=0)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 100.96.122.210:80 rr synproxy
-> 192.168.7.27:80 FullNat 100 0 0
TCP 100.96.122.212:80 rr synproxy
-> 192.168.7.27:80 FullNat 10 0 0
TCP 192.168.7.182:80 rr synproxy
-> 192.168.7.81:80 FullNat 100 0 0
查看当前所有连接状态
/usr/local/dpvs/bin/ipvsadm -l -c -n
>>>
[1]tcp 7s TIME_WAIT 192.168.7.95:55500 100.96.122.212:80 192.168.7.233:1048 192.168.7.27:80
[1]tcp 7s TIME_WAIT 192.168.7.95:55492 100.96.122.212:80 192.168.7.233:1040 192.168.7.27:80
[1]tcp 7s TIME_WAIT 192.168.7.95:55496 100.96.122.212:80 192.168.7.233:1044 192.168.7.27:80
[2]tcp 7s TIME_WAIT 192.168.7.95:55494 100.96.122.212:80 192.168.7.233:1049 192.168.7.27:80
[2]tcp 7s TIME_WAIT 192.168.7.95:55498 100.96.122.212:80 192.168.7.233:1053 192.168.7.27:80
查看包吞吐速率
/usr/local/dpvs/bin/ipvsadm -l --rate
>>>
IP Virtual Server version 0.0.0 (size=0)
Prot LocalAddress:Port CPS InPPS OutPPS InBPS OutBPS
-> RemoteAddress:Port
TCP 100.96.122.210:http 0 0 0 0 0
-> 192.168.7.27:http 0 0 0 0 0
TCP 100.96.122.212:http 0 0 0 0 0
-> 192.168.7.27:http 0 0 0 0 0
TCP 192.168.7.182:http 0 0 0 0 0
-> homelab_inspur_node01:http 0 0 0 0 0
SIP管理
添加SIP
# 语法
/usr/local/dpvs/bin/ipvsadm -A -t service-address(SIP):port [-s scheduler] [-j eanble/disable] [-p [timeout]] [-M netmask] [--pe persistence_engine]
# 更多参数详见 -h 输出
Options:
--scheduler -s scheduler one of rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,
the default scheduler is wlc.
...
例子
# 以rr轮询方式,添加SIP,并开启synproxy
/usr/local/dpvs/bin/ipvsadm -A -t 100.96.122.212:80 -s rr -j enable
删除SIP
/usr/local/dpvs/bin/ipvsadm -D -t|u|f service-address:port
例子
/usr/local/dpvs/bin/ipvsadm -D -t 100.96.122.212:80
RS管理
添加后端/RS
# 语法
/usr/local/dpvs/bin/ipvsadm -a|e -t|u|q|f service-address -r server-address [options]
# 更多参数详见 -h 输出
Options:
--gatewaying -g gatewaying (direct routing) (default)
--ipip -i ipip encapsulation (tunneling)
--fullnat -b fullnat mode
--snat -J SNAT mode
--masquerading -m masquerading (NAT)
...
例子
# 为100.96.122.212:80这组SIP添加192.168.7.27:80
# 设置权重为10并以fullnat方式转发
/usr/local/dpvs/bin/ipvsadm -a -t 100.96.122.212:80 -r 192.168.7.27:80 -w 10 -b
调整后端权重
# 语法
ipvsadm -e -t|u|f service-address(SIP):port -r server-address(RS):port [options]
# 更多参数详见 -h 输出
Options:
--tcp-service -t service-address service-address is host[:port]
--udp-service -u service-address service-address is host[:port]
--fwmark-service -f fwmark fwmark is an integer greater than zero
--weight -w weight capacity of real server
...
例子
调整 1.1.1.4:443 入口的 192.168.10.2:443 后端权重为 10
/usr/local/dpvs/bin/ipvsadm -e -t 1.1.1.4:443 -r 192.168.10.2:443 -w 10
删除后端
/usr/local/dpvs/bin/ipvsadm -d -t 1.1.1.4:443 -r 192.168.10.2:443
LIP管理
添加LIP
# 语法
ipvsadm -P -t service-address:port -z local-address -F ifname
例子
/usr/local/dpvs/bin/ipvsadm -P -t 100.96.122.212:80 -z 192.168.7.233 -F dpdk0
查看SIP对应的LIP
# 语法
ipvsadm -G -t service-address:port
例子
/usr/local/dpvs/bin/ipvsadm -G -t 100.96.122.212:80
删除指定SIP的LIP
# 语法
ipvsadm -Q -t service-address:port -z local-address -F ifname
例子
/usr/local/dpvs/bin/ipvsadm -Q -t 100.96.122.212:80 -z 192.168.7.234 -F dpdk0
可能遇到的问题
添加VIP后直接请求造成如下报错
来源于dpvs日志。
IPVS: dp_vs_synproxy_ack_rcv: ip_vs_schedule failed
IPVS: dp_vs_synproxy_ack_rcv: syn_cookie check failed seq=2834256631
原因是没有配置LIP
# 例如
/usr/local/dpvs/bin/ipvsadm -P -t 100.96.122.212:80 -z 192.168.7.234 -F dpdk0
添加后再次请求即可。
参考文档
Fullnat系列(二):如何使用fullnat ( 需注意,与真实dpvs下的真实配置会有略微出入,仅供参考 )