dsnat簡介
dsnat(Dynamic Source Network Address Translation) 是一個基于lvs的模塊,在taobao開源的FNAT基礎(chǔ)上開發(fā),dsnat位于網(wǎng)絡(luò)的網(wǎng)關(guān)位置,內(nèi)網(wǎng)訪問外網(wǎng)時,會將內(nèi)網(wǎng)地址改成公網(wǎng)地址池中的ip,輪詢選擇
目前該模塊只支持ipv4下的TCP,UDP協(xié)議, ICMP暫時還不支持
dsnat_tools包含ipvsadm和keepalived這2個工具,在官方源碼的基礎(chǔ)上修改添加了對dsnat的支持
- ipvsadm是對lvs進行配置的用戶空間工具,ipvsadm->lvs類似于iptables->netfilter
- keepalived是對lvs集群的一個自動化配置工具(以服務(wù)形式常駐內(nèi)存),可針對rs自動摘除和添加rs到vs中;并帶有HA功能,提供熱備容災(zāi)
安裝
安裝二進制包(xiaomi內(nèi)網(wǎng)可訪問)
- 內(nèi)核
rpm -ivh http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/kernel-firmware-2.6.32-279.23.1.mi4.el6.x86_64.rpm
rpm -ivh http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/kernel-2.6.32-279.23.1.mi4.el6.x86_64.rpm
#開發(fā)包
rpm -ivh http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/kernel-devel-2.6.32-279.23.1.mi4.el6.x86_64.rpm
rpm -ivh http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/kernel-headers-2.6.32-279.23.1.mi4.el6.x86_64.rpm
- ipvsadm/keepalive
#如發(fā)現(xiàn)/usr/local目錄下的ipvsadm/keepalived,刪掉
wget http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/tools/ipvsadm -O /sbin/ipvsadm
wget http://xiaomi-kernel.xae.xiaomi.com/mi4-dsnat/tools/keepalived -O /sbin/keepalived
源碼安裝
- 下載 redhat 6.3的內(nèi)核
wget ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS/kernel-2.6.32-279.23.1.el6.src.rpm
- 準(zhǔn)備代碼
cat > ~/.rpmmacros << 'EOF'
%_topdir ~/rpms
%_tmppath ~/rpms/tmp
%_sourcedir ~/rpms/SOURCES
%_specdir ~/rpms/SPECS
%_srcrpmdir ~/rpms/SRPMS
%_rpmdir ~/rpms/RPMS
%_builddir ~/rpms/BUILD
EOF
cd
mkdir -p ~/rpms/{tmp,BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
rpm -ivh kernel-2.6.32-279.23.1.el6.src.rpm
cd ~/rpms/SPECS
rpmbuild -bp kernel.spec
- 打補丁
cd ~/rpms/BUILD/
cd kernel-2.6.32-220.23.1.el6/linux-2.6.32-279.23.1.el6.x86_64/
wget https://raw.github.com/xiaomi-sa/dsnat/master/dsnat-kernel-2.6.32-279.23.1.el6/dsnat-2.6.32-279.23.1.el6.xiaomi.noconfig.patch
patch -p1 < dsnat-2.6.32-279.23.1.el6.xiaomi.noconfig.patch
- 編譯安裝
make -j16
make modules_install
make install
##重啟使用新內(nèi)核
init 6
LVS TOOL 安裝
標(biāo)準(zhǔn)的ipvsadm和keepalive將無法正常使用,
需要編譯安裝ipvsadm和keepalived,在dsnat_tools下載工具源碼
git clone git@github.com:xiaomi-sa/dsnat.git
cd dsnat/dsnat_tools/ipvsadm
make && make install
cd ../keepalived
make && make install
配置用例
將lvs放在網(wǎng)關(guān)的位置,假設(shè)網(wǎng)絡(luò)環(huán)境是這樣的
client eth0 1.1.1.1 255.255.0.0 (cip)
lvs eth0 1.1.100.1 255.255.0.0 (gw ip)
lvs eth1 1.2.100.1-4 255.255.0.0 (lip)
rs eth1 1.2.1.4 255.255.0.0 (rip)
網(wǎng)絡(luò)環(huán)境是(模擬一下)
- client在內(nèi)網(wǎng)
- realserver在外網(wǎng)
- 內(nèi)網(wǎng)到外網(wǎng)的路由指向lvs
- route add -net 1.2.0.0 netmask 255.255.0.0 gw 1.1.100.1(用默認(rèn)路由也可以)
- 外網(wǎng)服務(wù)器可以訪問lvs的lip

Alt text
網(wǎng)關(guān)的配置
##寫入開機啟動腳本
# echo >> /etc/rc.local << 'EOF'
#打開轉(zhuǎn)發(fā)設(shè)置
echo 1 > /proc/sys/net/ipv4/ip_forward
#由于gro/lro功能會影響轉(zhuǎn)發(fā)后數(shù)據(jù)包大小,超過MTU后會被丟棄重發(fā),系統(tǒng)默認(rèn)是開啟的
#關(guān)掉gw ip所在的網(wǎng)卡gro/lro
ethtool -K eth0 gro off
ethtool -K eth0 lro off
#綁定網(wǎng)卡中斷,讓中斷在多核cpu上輪訓(xùn),效果很贊,同樣是gw ip所在的網(wǎng)卡
set_irq_affinity.sh eth0
EOF
##關(guān)閉irqbalance
# service irqbalance stop
# chkconfig --level 2345 irqbalance off
## 綁定local address
# echo >> /etc/rc.local << 'EOF'
ip addr add 1.2.100.1/16 dev eth1
ip addr add 1.2.100.2/16 dev eth1
ip addr add 1.2.100.3/16 dev eth1
ip addr add 1.2.100.4/16 dev eth1
EOF
zone 說明
- zone是有序的
- zone是local address的容器
- 源地址會從第一個網(wǎng)段開始,依次檢查到最后一個,一旦找到相匹配的網(wǎng)段即終止檢查
- 網(wǎng)段內(nèi)如果沒有l(wèi)ocal address
- 或者local address中的ip上的所有端口都被占用
- 或者沒有匹配到任何網(wǎng)段lvs將不會做任何處理(可視為丟棄)
通過ipvsadm配置lvs規(guī)則
如果執(zhí)行報錯,請核對一下使用的內(nèi)核補丁是否生效,ipvsadm是否為dsnat_tools編譯安裝版本
#打開添加一個0/0的虛擬服務(wù),開啟dsnat,讓所有的內(nèi)網(wǎng)請求都能命中該服務(wù)
ipvsadm –A –t 0.0.0.0:0 –s rr
#添加一個1.1.0.0/16的網(wǎng)段,用來做源地址匹配(client的ip是1.1.1.1/16)
ipvsadm -K --zone 1.1.0.0/16
#為1.0.0.0/16的zone添加local address
ipvsadm -P --zone 1.1.0.0/16 -z 1.2.100.1
ipvsadm -P --zone 1.1.0.0/16 -z 1.2.100.2
#再添加一個缺省的網(wǎng)段0/0
ipvsadm -K --zone 0.0.0.0/0
#為缺省網(wǎng)段添加local address
ipvsadm -P --zone 0.0.0.0/0 -z 1.2.100.3
...
#查看vs
ipvsadm -ln
#查看公網(wǎng)ip地址池
ipvsadm -G
通過keepalive配置lvs規(guī)則
如果執(zhí)行報錯,請核對一下使用的內(nèi)核補丁是否生效,keepalive是否為dsnat_tools編譯安裝版本,
keepalive需要2臺機器了,這里給出一臺的配置
- 啟動:service keepalived start
- 更新:service keepalived reload
- 停止:service keepalived stop
## /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_DEVEL
}
##這是lvs的配置,寫好公網(wǎng)ip地址池的ip
local_address_group laddr_g1 {
1.2.100.1
1.2.100.2
}
local_address_group laddr_g2 {
1.2.100.3
}
zone 1.1.0.0 16 {
laddr_group_name laddr_g1
}
zone 0.0.0.0 0.0.0.0 {
laddr_group_name laddr_g2
}
##這是High Availability部分的配置,會根據(jù)lvs的狀況,讓virtual_ipaddress在合適的機器上浮動
vrrp_sync_group G1 {
group {
VI_1
VI_2
}
}
##配置eth0浮動ip
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type pass
auth_pass 1111
}
virtual_ipaddress {
1.1.100.1
}
}
#配置eth1浮動ip
vrrp_instance VI_2 {
state master
interface eth1
virtual_router_id 53
priority 100
advert_int 1
authentication {
auth_type pass
auth_pass 1111
}
virtual_ipaddress {
1.2.100.1/16
1.2.100.2/16
}
}
##配置lvs,添加一個0/0的虛擬服務(wù),開啟dsnat,讓所有的內(nèi)網(wǎng)請求都能命中該服務(wù)
virtual_server 0.0.0.0 0 {
delay_loop 6
lb_algo rr
lb_kind FNAT
protocol TCP
laddr_group_name laddr_g1
}