( Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu )
Keepalived配置的核心IP地址主要是:虚拟IP(VIP)、本地源IP(SrclP)、其它主机目的IP(DestIP)。
就这三个配置项做一下配置研究。
一、Keepalived简介
Keepalived是一款基于VRRP(虚拟路由冗余协议) 实现的高可用软件,核心功能是为服务器集群提供“故障自动切换”能力,避免单点故障导致服务中断。它通过在多台服务器(通常称为“节点”)间协商,选举出一台“主节点(Master)”对外提供服务,其余为“备节点(Backup)”;当主节点故障时,备节点会自动接管服务,整个过程无需人工干预,常见于Web服务、数据库、负载均衡(如Nginx、HAProxy)等场景的高可用部署。
二、Keepalived核心IP配置与影响
Keepalived的IP配置是实现高可用的关键,主要包括虚拟IP(VIP)、源IP(Src IP) 和目的IP(Dest IP),三者配置不同会直接影响服务的可用性、路由路径和安全性。
- 虚拟IP(VIP)配置
虚拟IP是Keepalived对外提供服务的“统一入口”,主节点会占用VIP并响应外部请求,备节点仅在主节点故障时接管VIP。
配置示例(主节点)
vrrp_instance VI_1 {
state MASTER # 节点角色:MASTER/Backup
interface eth0 # 绑定VIP的网卡
virtual_router_id 51# 虚拟路由ID(同一VRRP实例的节点需一致)
priority 100 # 优先级(MASTER需高于Backup,如Backup设为90)
advert_int 1 # VRRP报文发送间隔(秒)
# 虚拟IP配置(可配置多个)
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:0 # VIP及网卡标签
}
}
配置影响
• 服务可用性:VIP是外部访问的唯一入口,若配置错误(如网卡不匹配、子网掩码错误),会导致外部无法访问服务。
• 地址冲突:同一网络内,VIP不能与其他服务器的物理IP重复,否则会触发ARP地址冲突,导致服务中断。
• 切换效率:当主节点故障时,备节点通过VRRP协商接管VIP,切换时间通常在1-3秒(由advert_int和优先级决定),advert_int越小,切换越快,但网络开销越大。
- 源IP(Src IP)配置
源IP是Keepalived节点发送VRRP报文或服务请求时,使用的“本地IP”(默认使用节点的物理IP),可通过配置指定特定IP作为源IP,常用于多网卡、多网段场景。
配置示例
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
# 指定VRRP报文的源IP(默认使用interface绑定的物理IP)
smtp_server 192.168.1.2 # (扩展)邮件通知的源IP,非VRRP核心,但原理类似
src_ip 192.168.1.5 # 明确指定源IP(部分场景需结合iptables)
virtual_ipaddress {
192.168.1.100/24
}
}
配置影响
• 路由识别:在多网段环境中,指定源IP可确保VRRP报文或服务请求从正确的网段发出,避免路由丢失(如跨网段备节点无法接收主节点的VRRP报文)。
• 权限控制:若后端服务(如数据库)仅允许特定IP访问,配置源IP可确保服务请求的源地址符合权限规则,避免被拒绝。
• 报文合法性:部分网络设备(如防火墙)会校验报文源IP与网段的一致性,错误的源IP会导致报文被拦截。
- 目的IP(Dest IP)配置
目的IP是Keepalived发送VRRP报文或服务请求的“目标IP”,VRRP协议默认使用组播IP(224.0.0.18) 发送协商报文,也可通过配置指定单播目的IP(适用于不支持组播的网络)。
配置示例(单播模式)
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
# 单播模式:指定备节点的物理IP作为目的IP(替代默认组播)
unicast_peer {
192.168.1.6 # 备节点1的IP
192.168.1.7 # 备节点2的IP(多备节点场景)
}
virtual_ipaddress {
192.168.1.100/24
}
}
配置影响
• 网络兼容性:组播模式依赖网络设备支持组播(如交换机需开启IGMP Snooping),若网络不支持组播,需配置单播目的IP,否则节点间无法协商。
• 安全性:组播报文会被同一网络内所有节点接收(仅VRRP实例ID匹配的节点处理),单播模式仅向指定备节点发送报文,减少网络广播风暴和信息泄露风险。
• 协商效率:单播模式下,主节点仅与指定备节点通信,协商速度比组播更快,尤其在多节点集群中优势明显。
三、核心IP配置的代码实现(基于Keepalived 2.2.7)
Keepalived的核心代码集中在vrrp/目录下,涉及IP配置的核心逻辑包括VRRP报文处理、VIP管理和IP路由控制,以下为关键代码模块的解析。
- 虚拟IP(VIP)的添加与删除
VIP的管理由vrrp_ipaddress.c实现,主节点选举成功后,通过ipaddr_add()函数添加VIP到指定网卡;主节点故障时,备节点接管后执行相同操作,原主节点恢复时则通过ipaddr_del()删除VIP。
关键代码片段(ipaddr_add函数核心逻辑)
#include "vrrp_ipaddress.h"
/* 添加VIP到网卡 */
int ipaddr_add(struct ipaddr *ip, const char *ifname) {
struct sockaddr_in *sin;
int sockfd, ret;
// 1. 创建RAW socket(用于发送IP层报文):
if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket");
return -1;
}
// 2. 配置VIP地址结构(IP+子网掩码)
sin = (struct sockaddr_in *)&ip->addr;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = inet_addr(ip->ip); // VIP地址(如192.168.1.100)
sin->sin_port = 0;
// 3. 绑定VIP到指定网卡(通过SIOCSIFADDR ioctl命令)
ret = ioctl(sockfd, SIOCSIFADDR, ifname); // SIOCSIFADDR:设置网卡IP
if (ret < 0) {
perror("ioctl(SIOCSIFADDR)");
close(sockfd);
return -1;
}
// 4. 发送ARP广播,告知网络内其他设备“VIP已绑定到当前网卡”
arp_send_gratuitous(ip->ip, ifname);
close(sockfd);
return 0;
}
代码逻辑说明
• RAW socket:使用IPPROTO_RAW创建的socket可直接操作IP层,用于发送VIP配置的控制报文。
• ioctl命令:通过SIOCSIFADDR(设置网卡IP)和SIOCSIFNETMASK(设置子网掩码),将VIP绑定到指定网卡(如eth0)。
• 免费ARP:调用arp_send_gratuitous()发送ARP广播,更新网络内其他设备的ARP缓存,确保外部请求能正确路由到当前主节点。
- 源IP(Src IP)的指定与生效
源IP的配置通过vrrp_instance的src_ip参数生效,核心逻辑在vrrp_send.c的vrrp_send_advert()函数中——发送VRRP协商报文时,指定源IP为配置的src_ip(默认使用网卡的物理IP)。
关键代码片段(vrrp_send_advert函数)
#include "vrrp_send.h"
/* 发送VRRP协商报文(Advertisement) */
void vrrp_send_advert(struct vrrp_instance *vrrp) {
struct sockaddr_in src_addr, dest_addr;
int sockfd, ret;
char buf[VRRP_ADVERT_LEN];
// 1. 创建UDP socket(VRRP报文基于UDP传输,端口112)
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("socket");
return;
}
// 2. 配置源IP(优先使用src_ip,否则使用网卡物理IP)
memset(&src_addr, 0, sizeof(src_addr));
src_addr.sin_family = AF_INET;
if (vrrp->src_ip) {
src_addr.sin_addr.s_addr = inet_addr(vrrp->src_ip); // 配置的源IP
} else {
// 获取网卡的物理IP(如eth0的IP)
src_addr.sin_addr.s_addr = if_get_addr(vrrp->ifp->name);
}
src_addr.sin_port = htons(VRRP_PORT); // VRRP默认端口112
// 3. 绑定源IP到socket
if (bind(sockfd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
perror("bind");
close(sockfd);
return;
}
// 4. 配置目的IP(组播/单播)并发送报文
// ...(省略目的IP配置和报文发送逻辑)
close(sockfd);
}
- 目的IP(Dest IP)的路由控制
目的IP的逻辑分为组播模式和单播模式,核心代码在vrrp_instance.c的vrrp_init_unicast()和vrrp_send_advert()中:
• 组播模式:默认目的IP为224.0.0.18(VRRP组播地址),通过setsockopt()设置组播路由。
• 单播模式:读取unicast_peer配置的备节点IP,逐个发送VRRP报文,避免组播依赖。
单播模式关键代码片段
#include "vrrp_instance.h"
/* 初始化单播peer列表 */
void vrrp_init_unicast(struct vrrp_instance *vrrp) {
struct unicast_peer *peer;
// 遍历unicast_peer配置,将备节点IP存入vrrp->unicast_peers列表
list_for_each_entry(peer, &vrrp->unicast_peers, list) {
peer->sockaddr.sin_family = AF_INET;
peer->sockaddr.sin_addr.s_addr = inet_addr(peer->ip); // 备节点IP
peer->sockaddr.sin_port = htons(VRRP_PORT);
}
}
/* 单播模式发送VRRP报文 */
void vrrp_send_unicast_advert(struct vrrp_instance *vrrp, char *buf, int len) {
struct unicast_peer *peer;
int sockfd;
sockfd = vrrp_get_socket(vrrp); // 获取已绑定源IP的socket
// 向每个备节点发送VRRP报文
list_for_each_entry(peer, &vrrp->unicast_peers, list) {
sendto(sockfd, buf, len, 0,
(struct sockaddr *)&peer->sockaddr, sizeof(peer->sockaddr));
}
close(sockfd);
}
四、总结
Keepalived的IP配置是其高可用能力的核心,虚拟IP(VIP)确保服务入口统一,源IP(Src IP)控制请求来源,目的IP(Dest IP)决定节点间通信方式,三者需结合业务场景(如网络拓扑、安全性要求)合理配置。
从代码实现来看,Keepalived通过RAW/UDP socket操作IP层,结合ioctl命令和ARP协议管理VIP,通过单播/组播控制报文路由,最终实现“故障自动切换”的核心目标。在实际部署中,需重点关注VIP地址冲突、网络对组播的支持性,以及源/目的IP的路由合法性,避免因配置错误导致高可用失效。
注:内容有参考豆包ai交互内容输出。

1441

被折叠的 条评论
为什么被折叠?



