Skip to main content

2 posts tagged with "高可用"

View All Tags

Notify script is not working on Keepalived v1.3.5

· 2 min read

在公司内网通过 Keepalived 的 VIP 机制及诊断脚本提供一些高可用服务及智能选择服务,但由于内网网络设备及环境复杂,导致在上面组建的 Overlay 网络内的 ARP 广播不通畅,在 Keepalived 主备切换切换后当前有效节点的 MAC 地址通知不到客户端,从而导致客户端不能连接到正确的服务节点,因此就想使用 Keepalived 的 notify scripts, 在 Keepalived 状态转变后在所有客户端执行一个脚本更新 MAC 地址。

脚本也简单,定义客户端列表直接 shell 上去设置 MAC 地址(节点间通过 ssh key 配置了自动登录):

#!/bin/sh

declare -a nodes=(
"192.168.126.8"
"192.168.126.9"
"192.168.126.10"
"192.168.126.11"
"192.168.126.12"
"192.168.126.13"
"192.168.126.14"
"192.168.126.15"
)

ip addr show eth0 | grep 192.168.126.99
foundVip=$?

for ip in "${nodes[@]}"; do
if [ $foundVip -eq 0 ]; then
MAC=`ip addr show eth0 | grep ff:ff:ff:ff:ff:ff | awk '{print $2}'`
ssh root@$ip arp --set 192.168.126.99 $MAC
fi
done

环境:CentOS 7.6, Kernel 4.20.5, Keepalived v1.3.5

按照 track_script 和 real_server 中定义 MISC_TASK 脚本的惯例用法, 把脚本放在了/usr/libexec/keepalived 目录下, 配置了 execute 权限, 单独测试脚本工作正常。在 vrrp_instance 中配置 notify 脚本路径及执行用户 root, 如下:

vrrp_instance VI_POSTGRESQL {
...
virtual_ipaddress {
192.168.126.99/24 dev eth0 label eth0:1
}
...
notify "/usr/libexec/keepalived/update_mac_for_vip.sh" root
}

配置完成后停止/启动脚本测试了多次, 都不能得到执行, Google 了半天, 有些资料提到 Keepalive 其中的一个 patch 把 notify 的配置方法改成了 array, 于是尝试按列表方式配置 notify scripts, 如下:

notify {

    "/usr/libexec/keepalived/update_mac_for_vip.sh" root

}

依然不奏效。

一个偶然的尝试把脚本从/usr/libexec/keepalived 路径移到了/etc/keepalived 目录下, 并更新 Keepalived 配置文件/etc/keepalived/keepalived.conf, 重启 Keepalived 后, notify 机制竟然工作正常了。

暂未探寻究竟,也未尝试其它目录,权且记录,以备后查。

CentOS 7配置LVS-集群

· 6 min read

LVS有三种工作模式:NAT, TUN, DR. DR 是三种工作模式中性能最高的,TUN 次之。

本文记录 LVS/TUN 和 LVS/DR 工作模式的配置过程。

环境:

  • 三台 CentOS 7 x64 虚拟机: CentOS Linux release 7.4.1708 (Core)
  • IP 地址分别为 192.168.1.11/24, 192.168.1.12/24, 192.168.1.13/24
  • 虚拟 IP 为 192.168.1.99, 网络结构为:

1. LVS/TUN - 隧道模式:

Director(192.168.1.11)上的配置:

为 tunl0 设备配置 VIP:

# ifconfig tunl0 192.168.1.99 broadcast 192.168.1.99 netmask 255.255.255.255 up

安装 ipvsadm 工具:

# yum install ipvsadm

用 ipvsadm 配置 LVS 转发器:

  • 清除配置表
  • 添加一个访问地址为 192.168.1.99:80 的 TCP 服务,并设置调度算法为轮叫(rr)
  • 为服务添加两个 Real Server 192.168.1.12 和 192.168.1.13, -i 参数标识工作模式为 TUN 模式
  • 最后清除 iptables,重新生成
# ipvsadm -C
# ipvsadm -A -t 192.168.1.99:80 -s rr
# ipvsadm -a -t 192.168.1.99:80 -r 192.168.1.12 -i
# ipvsadm -a -t 192.168.1.99:80 -r 192.168.1.13 -i
# iptables -F

配置完成后使用 ipvsadm -Ln 查看:

# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.99:80 rr
-> 192.168.1.12:80 Route 1 0 0
-> 192.168.1.13:80 Route 1 0 0

Real Server(192.168.1.12,192.168.1.13)上的配置:

  • 配置 VIP
  • 配置 Real Server 不响应 VIP 的 ARP 请求
  • 关闭数据包源地址检验
  • 最后清除 iptables,重新生成
# ifconfig tunl0 192.168.1.99 broadcast 192.168.1.99 netmask 255.255.255.255 up
# echo "1" > /proc/sys/net/ipv4/conf/tunl0/arp_ignore
# echo "2" > /proc/sys/net/ipv4/conf/tunl0/arp_announce
# echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
# echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
# echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
# iptables -F
  • 在 Real Server 上启动一个简单的 web 服务。两种方式:

