F5、Nginx、Kubernetes如何分工协作,构建高并发高可用架构

发布时间:2026/9/8 4:42:54
F5、Nginx、Kubernetes如何分工协作,构建高并发高可用架构 在实际交付一个互联网服务时架构评审会上经常会把 F5、Nginx、Kubernetes 三个名字放进同一张图里。很多人会问这三者看起来都在提高服务的并发能力和可用性到底谁更关键Kubernetes 已经能做服务发现和副本管理是不是就不需要 Nginx 了云上部署是不是可以完全放弃 F5这个问题之所以讨论不出结果是因为三个工具并不在同一层工作。F5 是靠近网络入口的专用流量网关负责高速转发、连接管理和入口高可用Nginx 是软件反向代理负责七层路由、流量分发和一定的故障转移Kubernetes 是容器编排平台负责应用实例的调度、自愈和水平扩展。它们之间是纵向的分层协作不是横向的同层替代。这篇文章会从“并发”和“可用性”两个指标入手拆开每个工具的工作原理、典型配置和取舍边界最后给出组合架构和排查链路。1. 先搞清楚并发和可用性问题发生在哪一层1.1 并发能力至少要拆成两个指标讨论并发时最常见的误区是只用一个词“高并发”覆盖所有场景。实际项目里至少要把并发拆成两个指标并发连接数同一时刻系统维持的 TCP 连接、HTTP 长连接或 WebSocket 连接数量。每秒请求数QPS或每秒事务数TPS单位时间内系统能处理的请求数量。这两个指标互相影响但瓶颈点不一样。连接数很高时可能是线程模型、文件句柄、内存占用受限QPS 很高时可能是 CPU、网络带宽、数据库连接池或上游服务处理能力受限。长连接型业务比如消息推送、在线协作文档更容易先撞上连接数瓶颈。短请求型业务比如搜索、下单、查询更容易先撞上 QPS 瓶颈。评估 F5、Nginx、Kubernetes 对并发的贡献要先明确业务是哪种类型。1.2 可用性不是“保证不宕机”而是几个能力组合可用性通常用 SLA 衡量比如 99.9% 意味着一年停机时间不能超过约 8.76 小时。但更实际的理解是可用性由几个能力组合而成。冗余关键节点不止一个实例单个实例故障不会导致整体中断。健康检查系统能识别哪个实例已经不健康并把流量从它身上摘除。故障转移摘除故障实例后流量能自动落到健康实例上。优雅启停发布或扩容时正在处理的请求不会被粗暴切断。F5、Nginx、Kubernetes 都具备一定程度的健康检查和故障转移能力但检查的粒度、频率和触发后的动作差别很大。这也是后面几章要展开的内容。1.3 三个工具的边界从哪里划分可以先做一个粗糙的边界划分F5工作在 L4 到 L7天然靠近网络入口适合做 VIP、南北向流量入口、TLS 卸载和超大并发连接承接。Nginx工作在 L7适合做域名路由、URL 路由、缓存、限流和到后端的反向代理。Kubernetes工作在应用编排层解决“副本够不够”“Pod 是否健康”“流量如何映射到后端 Pod”这类问题。理解了这层边界再看三者为什么不是替代关系就会清楚很多。2. F5 在入口链路上靠什么扛住并发2.1 F5 不是“高级 Nginx”而是一台专用流量网关F5 在本文中指 F5 BIG-IP 这类应用交付控制器ADC不是浏览器里的刷新快捷键也不是功率放大器里的场效应管型号。BIG-IP 的核心模块 LTMLocal Traffic Manager负责把到达虚拟服务器Virtual Server的流量分发给后端资源池Pool中的成员Pool Member。这里先建立一组常用概念Virtual Server对外提供服务的入口比如203.0.113.10:80客户端只访问这个地址。Pool一组后端服务器节点的集合。Pool Member池里的某个具体节点比如10.0.1.11:80。Health Monitor定期探测后端节点是否存活探测失败会自动把节点从池中摘除。SNAT源地址转换让后端回包能正确回到客户端。DSR直接服务器返回后端直接回包给客户端流量不绕回负载均衡器。F5 提升并发的思路不是“CPU 更高”而是把流量转发这件事从通用 CPU 链路中剥离出来。专用硬件、内核旁路、连接表加速这些技术合在一起让它在超大并发连接场景下仍然保持稳定转发。2.2 F5 提升可用性的机制Monitor 加主备F5 对可用性的贡献主要体现在两个层面。第一层是 Pool 成员级别。配置健康检查后F5 会持续探测后端节点。探测方式可以是简单的 TCP 端口探测也可以是 HTTP GET 某个特定路径。一旦节点连续失败F5 会将这个成员标记为 down新流量不再分发给它。第二层是设备级别。生产环境通常部署两台 F5 组成主备对主备之间通过专用心跳同步会话表、配置和连接状态。主设备故障时备设备接管 VIP。这一层切换发生在入口对客户端是透明的。2.3 一个用于理解概念的最小示例下面这段 tmsh 风格配置只用于理解 F5 的配置思路不同版本的语法有差异落地前要以对应版本文档为准。create ltm pool web_pool { load-balancing-mode round-robin members { 10.0.1.11:80 { } 10.0.1.12:80 { } } monitor http } create ltm virtual web_vs { destination 203.0.113.10:80 pool web_pool source-address-translation { type automap } }这段配置表达的意思是外部客户端访问203.0.113.10:80时F5 将流量按轮询方式分发给10.0.1.11:80和10.0.1.12:80并且通过 HTTP Monitor 检查两个后端的健康状态。实际项目中 F5 还需要考虑 TLS 证书卸载、会话保持、访问控制、日志分析和主备同步。如果业务量没有达到需要硬件网关的程度直接用云上负载均衡或纯软件方案也可以不必为了“技术完整”强行引入 F5。2.4 F5 到底适合什么场景F5 适合的场景通常有三个共同点入口流量非常集中单台软件实例的转发能力已经紧张。需要统一的网络入口策略比如 CIDR 白名单、协议限制、TLS 集中卸载。链路要求稳定的故障切换比如运营商级网络或政企内网边界。如果业务处于中小规模云上的负载均衡产品和 Nginx 已经能覆盖大部分需求。这也是很多中小团队觉得 F5 离自己很远的原因。它解决的是规模化之后的工程问题不是入门阶段的第一选择。3. Nginx 在七层软件层做了什么3.1 事件驱动模型为什么比多线程更适合高并发Nginx 是软件反向代理工作在七层核心优势可以用一个词概括事件驱动。它不像传统 Web 服务器那样为一个连接分配一个进程或线程而是用少量 Worker 进程配合事件循环处理大量连接。这种模型的效果是连接数很多时系统资源的消耗不会随连接数线性暴涨。Nginx 的官方设计目标是支持数万个并发连接而 Worker 数量通常只设置为 CPU 核心数。关键配置项很直接worker_processes auto; worker_rlimit_nofile 65535; events { use epoll; worker_connections 10240; }worker_processes auto让 Nginx 按 CPU 核心数自动创建 Worker。use epoll在 Linux 上使用 epoll 事件模型。worker_connections 10240单个 Worker 允许的最大连接数。这里要注意worker_connections调大不意味着性能一定提升。文件句柄限制、内存、后端处理能力都可能先成为瓶颈。盲目调大只会把压力推到后端或让系统资源耗尽。3.2 用 upstream 做负载均衡和故障转移Nginx 提升可用性最常用的方式是 upstream 分组。当后端节点故障时Nginx 可以通过被动健康检查把请求转发到其他节点。一段典型的反向代理配置upstream backend_http { server 10.0.1.11:8080 max_fails2 fail_timeout30s; server 10.0.1.12:8080 max_fails2 fail_timeout30s; keepalive 32; } server { listen 80; server_name api.example.com; location /api/ { proxy_pass http://backend_http; proxy_http_version 1.1; proxy_set_header Connection ; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 5s; proxy_read_timeout 30s; } }这里有几个关键细节max_fails2 fail_timeout30s30 秒内失败 2 次Nginx 认为该节点不可用是开源版的被动健康检查机制。keepalive 32Nginx 与后端之间保留 32 个空闲长连接避免每次请求都重新建立 TCP 连接。proxy_set_header Connection 在与后端通信时切回 HTTP/1.1 并去掉逐跳头配合 keepalive 使用。X-Forwarded-For保留客户端真实 IP 链路后端才能做日志分析和访问控制。3.3 关键参数速查参数含义调大影响调小影响推荐场景worker_processesWorker 进程数提高并行处理能力但过多会增加上下文切换单核多连接时可能成为瓶颈一般设为 CPU 核心数worker_connections单 Worker 最大连接数提升并发连接上限并发高时出现连接拒绝结合系统句柄和内存调整keepalive上游空闲连接数减少 TCP 建连开销每次请求都要新建连接延迟升高短期突发请求多的场景max_fails允许失败次数容忍抖动但摘除变慢误判增多节点容易被误摘后端较稳定时设为 2 到 3fail_timeout统计失败的时间窗口记录周期过长摘除慢周期过短瞬时抖动触发误摘30 到 60 秒比较常见proxy_read_timeout等待后端响应时间容忍慢接口但占用连接快速失败适合要求低延迟的接口按业务接口耗时设置3.4 开源版 Nginx 健康检查的局限开源版 Nginx 的健康检查是“被动”的只有请求被转发到故障节点并失败后才会触发max_fails计数。这意味着从后端故障到流量被摘除存在延迟且检查结果依赖真实请求不是主动探测。如果业务对故障转移要求高有几种补法使用 Nginx Plus 的主动健康检查功能。使用外部拨测脚本定期探测后端并动态更新 upstream 配置。将 Nginx 部署在 Kubernetes 内作为 Ingress Controller 使用利用 K8s 的 Endpoints 变化机制及时摘除故障 Pod。最后一种方式很常见它把 Nginx 的流量能力和 K8s 的服务发现能力组合起来正好引出下一章。4. Kubernetes 从编排层解决了什么4.1 Kubernetes 不是负载均衡器而是声明式自愈系统Kubernetes 经常被误解为“自带负载均衡”。它确实有 Service 和 Ingress 组件但 Kubernetes 的核心价值不在流量转发而在于三个能力声明式部署用户描述期望状态比如“web 服务要有 3 个副本”。自愈循环控制面持续对比当前状态与期望状态发现 Pod 异常后自动重建。水平扩展通过 HPA 等机制根据 CPU、内存或自定义指标调整副本数。Kubernetes 的可用性来源不是某台机器的稳定性而是“即使个别 Pod 挂了系统也能快速把它拉回期望状态”的机制。这和 F5、Nginx 的流量层故障转移是不同维度的保障。4.2 Deployment 和探针什么才算一个可用实例一个常见的错误是只检查“进程还在不在”不检查“服务是否真的能处理请求”。Kubernetes 用三类探针处理这个问题。apiVersion: apps/v1 kind: Deployment metadata: name: web namespace: prod spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: web image: registry.example.com/web:1.0.0 ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 10readinessProbe探活通过后Pod 才被加入 Service 的 Endpoints流量才会进入。这是最重要的流量准入开关。livenessProbe探活失败后kubelet 会重启容器处理“进程还在但服务卡死”的情况。startupProbe用于启动很慢的应用避免启动期间被 readiness 和 liveness 反复误杀。注意探针不是越频繁越好。过短的 periodSeconds 会把瞬时慢请求误判为故障导致 Pod 被反复摘除和重启。建议先观察应用的启动耗时和抖动分布再设定 initialDelaySeconds 和 periodSeconds。4.3 Service 与 Ingress流量如何到达 PodService 是 Kubernetes 内部的稳定访问入口。它通过 selector 找到一组 Pod并提供 ClusterIP。默认的 Service 类型是 ClusterIP只能在集群内部访问。apiVersion: v1 kind: Service metadata: name: web namespace: prod spec: selector: app: web ports: - port: 80 targetPort: 8080 type: ClusterIP集群外流量要进入需要 NodePort、LoadBalancer 或 Ingress。Ingress 不是真正的负载均衡器它只是一套路由规则真正的转发逻辑由 Ingress Controller 执行。最常见的 Nginx Ingress Controller本质上就是把 Nginx 装进集群再监听 Service Endpoints 变化动态更新 upstream 配置。所以生产链路里经常会看到这样的分工Nginx 负责路由规则Service 负责选 PodNginx Ingress Controller 负责把两者衔接起来。4.4 HPA按负载水平扩展副本Kubernetes 提升并发的核心手段是横向扩容。HPA 可以根据指标自动调整副本数。apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web-hpa namespace: prod spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web minReplicas: 3 maxReplicas: 20 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60这段配置的含义是当 Deployment 里 Pod 的平均 CPU 使用率超过 60% 时HPA 增加副本最多到 20低于阈值后缩回最少保留 3。HPA 生效依赖集群部署了 metrics-server并且kubectl get hpa能看到指标数据。生产环境还可以基于自定义指标扩容比如队列长度、RPS 或延迟。扩容不是即时完成的Pod 从启动、探针通过到接收流量需要时间所以在流量突增场景下要预留足够的余量或配合预测扩容。5. 三层组合从用户请求到业务 Pod 的完整链路5.1 三者不是替换关系而是分层协作对比维度F5 BIG-IPNginxKubernetes工作层次网络入口偏 L4/L7七层反向代理应用编排与调度部署形态专用硬件或专用虚机软件进程集群平台提升并发的手段硬件转发、连接加速、DSR事件驱动、多 Worker、连接复用Pod 水平扩容健康检查方式主动 Monitor可配置协议和路径开源版被动检查Plus 支持主动检查readiness/liveness/startup 探针故障转移粒度Pool 成员设备主备切换upstream 节点摘除Pod 重建、重新调度典型适用场景机房入口、超大流量、统一安全策略域名路由、URL 路由、缓存、限流应用生命周期、弹性伸缩、多副本管理故障影响范围入口中断影响所有业务路由中断后端可能仍健康控制面异常时已运行 Pod 受影响较小从这张表可以看出来三个工具不在同一条赛道上。F5 是流量入口的守门员Nginx 是请求路由的分发员Kubernetes 是应用实例的调度员。5.2 一条典型的生产链路用户请求 - DNS / GSLB - F5 VIPTLS 卸载、入口策略、大并发承接 - Nginx Ingress Controller域名路由、URL 路由、限流 - Service选择健康 Pod 的 Endpoints - Pod / 容器实例业务代码在这条链路里每一层都解决一个具体问题F5 解决入口的集中接入、大流量承接和网络层高可用。Nginx Ingress Controller 解决“外部域名/路径”到“集群内 Service”的映射。Service 解决“一组 Pod 的稳定访问入口”和“Pod 摘除后的流量变更”。Deployment 和 HPA 解决“副本数是否足够”“是否健康”“是否自动扩容”。5.3 什么时候可以省略某一层架构设计不是越多层越好。是否需要 F5、Nginx、Kubernetes 同时存在取决于规模。单机或少量实例只用一个 Nginx 反代业务进程就足够。容器化但规模中等只用 Kubernetes Ingress 或云上负载均衡即可不需自建 F5。企业级集中入口流量、安全和合规要求高时F5 这类专用网关才值得引入。云上部署云厂商的负载均衡产品可以承担类似 F5 的入口职责不一定需要采购硬件设备。省略某一层的前提是被省略的能力有明确替代者并且团队清楚替代者在并发和可用性方面的边界。6. 常见坑、排查路径和上线检查清单6.1 至少要知道这几个常见坑问题现象常见原因检查方式处理建议滚动更新后仍有请求打到旧 Pod只有 liveness 探针没有 readiness或 readiness 检查路径错误kubectl get pod查看探针状态为业务接口配置 readinessProbe启动慢的应用再加 startupProbeNginx 到后端的连接大量处于 TIME_WAITupstream 未开启 keepalivess -s查看连接状态配置keepalive并设置proxy_http_version 1.1后端某节点已经 500Nginx 仍在持续转发开源版被动健康检查生效慢检查 max_fails 和 fail_timeout调小 fail_timeout或引入主动健康检查和外部拨测F5 把流量发给已故障节点Monitor 间隔过长或探测路径未覆盖真实接口查看 pool member 状态和 Monitor 配置使用 HTTP Monitor 检查真实健康接口间隔不要设置太长外部无法访问服务Service 类型用了 ClusterIPkubectl get svc查看 TYPE按场景选择 ClusterIP、NodePort、LoadBalancer 或 Ingress后端日志全是负载均衡地址看不到客户端 IP未透传 X-Forwarded-For对比源站日志中的 remote_addr每层统一维护 X-Forwarded-For后端从 XFF 解析真实 IP其中探针配置问题是容器化之后最容易踩的。只配 liveness 不配 readiness会导致流量仍然发往未就绪的 Pod只配 readiness 不配 liveness应用卡死后容器不会被重启。两者要配合使用。另一个高发问题是对开源 Nginx 被动健康检查抱有太高期望。被动检查依赖真实请求触发无法做到秒级故障摘除。需要快速摘除时要么使用 Nginx Plus 的主动检查要么利用 Ingress Controller 和 K8s 探针的组合机制。6.2 请求异常时按这个顺序排查排查链路建议从客户端向服务端推进先确认“问题发生在哪一段”再定位根因。客户端验证执行curl -v http://域名/接口确认连接是否建立、TLS 是否正常、响应码是什么。确认 F5 层检查 VIP 是否 enable、pool 是否 up、后端成员是否健康。通过 tmsh 或管理界面查看show ltm pool。确认 Nginx 层查看access.log和error.log关注upstream_response_time、upstream_status确认请求是否转发到后端。确认 Service 层执行kubectl get endpoints svc确认 Endpoints 里是否有健康 Pod。Endpoints 为空说明 Service 选不到 Pod。确认 Pod 层执行kubectl describe pod pod查看探针状态和最近事件执行kubectl logs pod看业务日志。确认扩容策略执行kubectl get hpa看当前副本数和目标指标确认是否因为资源不足导致扩容失败。排查顺序建议从最靠近用户的一端开始。直接跳到 Pod 层看日志经常会在链路前面漏掉真正的问题点比如 Ingress 路由规则写错、Service 端口不匹配、F5 已把节点摘除。6.3 并发可用性上线检查清单在发布一个改动前可以按这份清单逐项确认健康检查路径是否覆盖真实业务接口而不是只检查端口连通。Nginx upstream 是否开启 keepalive超时时间是否符合业务耗时。K8s Deployment 是否配置了 readinessProbe、livenessProbe 和 resource limits。滚动更新策略是否设置了合理的 maxSurge 和 maxUnavailable。HPA 依赖的 metrics-server 是否正常目标指标是否基于真实压测数据。F5 主备配置是否同步pool 成员是否经过拔测验证。日志是否能够按 traceId 跨 F5、Nginx、Pod 串联。压测结果是否留档压测后的缩容和清理是否有自动化脚本。是否有回滚方案镜像版本、配置版本是否能快速恢复到上一个稳定状态。7. 选型与学习建议如果只记住一句结论那就是并发和可用性不是某一个组件单独提供的而是从入口到应用实例每一层共同承担一部分。F5 擅长在入口做高速转发和网络级高可用Nginx 擅长在七层做路由、连接复用和故障摘除Kubernetes 擅长在应用层做自愈、副本管理和水平扩展。它们不是互相淘汰的关系而是不同规模、不同阶段会依次出现的工程能力。对初学者来说最有价值的练习不是分别背三个工具的文档而是搭一套最小环境把它们串起来先用 Nginx 反代两个后端进程观察故障摘除再把后端容器化用 Deployment 和 Service 管理最后把 Nginx 换成 Ingress Controller理解 Ingress 规则到 Endpoints 的变化。等这条链路跑通后再回到入口层思考 F5 类的硬件网关解决了什么纯软件方案解决不了的问题。这样一层一层建立起来的认知会比只记住“F5 比 Nginx 强、K8s 能自动伸缩”这类结论可靠得多。