资讯详情

Nginx 权重、LVS 转发与 Keepalived 脑裂排障解析

📅 2026/9/20 5:36:16 | 华诺云谱 👁 阅读
Nginx 权重、LVS 转发与 Keepalived 脑裂排障解析
简介面向 HCIP-OpenEuler V1.0 认证备考者的一套超全题库聚焦 Nginx 负载均衡、LVS 集群调度与自动化运维三大方向适合具备一定 Linux 系统管理与网络基础、负责 Web 站点建设维护的企业 IT 工程师及考证人员使用。压缩包内共 1 个文件为 1.03MB 的 PDF 文档收录单选、多选、判断、填空等 96 道题目题面结合真实生产场景展开难度适中便于打印标注与离线刷题。其中既有上游服务器权重分配、ip_hash 与 backup 参数辨析、HTTP 工作机制判断也涉及 firewalld 与 SELinux 策略导致的访问异常排查、Keepalived 高可用方案取舍、Ansible、SaltStack 与 Puppet 工具选型以及 Zabbix 监控启动故障定位等实践考点并延伸至大型企业万台服务器的自动化部署与 Web 集群稳定性保障。目前已有 311 人学习可用于系统复习与查漏补缺在理解负载均衡配置和自动化运维思路的同时提升实际排障能力。1. 从 upstream weight 配置题看 Nginx 负载均衡的调度语义一台 Nginx 挂在 web0110.0.0.7和 web0210.0.0.8前面业务侧的要求是「两台都要收到请求但 web01 多分担一些」。这句话翻译成配置语言等于排除了 backup、down、ip_hash 三条路只剩 weight。正确写法是在 10.0.0.7 上压 weight5另一台不写权重默认为 1调度比例就是 5:1两台都活着同时满足「都能收到」和「web01 更多」两个条件。反观另外几个选项纯轮询是均分把 10.0.0.8 标 down 等于直接摘机标 backup 则只有主节点全挂时才会启用备机。这里还有一层容易踩的细节——upstream 块名只是逻辑标识符真正决定行为的是 server 指令后面的参数而且 weight 是相对值而非百分比5 和 1 跟 50 和 10 的效果完全一样。2. LVS 三种转发模式与 ipvsadm 规则落地2.1 NAT、DR、TUN 的报文改写差异LVS 的调度逻辑在内核ip_vs模块里完成用户态只负责下发规则。三种工作模式的区别本质是「谁改写报文、响应怎么回」这三件事不一样。NAT 模式下客户端请求先到 DirectorDirector 改写目的 IP 转发给 RSRS 处理完把响应回给 DirectorDirector 再改写源 IP 回给客户端——请求和响应都要穿过 Director所以 Director 很容易先成为瓶颈。DR 模式只改写数据帧的目的 MACRS 处理完直接把响应甩给客户端Director 只扛「进」不扛「出」吞吐上限高得多。TUN 模式则是在原报文外层再封一层 IP 隧道适合 Director 和 RS 跨网段的场景代价是 RS 必须能解封装 IPIP。题干里那句「后端服务器数量较多、网段无法统一」直接指向 NAT 模式因为 DR 要求 Director 与所有 RS 处在同一广播域内网段不齐就没法用。至于「提高转发效率、避免成为性能瓶颈」答案落在 DR 上。模式是否改写报文大小转发效率网段要求ipvsadm 参数NAT是改 IP 头中Director 与 RS 可不同网段-mDR否高必须同网段-gTUN是加隧道头中高可跨网段-i2.2 ipvsadm 添加 RS 的正确姿势题目给的条件是 NAT 模式VIP 192.168.1.10DIP 10.0.0.1RS 真实 IP 10.0.0.2。添加真实服务器的命令必须把「对外服务地址」和「真实服务器地址」分清楚-t后面跟的是 VIP 加端口-r后面才是 RS。写成-t 10.0.0.2或者漏掉-m都无法生效。# 先建虚拟服务-s 指定调度算法rr 为轮询 ipvsadm -A -t 192.168.1.10:80 -s rr # 再挂真实服务器-t 是 VIP-r 是 RS-m 表示 NAT 模式 ipvsadm -a -t 192.168.1.10:80 -r 10.0.0.2:80 -m # 查看当前规则和连接状态 ipvsadm -Ln --stats命令拆开看-A是新增虚拟服务-a是往已有服务里加节点大小写不能混-t表示 TCP 服务UDP 要换成-u-s只在建服务时写一次调度算法有rr、wrr、lc、wlc、sh等后面挂节点时不再重复指定。执行完之后用ipvsadm -Ln核对如果ActiveConn长期为 0 而InActConn一直在涨通常说明 RS 的网关没指向 DIP响应回不来。NAT 模式还要打开内核转发否则 Director 收到包也不知道往哪送。常见做法是在/etc/sysctl.d/下丢一个配置文件而不是直接改/etc/sysctl.confcat /etc/sysctl.d/99-lvs.conf EOF net.ipv4.ip_forward 1 EOF sysctl -p /etc/sysctl.d/99-lvs.confip_forward这个开关不只影响 LVSHAProxy、iptables 的 DNAT 转发、部分 Keepalived 场景都吃它所以把它关掉以后受影响的往往是一整条转发链路而不是单个服务。2.3 DR 模式的两处硬性前提DR 模式配完发现转发不正常排查顺序基本固定。第一是 RS 上有没有把 VIP 配到lo或回环别名上——DR 不改目的 IPRS 必须认为这个 VIP 属于自己否则内核收到包会直接丢掉。第二是 ARP 抑制有没有做如果 RS 没关掉对 VIP 的 ARP 应答客户端和网关的 ARP 表里 VIP 就可能指向某台 RS整个集群的入口就乱了。# 抑制 ARP 应答与通告避免 RS 抢答 VIP 的 ARP 请求 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 # 在回环接口上挂 VIP掩码写 32 位防止产生直连路由 ip addr add 192.168.1.10/32 dev lo这四个arp_*参数是 DR 模式能不能通的隐形开关很多人只配了 VIP 忘了抑制结果测试时好时坏。另外firewalld里对应接口如果没有放通转发同样会被拦下来排查时先systemctl stop firewalld做一次对照实验能省不少时间。3. HTTP 响应报文解析与 403、长连接类故障定位3.1 从响应头字段反推链路拓扑一段 HTTP 报文只要看首行就能分清请求还是响应HTTP/1.1 200开头的是响应报文GET /path HTTP/1.1开头的是请求报文。响应头里Connection: keep-alive配合 HTTP/1.1 默认行为说明这条 TCP 连接会复用不需要每个资源都重新握手Cache-Control: max-age604800和Expires一起出现说明资源被缓存一周Content-Encoding: gzip表示响应体经过压缩客户端要能解压。更有意思的是那几行X-Kong-Upstream-Latency、X-Kong-Proxy-Latency这类X-前缀的自定义头是网关自己加的看到它就能判断前端不是裸 Nginx也不是 Keepalived——Keepalived 工作在网络层根本不碰 HTTP 头。这是一个很实用的反推技巧响应头里带厂商或组件特征的字段比配置文件更诚实地告诉你流量经过了谁。# 只看响应头-I 发的是 HEAD 请求不下载响应体 curl -I http://www.test.com/ # 看完整请求响应过程含 TLS 握手和重定向链 curl -v -o /dev/null -s http://www.test.com/ # 只打印响应头里的关键字段 curl -sI http://www.test.com/ | grep -Ei server|connection|cache-control-I走的是 HEAD 方法有些后端对 HEAD 的支持和 GET 不一致返回的Content-Length可能不同这时候要换成-X GET -o /dev/null -D -来看真实的 GET 响应头。3.2 403 状态码的三条常见路径403 是「服务器听懂了你想要什么但拒绝给你」。在 Apache 场景里它最常见的三个来源是SELinux 处于 enforcing 状态httpd 进程没有读取目标目录的安全上下文Directory段里写了Require not ip把当前客户端 IP 排除了目录本身缺少x权限或者既没有 index 文件又禁用了目录列表。这三条都要逐个排除而不是看到 403 就先去改httpd.conf。# 查 SELinux 当前状态与 httpd 相关布尔值 getenforce getsebool -a | grep httpd # 看目录的安全上下文必要时用 restorecon 修复 ls -Zd /var/www/html restorecon -Rv /var/www/html # 看 Apache 实际生效的目录权限配置 apachectl -S grep -rn Require /etc/httpd/conf.d/ /etc/httpd/conf/httpd.confgetenforce返回Enforcing时restorecon通常能把因为拷贝文件而错乱的安全上下文拉回来如果确认是 SELinux 挡的临时验证可以用setenforce 0但生产上不建议长期关改布尔值或打标签才是正路。用 Ansible 批量装完 httpd 却访问不到默认页第一反应就该是 SELinux而不是 httpd 有没有启动——服务起来了但页面 403恰恰是 enforcing 的典型表现。3.3 反向代理的端口与路径验证Nginx 做反向代理时客户端访问的端口和真实服务器提供的端口可以完全不同。客户端访问www.test.com:80Nginx 把请求转给后端的www.test80.com:80、www.test81.com:81、www.test82.com:82这是proxy_pass的常规用法。但要注意firewalld的 public zone 放通策略——Nginx 所在主机作为入口对外只需要放通它自己监听的 80后端那三个端口是 Nginx 作为客户端去发起的出站连接不经过本机防火墙的入站规则。两者别混为一谈。upstream backend_pool { server 10.0.0.21:80; server 10.0.0.22:81; server 10.0.0.23:82; } server { listen 80; server_name www.test.com; location / { proxy_pass http://backend_pool; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 30s; } }proxy_set_header这两行不是可选项缺了Host和X-Real-IP后端拿到的全是 Nginx 自己的地址日志和鉴权都会失真。proxy_read_timeout默认 60 秒长连接业务里如果后端处理慢要么调大它要么在 upstream 里配keepalive和proxy_http_version 1.1否则每次请求都会重新建连压测时表现为 QPS 上不去、TIME_WAIT 堆积。虚拟主机用端口区分资源时如果发现不同端口访问出来是同一份内容八成是各个server块里的root写成了同一个路径或者index指向同一个文件配置本身没生效到对应的 server 块上。用nginx -T把合并后的完整配置打出来看比逐个文件翻要快得多。4. Ansible 与 SaltStack 在 GlusterFS 集群运维里的分工4.1 模块对应关系与 ad-hoc 落地Ansible 和 SaltStack 在功能上高度重叠但模块命名体系不同。做功能迁移时按对应关系替换能省掉大量试错包管理上 Ansible 的yum对应 SaltStack 的pkg服务管理两边都叫service文件管理两边都叫file。不成立的是把 Ansible 的service_facts对应 SaltStack 的pillar——前者是采集服务状态的事实模块后者是下发变量的数据容器压根不是一个层次的东西。# 用 ad-hoc 在 test 组批量安装 httpdstatepresent 表示确保存在 ansible test -m yum -a namehttpd statepresent # 等价的 SaltStack 写法target 用通配匹配主机 salt test* pkg.install httpd # 采集服务状态用于核对 httpd 是否真的在跑 ansible test -m service_facts-m指定模块-a传模块参数这是 Ansible ad-hoc 的固定骨架。statepresent只保证装上不保证启动要启动得再补一句ansible test -m service -a namehttpd statestarted enabledyes。安装成功却访问不到默认页除了前面说的 SELinux还要确认enabledyes是否漏了——CentOS 系下 httpd 装完默认不设开机自启。4.2 什么时候该退回 shell 加 cron自动化工具不是万能钥匙。周期性检查 bricks 所在磁盘容量这类任务用 shell 脚本配 cron 反而比 playbook 更合适。原因在于它是高频、轻量、只读的巡检动作不需要幂等状态也不需要维护「期望状态」每次跑 playbook 都要走一遍 SSH 建连和 fact 采集开销远大于收益。反过来安装并配置 Keepalived、在 DNS 服务器添加解析记录这类涉及状态变更和依赖顺序的操作才应该交给 playbook。任务类型推荐方式理由批量装包、配服务Ansible playbook需要幂等和依赖编排周期巡检磁盘容量shell cron高频只读无需状态管理采集节点磁盘清单shell 或 ad-hoc一次性读取输出即结果Keepalived 高可用配置Ansible Jinja2 模板多机配置需严格一致gather_facts: no这个开关在纯执行类任务里值得加上能把每次运行的时间砍掉一大截。用 Jinja2 模板渲染 Keepalived 配置时virtual_router_id、priority、state这些值最好全部由变量驱动否则容易出现所有主机都渲染成同一份配置、大家都以为自己是 MASTER 的尴尬局面。4.3 GlusterFS 卷类型与容灾边界GlusterFS 没有中心元数据节点属于去中心化架构这个特性直接决定了它的扩展方式——加 brick 就能扩不像传统分布式文件系统那样受元数据服务器限制。三种基本卷的容灾表现差别很大分布卷把文件散到各个 brick 上坏一台只是部分文件读不到复制卷每份数据存多副本坏一台数据依然完整分散卷disperse靠冗余块做纠错配置时必须满足redundancy严格小于disperse的一半像 disperse2、redundancy2 或者 disperse4、redundancy2 都是无效组合前者冗余等于总数后者刚好卡在边界上不满足严格小于。# 创建三副本复制卷副本数 2 表示每个文件存 2 份 gluster volume create vol_replica replica 2 \ node1:/data/brick1 node2:/data/brick1 node3:/data/brick1 force # 启动卷并查看状态 gluster volume start vol_replica gluster volume info vol_replicareplica 2至少要两个 brick实践里通常配三个节点做「两副本加仲裁」的形态。建卷时 brick 目录必须是空目录非空会要求加force但强上的后果是数据可能被覆盖这个参数用之前要确认清楚。配合 Keepalived 的 VIP 对外提供挂载点时客户端挂载的是 VIP 而不是某个具体节点节点故障时 VIP 漂移过去客户端只需要重新挂载一次。5. Keepalived VRRP 脑裂排查与 VIP 漂移验证Keepalived 用 VRRP 协议做选举同一组实例里virtual_router_id必须一致priority大的当 MASTER这个方向和很多人第一直觉相反。配置里两台机都写state BACKUP且优先级相同就会同时进入选举、同时又都收不到对方的通告结果两台都把自己升成 MASTER各配一份 VIP——这就是典型脑裂。除了优先级防火墙没放通 VRRP 协议协议号 112也是常见诱因firewalld默认不放行通告包发不出去对方自然以为主挂了。# 抓 VRRP 通告包正常应每秒一次方向为组播 224.0.0.18 tcpdump -i ens33 -nn vrrp # 看 keepalived 日志里的状态迁移过程 journalctl -u keepalived -f # 确认 VIP 当前落在哪台机器上 ip addr show ens33 | grep 10.0.0.20advert_int 1表示每秒发一次通告如果tcpdump里看不到包先查防火墙而不是查配置。virtual_router_id取值 1 到 255同一网段里不同业务要用不同 ID否则两组集群会互相干扰。用 Ansible 批量下发配置后出现「所有主机都先变 BACKUP 再自升 MASTER」优先怀疑模板变量没渲染——把priority和state都写成固定值所有机器拿到的就是同一份文件日志里会看到整齐划一的状态迁移这本身就是个很明确的信号。验证 VIP 漂移最直接的办法是停掉 MASTER 上的 keepalived在备机上journalctl应该看到Entering MASTER STATE且ip addr多出 VIP恢复后再看它是否按nopreempt的设定让位。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。