1. 在 192.168.1.12 和 192.168.1.13 上直接通过 rpm 包安装 nginx, 在 192.168.1.12 和 192.168.1.13 上配置两个 web server 显示两个可识别的 web 页面:

# rpm -Uvh http://nginx.org/packages/centos/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm

2. 通过 docker 使用默认 NAT 网络启动一个 nginx 实例,在 192.168.1.12 和 192.168.1.13 上配置两个 nginx 实例显示两个可识别的 web 页面。通过 docker 启动 web 服务时要在 Real Server 上开启 ip_forward, 因为 docker run 默认使用的 NAT 网络依赖 ip_forward:

# docker run --name nginx -d -p 80:80 -v /etc/nginx/:/etc/nginx/ -v /var/www/html/:/usr/share/nginx/html/ -v /var/log/nginx/:/var/log/nginx/ nginx:1.13.12
# echo "1" > /proc/sys/net/ipv4/ip_forward

最后执行 iptables -F 确保所有通信不被防火墙阻挡。

LVS/TUN 模式配置完成,通过在另一个 linux 虚拟机中通过 curl 访问 192.168.1.99, 可以看到 http 请求会以轮询的方式被分别转发到的 192.168.1.12 和 192.168.1.13:

在浏览器中访问时由于浏览器缓存可能没那么明显。

2. LVS/DR 模式:

Director(192.168.1.11)上的配置:

# ifconfig enp0s3:0 192.168.1.99 netmask 255.255.255.255 up
# ipvsadm -C
# ipvsadm -A -t 192.168.1.99:80 -s rr
# ipvsadm -a -t 192.168.1.99:80 -r 192.168.1.12 -g
# ipvsadm -a -t 192.168.1.99:80 -r 192.168.1.13 -g
# iptables -F

DR 模式不使用隧道设备 tunl0, 而是把虚拟 IP 配置本地网卡别名 enp0s3:0 上,添加 Real Server 时指定模式为-g。也有人说把虚拟 IP 配置在 lookback 别名上,实测配置在 loopback 好像对 real server 的轮询切换并不那么及时。

Real Server(192.168.1.12,192.168.1.13)上的配置:

# ifconfig enp0s3:0 192.168.1.99 netmask 255.255.255.255 up
# echo "1" > /proc/sys/net/ipv4/conf/enp0s3/arp_ignore
# echo "2" > /proc/sys/net/ipv4/conf/enp0s3/arp_announce
# echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
# echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
# iptables -F

如需网络内核参数永久生效请修改/etc/sysctl.conf (最好这样做):

# cat <<EOF >> /etc/sysctl.conf
net.ipv4.conf.enp0s3.arp_ignore = 1
net.ipv4.conf.enp0s3.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
EOF
# sysctl -p

Real Server 中同样要配置虚拟 IP,并设置不响应对 192.168.1.99 的 arp 查询,Web Server 的配置与 TUN 模式相同。

配置完成。

Tips:

如果在 Director 上也有 web 服务,还可以把 Director(192.168.1.11)也作为 Real Server 使用。


参考信息:

关于 arp_ignore, arp_announce, rp_filter 参数的作用,请参见:

上述配置在 firewalld 为运行状态并且 SELinux 为 Enforcing 状态时测试通过。

所有的网络参数配置均为临时立即生效,若要长久生效,请修改/etc/sysctl.conf 文件,并执行 sysctl -p

# vi /etc/sysctl.conf
# sysctl -p

ipvsadm 配置的内容在系统重启后也会丢失,可能通过 ipvsadm -Sn 保存到文件,然后可通过 ipvsadm --restore 加载。

注意 ipvsadm 的-S(--save)一起要跟上 n 参数,否则会保存错误的 IP 地址。

[root@centos01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.99:80 rr
-> 192.168.1.12:80 Route 1 0 7
-> 192.168.1.13:80 Route 1 0 4
[root@centos01 ~]# ipvsadm -Sn > ipvsadm.conf
[root@centos01 ~]# cat ipvsadm.conf
-A -t 192.168.1.99:80 -s rr
-a -t 192.168.1.99:80 -r 192.168.1.12:80 -g -w 1
-a -t 192.168.1.99:80 -r 192.168.1.13:80 -g -w 1
[root@centos01 ~]# ipvsadm -C
[root@centos01 ~]# cat ipvsadm.conf | ipvsadm --restore
[root@centos01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.99:80 rr
-> 192.168.1.12:80 Route 1 0 4
-> 192.168.1.13:80 Route 1 0 4

如果遇到转发故障可通过 tcpdump 进行诊断。如:监听接口 enp0s3,抓取 host 为 192.168.1.99 并且目的端口为 80,或 host 为 192.168.1.12 并且源端口为 80 的数据包:

# tcpdump -i enp0s3 '((dst port 80) and (host 192.168.1.99)) or ((src port 80) and (host 192.168.1.12))'

关于 LVS 的调度算法请参见:LVS 集群的负载调度

ClustrMaps