ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

KOS上ipvsadm适配与LVS四层负载均衡集群搭建实战

KOS上ipvsadm适配与LVS四层负载均衡集群搭建实战 最近在浪潮的 KeyarchOSKOS服务器上搭一套四层负载均衡集群卡在 ipvsadm 的版本适配和功能验证上前前后后折腾了一整天。系统默认 yum 源里能装到的 ipvsadm 版本比较老跟新版内核的 IPVS 接口配合时总会出现调度器注册异常、连接统计不准这类莫名其妙的问题。后来我把 ipvsadm-1.31-6 重新编译适配了一遍才把集群稳定跑起来。这篇东西就是把那次适配和搭建过程完整记录下来包括环境检查、依赖处理、编译安装、转发模式选型、DR 模式集群配置、Keepalived 高可用以及最后几处容易让人头大的坑。适合正在 KOS 或者同类国产 Linux 发行版上做负载均衡的朋友参考。1. KOS 上为什么需要单独适配 ipvsadm版本与内核的匹配问题KeyarchOS简称 KOS是浪潮信息推出的企业级服务器操作系统底层是 Linux 内核整体生态兼容 CentOS 那一套软件包管理、systemd 服务、SELinux 策略这些习惯都和主流发行版保持一致。对于长期在 CentOS 7/8 上做运维的人来说切到 KOS 几乎没有什么学习成本yum 仓库里该有的基础工具基本都在。但问题恰恰出在基本都在这四个字上。yum 仓库里的 ipvsadm 版本号通常停留在比较早的版本而 KOS 为了充分发挥国产服务器硬件的性能内核版本更新得比较勤。老版本 ipvsadm 面对新内核的 IPVS 子系统时会出现两类典型问题一是内核通知链结构变了ipvsadm 在添加虚拟服务时返回协议不支持的错误二是调度器模块注册路径调整后ipvsadm 识别不到动态加载的调度算法导致-s参数指定的算法不生效转发流量全部落在第一个后端节点上。这类问题单靠系统仓库里的老包很难解决。我的处理方式很直接拉官方源码在 KOS 上重新编译 ipvsadm-1.31-6针对 KOS 的内核配置和库文件路径做适配让管理工具和内核 IPVS 模块完全对齐。这是把四层负载均衡集群搭建稳定的前提也是后续一切配置的基础。如果跳过这一步后面线上接入流量后大概率会以各种奇怪的方式翻车。1.1 ipvsadm 到底在负载均衡集群里扮演什么角色在虚拟服务器LVS架构中IPVS 是 Linux 内核里的四层负载均衡模块工作在 TCP/UDP 层负责把进入虚拟 IPVIP的流量按照预设算法转发给后端的真实服务器。ipvsadm 就是用户空间里对 IPVS 进行配置和查询的命令行工具类似于 iptables 之于 netfilter 的关系。一条完整的四层负载均衡规则由两部分组成虚拟服务器Virtual Server和真实服务器Real Server。虚拟服务器定义 VIP、端口、协议和调度算法真实服务器定义实际接收流量的后端节点地址。ipvsadm 的所有操作都是围绕这两层结构展开的常用的增删改查命令模式相对固定熟练掌握之后整个集群的流量路径会非常清晰。1.2 老版本 ipvsadm 在 KOS 上的实际故障表现我最初在 KOS 上用 yum 安装 ipvsadm 后执行ipvsadm -A -t 192.168.100.100:80 -s rr建立虚拟服务命令没有报错但检查调度器状态时发现-s rr指定的轮询算法没有注册成功。执行ipvsadm -L -n看到的 Scheduling 列是空的所有连接都被固定转发到第一台真实服务器第二台始终处于空闲状态。后来查看内核日志才发现关键报错信息是IPVS: Cant schedule connection这个错误和调度器模块的注册方式有关。新版内核的 IPVS 调度器接口已经调整旧版 ipvsadm 自带的调度器名称映射表没有同步导致用户空间的调度器名称无法正确关联到内核模块。重新编译新版本的 ipvsadm 后调度器映射关系匹配rr、wrr、lc、wlc 这些常用算法全部恢复正常。这个故障非常有代表性做国产系统适配时遇到功能看起来正常但实际不生效的诡异现象先怀疑工具版本与内核不匹配是一个很好的排查方向。2. 适配前的环境体检内核模块、依赖库与网络基线拿到一台全新 KOS 服务器后不要急着编译 ipvsadm。先把环境基础摸清楚能省掉后面一多半的麻烦。我习惯按内核模块 → 编译依赖 → 网络规划三个顺序做检查每项都有对应的验证命令和判断标准。2.1 确认 IPVS 内核模块是否可用确认 KOS 内核是否加载了 IPVS 相关模块这一步是基础中的基础。执行lsmod | grep ip_vs如果输出里能看到ip_vs、ip_vs_rr、ip_vs_wrr等模块名称说明内核自带 IPVS 支持且已被加载。如果看不到任何输出先执行modprobe ip_vs手动加载再检查一次。为了让后续的负载均衡功能完整可用建议把常用的调度器模块一并加载。KOS 上可以执行modprobe ip_vs_rr、modprobe ip_vs_wrr、modprobe ip_vs_lc、modprobe ip_vs_wlc等把轮询、加权轮询、最少连接、加权最少连接全部放进内核。如果希望重启后模块自动加载在/etc/modules-load.d/下创建一个配置文件把模块名逐行写进去即可。2.2 编译工具链与 libnl 依赖检查ipvsadm 1.31-6 编译时需要 libnl 库这套库用于内核对象和路由链路层的通信如果头文件缺失编译会直接报错提示找不到libnl3/netlink/netlink.h或libnl/genl/genl.h这类文件。在 KOS 上需要确保 gcc、make、kernel-devel 以及对应的头文件包都已安装完整。kernel-devel 的版本必须和当前运行的内核版本一致否则编译时引用的内核头文件与运行内核不匹配后续可能出现接口结构体不一致的问题。核对命令是uname -r和rpm -q kernel-devel版本号必须对齐。这是一个在 CentOS 系系统里同样容易出现的问题做 KOS 适配时要一眼先定位到版本对应关系。2.3 网络基线规划VIP、DIP、RIP 的梳理四层负载均衡集群的 IP 规划相对固定三个角色各司其职VIPVirtual IP是客户端访问的统一入口需要配置在 Director 节点上DIPDirector IP是 Director 与后端通信的地址RIPReal Server IP是后端真实服务器的地址。DR 模式下VIP 和后端服务器的 IP 必须在同一网段至少广播域要互通这是因为 DR 模式的转发原理本质上依赖二层数据链路层改写 MAC 帧头跨网段就无法工作。在规划阶段就要明确 VIP 不会与任何真实服务器 IP 冲突。曾经在上线前做 IP 规划时直接把 VIP 分配给了后端服务器网卡的某个地址结果 ARP 混乱客户端访问 VIP 时数据的 MAC 地址一会指向 Director、一会指向真实服务器整个集群完全没办法用。这个教训说明规划阶段把 VIP 单独空出来后续的坑会少很多。3. ipvsadm 1.31-6 的源码编译与 KOS 安全策略适配环境检查完毕进入最核心的编译适配环节。这一部分除了把源码编译通过还要处理 KOS 上 SELinux 和防火墙对 IPVS 管理命令的潜在限制。我实际踩过 SELinux 拦截 ipvsadm 更新内核表的坑所以把安全策略适配单独列为一项重点讲。3.1 源码获取与编译执行细节ipvsadm 官方源码可以从内核维护站点或 GitHub 镜像获取。我使用 1.31-6 这个版本是在 1.31 主线的基础上打了若干适配补丁对较新的内核版本支持更完善。解压后进入目录执行make前先确认 Makefile 里有没有指定LIBS的路径如果 libnl 头文件不在系统默认路径里需要手动指定。编译过程中比较容易忽略的是 popt 库。popt 用于解析命令行参数在部分精简系统上未必默认安装。执行编译时如果提示Cannot find -lpopt用包管理器安装popt-devel即可。编译完成后执行make installipvsadm 默认安装到/usr/local/sbin/ipvsadm。为了和系统路径统一建议复制一份到/usr/sbin/ipvsadm后续 Keepalived 调用时不需要额外配置 PATH。3.2 KOS 的 SELinux 策略对 ipvsadm 的影响KeyarchOS 默认启用 SELinux或者至少启用了 enforcing 模式的容器场景。ipvsadm 修改内核 IPVS 表时涉及net_admin和cap_net_admin能力如果 SELinux 策略没有给对应域赋予这些权限命令执行会返回权限不足但出于安全审计的原因SELinux 的拒绝信息不会明明白白地出现在终端只会在/var/log/audit/audit.log里记录一条avc: denied。遇到这种情况可以用ausearch -m avc -ts recent查看近期拒绝记录确认是ipvsadm相关进程被拒绝后执行setsebool -P nis_enabled 1或者为运行 ipvsadm 的域开启对应权限。实际项目中我更推荐把相关的布尔值打开而不是盲目关闭 SELinux这样既保证负载均衡功能可用又不牺牲节点安全隔离能力。3.3 防火墙放行与 IPVS 管理通道KOS 默认使用 firewalld 管理防火墙规则如果直接把防火墙关掉来调试负载均衡虽然省事但线上环境不推荐。需要放行的流量有两类一是客户端访问 VIP 的入口流量二是 Keepalived 的 VRRP 心跳报文。在有状态防火墙逐包过滤的场景里如果只放行 TCP 端口而忘了放行 VRRP协议号 112主备两台 Director 之间的心跳会时断时续触发频繁的脑裂切换集群可用性反而比单节点更差。我在配置中把 VRRP 报文在 firewalld 里单独放行firewall-cmd --permanent --add-rich-rulerule protocol valuevrrp accept。对后端服务器的健康检查流量如果 Keepalived 用 TCP 探测方式需要保证 Director 到 Real Server 的对应端口可达通常不需要额外放行但一定要确认中间没有其他安全组规则拦截。4. 转发模式选型KOS 服务器上为什么首选 DRLVS 支持多种转发模式包括 NAT、DR、TUN 和 FullNAT。每种模式在报文处理路径、网络要求、性能表现上差异很大在 KOS 上搭建集群之前必须根据业务场景选对模式不然集群上线后改模式等于推倒重来。4.1 NAT、DR、TUN、FullNAT 的核心区别NAT 模式是最直观的Director 作为网关把入站请求的目的 IP 改为 Real Server 的 IP回程流量再经过 Director 改回 VIP。这个模式的优势是后端服务器可以使用私有 IP劣势是进出流量都要过 Director在大流量场景下 Director 会成为瓶颈。DR 模式全称 Direct RoutingDirector 只处理入站流量把请求的 MAC 地址改为 Real Server 的 MAC 地址通过二层直接转发到后端。Real Server 处理完请求后直接把响应包发回客户端不再经过 Director。这个模式吞吐量最高但要求 Real Server 和 Director 必须在同一二层网络且 Real Server 需要配置 VIP 并抑制 ARP 响应。TUN 模式使用 IP 隧道封装Director 把原始报文封装在 IP 隧道中发给 Real Server适合跨网段场景但隧道开销会带来额外 CPU 消耗。FullNAT 是国内公司针对 NAT 的改良同时改写源和目的 IP不需要 Real Server 做特殊 ARP 配置但一般需要内核补丁或者定制模块KOS 上适配成本较高。4.2 DR 模式在 KOS 上的 ARP 配置细节DR 模式性能好但有一个著名的 ARP 问题当 Real Server 上配置了 VIP 后它也会响应针对 VIP 的 ARP 请求导致客户端直接和后端服务器通信负载均衡规则形同虚设。解决办法是在 Real Server 的 loopback 接口上配置 VIP并通过arp_ignore和arp_announce内核参数抑制 ARP 响应。在 KOS 上配置 DR 模式的 Real Server 时需要设置以下参数net.ipv4.conf.all.arp_ignore 1 net.ipv4.conf.all.arp_announce 2 net.ipv4.conf.lo.arp_ignore 1 net.ipv4.conf.lo.arp_announce 2arp_ignore 1表示只回答目标 IP 是本机物理网卡 IP 的 ARP 请求对 VIP 的 ARP 请求不予响应arp_announce 2表示只使用本接口的最佳本地地址发送 ARP 响应。配置后VIP 的 ARP 请求只会由 Director 响应Real Server 则安静地接收 Director 转过来的二层帧。改完参数后用sysctl -p刷新并确认这两个参数不生效的后果是流量混乱、连接超时排查起来相当耗费精力。4.3 调度算法的初步选择选好模式之后调度算法也需要结合业务特征决定。最小连接lc适合请求处理时间差异大的场景轮询rr适合请求处理时间接近的场景加权轮询wrr则适合后端服务器性能不一的场景。初始阶段从 wrr 或 lc 起步通常是比较稳妥的在 KOS 上验证的方式是执行ipvsadm -L -n --stats观察各 Real Server 的连接数和流量分布再根据实际情况调整权重或算法。5. 集群搭建实录Director 与后端节点的完整配置环境准备好了模式也选好了现在进入核心干货在 KOS 上把四层负载均衡集群完整搭建起来。这一节我会按 Director 节点、Real Server 节点、验证三个步骤走把每一处命令和配置目的讲清楚方便直接抄作业。5.1 Director 上的 VIP 配置与 ipvsadm 规则假设两个后端节点 IP 分别是 192.168.100.11 和 192.168.100.12VIP 是 192.168.100.200Director 对外提供 TCP 80 端口的负载均衡。第一步在 Director 主网卡上配置 VIPip addr add 192.168.100.200/24 dev eth0这里要注意掩码设置为和局域网一致的 24 位避免 VIP 的路由异常。需要持久化的话在 KOS 的/etc/sysconfig/network-scripts/ifcfg-eth0里追加 IPADDR 配置或者使用 NetworkManager 的连接管理命令。第二步添加虚拟服务器和后端节点ipvsadm -A -t 192.168.100.200:80 -s wrr ipvsadm -a -t 192.168.100.200:80 -r 192.168.100.11:80 -g -w 1 ipvsadm -a -t 192.168.100.200:80 -r 192.168.100.12:80 -g -w 2-t指定 TCP 协议-s wrr指定加权轮询算法-r添加后端真实服务器-g指定使用 DRGatewaying模式-w设置权重。权重分配的含义是后端节点 2 承担双倍于节点 1 的流量如果两台服务器配置相同就把权重保持为 1。5.2 后端节点上的 ARP 抑制与 VIP 回环接口配置Real Server 需要把 VIP 绑定到 loopback 接口让回程数据包能使用 VIP 作为源地址发出同时必须抑制对这个 VIP 的 ARP 响应否则会和 Director 争抢广播应答。在 192.168.100.11 和 192.168.100.12 两台机器上执行ip addr add 192.168.100.200/32 dev lo echo 1 /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 /proc/sys/net/ipv4/conf/all/arp_announce echo 1 /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 /proc/sys/net/ipv4/conf/lo/arp_announce添加到 loopback 接口的 VIP 掩码固定为 32 位不要用 24 位或其它网段掩码否则会产生额外的本地路由冲突。配置持久化建议同时更新/etc/sysctl.conf和网络配置文件。5.3 集群连通性验证与 ipvsadm 状态解读配置完成后验证是最重要的一环。从客户端或跳板机执行curl http://192.168.100.200/多次访问观察返回结果的变化。然后在 Director 上执行ipvsadm -L -n --stats输出中可以看到每台后端的连接数和字节数。如果频繁访问后两台后端节点的 ActiveConn 和 InActConn 都随时间增长且权重分配与流量比例接近预期说明转发逻辑是正常的。再用ipvsadm -L -n -c查看当前连接状态表能看到源地址到 VIP 再到 Real Server 的完整映射关系。这里的 TCP 连接状态包括SYN_RECV、ESTABLISHED、FIN_WAIT等状态流转正常说明 IPVS 的会话跟踪工作正常。如果发现所有连接都堆积在某一台后端上第一件事是检查调度算法是否真的生效其次检查后端权重是否设置正确。6. 高可用组合Keepalived 与 ipvsadm 的联动配置单台 Director 一旦宕机整个集群入口就没了。用 Keepalived 配合 ipvsadm 做高可用是标准做法。Keepalived 通过 VRRP 协议在主备节点之间虚拟共享一个 VIP并监控后端节点的健康状态实现自动故障摘除和切换。6.1 VRRP 实例与 VIP 漂移配置在 Director 主备两台机器上安装 Keepalived 后编辑/etc/keepalived/keepalived.conf。主节点配置global_defs { router_id LVS_MASTER } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass yourpassword } virtual_ipaddress { 192.168.100.200/24 dev eth0 } }备节点配置与主节点基本一致state改为BACKUPpriority改为 90。virtual_router_id在主备间必须一致auth_pass两端的值也必须完全匹配否则广播心跳无法通过认证导致双主分裂。6.2 后端健康检查与自动摘除Keepalived 可以通过虚服务器段配置实时检测后端节点virtual_server 192.168.100.200 80 { delay_loop 6 lb_algo wrr lb_kind DR protocol TCP real_server 192.168.100.11 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.100.12 80 { weight 2 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }Keepalived 每隔delay_loop秒对每个 real_server 发起 TCP 连接检查连续失败超过设定次数后自动把该节点从 ipvsadm 的转发列表中摘除恢复后再重新加入。这在业务高峰期非常关键之前某个后端服务的 Nginx 进程假死但 TCP 端口仍然能连接TCP_CHECK 透传 80 端口没有任何问题后来把检查方式改成 HTTP_GET 请求特定路径才真正捕获到应用层故障。如果你的后端是一个完整的 HTTP 服务健康检查应当优先考虑 HTTP_GET。6.3 主备切换与脑裂防护验证配置完 Keepalived 后需要主动验证主备切换能力。在 MASTER 节点执行systemctl stop keepalived几秒后 VIP 会自动漂移到 BACKUP 节点客户端使用同一 IP 访问时不应出现长时间中断。ip addr show eth0观察 VIP 的存在位置变化可以追踪漂移过程。脑裂是高可用里最需要防的场景典型现象是主备节点同时持有 VIP。导致脑裂的原因通常有配置不一致、心跳报文被防火墙拦截、物理链路故障等。在 KOS 上重点确认 firewalld 放行 VRRP 协议协议号 112同时让两端 keepalived.conf 中的认证密码和 virtual_router_id 保持一致。如果已经发生脑裂优先检查心跳路径不要急着强制停止某台节点否则可能造成数据不一致或者服务全断。7. 那些踩过的坑超时参数、连接追踪与性能调优集群能跑起来不难但跑得稳才见功力。在实际使用中我遇到过的几个问题和对应的处理方式值得在 KOS 上做四层负载均衡时特别注意。7.1 连接超时参数引发的连接挂死IPVS 连接超时参数控制空闲连接在连接表中的保留时间默认值对 TCP 会话是 900 秒TCP 半关闭 120 秒UDP 300 秒。默认值在大多数场景够用但如果业务中存在很多长连接例如 WebSocket、数据库连接池空闲连接会被过早清理反过来如果业务大量短连接连接表可能被TIME_WAIT状态的记录撑满影响新连接建立。调整超时参数使用以下命令ipvsadm --set 3600 600 300三个数字分别对应 TCP 空闲超时、TCP FIN 状态超时、UDP 超时。对长连接为主的业务把 TCP 超时调大到 7200 甚至更长。这个参数需要跟后端服务的 keepalive 配合着设置否则连接在任一端被关闭而 IPVS 表里还挂着旧记录流量会短暂地打到已经不存在的连接上表现为偶发请求超时。7.2 KOS 防火墙和 SELinux 对流量的影响在 KOS 上最容易忽略的就是 firewalld 和 SELinux 同时作用在流量路径上。即使 Director 已经把流量转发给后端后端服务器如果自身的 firewalld 没有放行 VIP 的入站端口TCP 握手仍然会失败表现出来就是curl一直超时。排查时先看后端的/var/log/messages或者journalctl如果看到大量的DROP或者state相关日志基本可以判断是防火墙拦截。SELinux 干扰 ipvsadm 的现象则是命令执行时报权限拒绝但没有任何进程崩溃日志。确认方法就是前面提到的ausearch -m avc -ts recent一旦出现ipvsadm相关的 denied 记录放开对应布尔值即可。记住一个原则KOS 上做网络相关的适配先看 SELinux 拒绝日志再看防火墙规则最后才怀疑网络物理链路。7.3 持久连接与调度不均的处理在部分业务中同一个客户端的多次请求必须保证落到同一台后端服务器比如需要共享会话状态的服务。IPVS 使用持久连接功能来满足这个需求。在 ipvsadm 中虚拟服务器配置时指定-p参数并带上超时时间即可ipvsadm -A -t 192.168.100.200:80 -s wrr -p 600这里的 600 代表 600 秒内来自同一源 IP 的连接会被定向到同一后端。但要注意开持久连接后轮询算法的分发效果会被减弱如果后端服务器配置差异大流量可能出现倾斜。需要结合ipvsadm -L -n --persistent-conn查看持久连接表确认分发合理性。7.4 性能层面的几个调优方向四层负载均衡的性能瓶颈通常不在 ipvsadm 本身而在于内核参数和网卡处理能力。KOS 上可以调整的几项包括连接跟踪表大小nf_conntrack_max、TIME_WAIT连接复用net.ipv4.tcp_tw_reuse、全连接队列长度net.core.somaxconn。还有一点容易被忽略的是多队列网卡的 RSS 配置如果网卡中断没有均衡到多个 CPU转发性能会被单核限制。另外一个直接有效的优化是关闭 Director 上不必要的 GSO/GRO 卸载有些网卡驱动在 IPVS 转发路径上存在卸载异常会导致大包丢包率偏高。执行ethtool -K eth0 gro off gso off后对比ipvsadm -L -n --rate的输出每秒转发包数和吞吐量会有可感知的提升。注意这个操作对具体的网卡驱动有依赖测试环境先验证再上生产。我在实际使用中还发现Keepalived 的advert_int调小到 0.5 秒能显著加快主备切换速度但前提是网络环境足够稳定否则频繁的 VRRP 广播会造成不必要的切换抖动。KOS 默认防火墙放行 VRRP 后这个参数可以放心调整。最终集群的稳定性是多个参数协同作用的结果建议每调整一项就压测一轮用数据说话不要凭感觉一次性改一堆参数。如果后面有机会再做扩展我会把 KOS 上结合 DPDK 的高性能负载均衡方案也整理出来那个方向在国产化服务器上的收益更明显。这次的 ipvsadm 适配和集群搭建就先分享到这里希望对正在 KOS 上做同样事情的朋友有帮助。
返回列表