在VPC中,为一台ECS绑定EIP,并在该ECS上搭建代理软件,可以将该ECS实例建设为一个SNAT网关,让同VPC内其他实例将该实例作为公网网关进行公网访问。
然而,这种方式搭建的SNAT网关是个单点,可用性较差。我们可以使用keepalived和HaVip来搭建一个具备主备切换能力的高可用SNAT网关。
## 环境
1. 准备两个EIP。
2. 准备四台ECS实例,在一个VPC的同一个VSwitch下。
* 192.168.1.201 (绑定了EIP 123.56.16.103):当做跳板机使用,SSH到这台机器上以后,再SSH私网IP跳转到其他机器。
* 192.168.1.202:SNAT双机中的主实例,一会儿会绑在HaVip上。
* 192.168.1.203:SNAT双机中的备实例,一会儿会绑在HaVip上。
* 192.168.1.204:当作需要上网的实例,用它来测试SNAT的效果。
3. 准备一个HaVip:
私网IP:192.168.1.200
绑定了EIP:123.56.16.108
绑定了两个实例:192.168.1.202、192.168.1.203;
## 搭建与配置
### Keepalived的安装:
在要当做SNAT服务器的两台ECS实例上,执行以下keepalived安装流程:
#### 下载:
[root@iZ250sept0mZ ~]# wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
由于目前这台机器目前不能直接连上公网,所以可以在跳板机上进行wget,然后scp到这两台机器上;
#### 安装:
```bash
[root@iZ250sept0mZ ~]# tar -zxf keepalived-1.2.19.tar.gz
[root@iZ250sept0mZ ~]# cd keepalived-1.2.19
[root@iZ250sept0mZ keepalived-1.2.19]# ./configure
[root@iZ250sept0mZ keepalived-1.2.19]# make && make install
#### 修改配置文件路径:
```bash
[root@iZ250sept0mZ keepalived-1.2.19]# cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
[root@iZ250sept0mZ keepalived-1.2.19]# cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
[root@iZ250sept0mZ keepalived-1.2.19]# mkdir /etc/keepalived
[root@iZ250sept0mZ keepalived-1.2.19]# cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
[root@iZ250sept0mZ keepalived-1.2.19]# cp /usr/local/sbin/keepalived /usr/sbin/
#### 将keepalived设置为服务,开机启动:
```bash
[root@iZ250sept0mZ keepalived-1.2.19]# vi /etc/rc.local
### 自定义路由配置:
添加一条自定义路由,目的CIDR为0.0.0.0/0 , 下一跳指向HaVip对象
添加完成后的效果如下:
### 开启内核的IP转发选项:
在两台SNAT服务器ECS实例上都进行如下修改:
运行:`sysctl -w net.ipv4.ip_forward=1`
为了保证实例重启后依然是开启这个选项的,需要对/etc/sysctl.conf 这个配置文件进行修改,将net.ipv4.ip_forward的值改为1,见下图:
### SNAT配置
在两台当做SNAT服务器的ECS实例上,准备两个shell脚本:
* 脚本一: 用于主备切换时让新的master机自动开启IP转发、加载SNAT规则,实现SNAT转发:
* 脚本二: 用于主机切换成备机时或者主机keepalived出错时去除SNAT转发规则(不去除的话,上网会有问题);
P.S. 如果备机带着这几条SNAT规则工作,会导致主机无法直接上网;
两个脚本的内容如下:
脚本一:/etc/keepalived/scripts/ha_vip_start.sh
```bash
#!/bin/bash
echo "start; `date`" >> /tmp/log
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -d 100.64.0.0/10 -j RETURN
iptables -t nat -A POSTROUTING -d 10.0.0.0/8 -j RETURN
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 ! -p vrrp -j SNAT --to-source 192.168.1.200
需要注意的地方:
1. 红字地方尤其需要注意,应该是HaVip的私网IP。
2. 需要注意几条规则的顺序,要按照上文给出的顺序才行。
3. 如果您的VPC的CIDR是10.0.0.0/8网段,那么需要略过第二条规则不加。
脚本二:/etc/keepalived/scripts/ha_vip_stop.sh
```bash
#!/bin/bash
echo "stop; `date`" >> /tmp/log
iptables -t nat -F
### Keepalived配置
配置文件位置:/etc/keepalived/keepalived.conf
Master实例 (例子中的192.168.1.202)的完整配置文件:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from zhao.wang_havip@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200 dev eth0 label eth0:havip
}
notify_master /etc/keepalived/scripts/ha_vip_start.sh
notify_backup /etc/keepalived/scripts/ha_vip_stop.sh
notify_fault /etc/keepalived/scripts/ha_vip_stop.sh
notify_stop /etc/keepalived/scripts/ha_vip_stop.sh
unicast_src_ip 192.168.1.202
unicast_peer {
192.168.1.203
}
}
注意:配置文件中,
* `192.168.1.202`和`192.168.1.203`应该换成你的两台实例的私网IP; 注意两个IP分别的位置,不要写反了。
* `192.168.1.200`应该是你的HaVip的私网IP地址。
backup 实例(例子中的192.168.1.203)的完整配置文件:
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from zhao.wang_havip@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.200 dev eth0 label eth0:havip
}
notify_master /etc/keepalived/scripts/ha_vip_start.sh
notify_backup /etc/keepalived/scripts/ha_vip_stop.sh
notify_fault /etc/keepalived/scripts/ha_vip_stop.sh
notify_stop /etc/keepalived/scripts/ha_vip_stop.sh
unicast_src_ip 192.168.1.203
unicast_peer {
192.168.1.202
}
}
注意:同样需要注意其中的私网IP,换成你的两台实例的私网IP;注意对应位置,不要写反了。
## 启动服务、验证SNAT效果
### 在202上启动keepalived
```bash
[root@iZ25eb8j6mqZ ~]# service keepalived start
观察log,进入master状态:
查看网卡配置,出现了192.168.1.200的ip;
查看iptables规则,出现了SNAT相关规则;
### 在204上验证上网效果
ping公网网址可以通;traceroute可以看到第一跳为192.168.1.202
### 在203上启动keepalived
观察log,进入backup状态:
查看网卡信息,发现并没有出现192.168.1.200,因为此时202是master,203还只是个备胎:
### 在204上验证上网效果
可以看到,和刚才验证的效果一样
### 将202的keepalived停掉
[root@iZ25eb8j6mqZ ~]# service keepalived stop
可以观察到:
1. 202的网卡上不再有192.168.1.200
2. 203的keepalived log显示,进入master状态
3. 203 的网卡上出现192.168.1.200
### 在204上验证上网效果
可以看到,依然可以ping通,traceroute变成了第一跳为203。说明,此时203成为了master,接管了vip。
### 将202的keepalived重新启动
观察到:
1. 203回到backup状态,并移除192.158.1.200的ip
2. 202进入master状态,并接管vip
### 在204上验证上网效果
可以看到,依然可以ping通,traceroute变回第一跳为202
上面的主备迁移过程,您也可以停机/系统重启的方式模拟宕机,来观察vip的切换。