从 NGINX 到 Kubernetes Ingress:现代微服务流量管理实战
一、引言
1. 背景与需求
在传统单体架构中,流量管理相对简单:一个应用直接暴露在外部网络上,通过负载均衡器(如F5或Nginx)实现基本的流量分发。然而,随着微服务架构的普及,服务数量呈指数级增长,传统的“每个服务一个公网IP”的模式变得不可持续。以NodePort为例,每个Service需要占用集群节点的端口,且端口管理复杂;LoadBalancer则依赖云厂商的负载均衡器,成本高昂。
Kubernetes 的出现为服务暴露提供了新的范式:Service 作为服务的抽象,而 Ingress 成为统一的流量入口。通过 Ingress,开发者可以基于 Host、URL 路径等规则将流量路由到不同的后端服务,无需为每个服务分配公网IP。这一设计不仅节省了资源,还简化了运维复杂度。
2. NGINX 与 Ingress 的关系
NGINX 作为经典的反向代理服务器,其高性能和灵活性使其成为 Kubernetes Ingress Controller 的首选实现之一。Kubernetes Ingress 是一种标准接口定义(API),而 NGINX Ingress Controller 是对这一标准的具体实现。它通过监听 Ingress 资源变化,动态生成 NGINX 配置,并实现热更新,从而将 Kubernetes 的声明式配置与 NGINX 的实际流量处理能力结合。
二、核心概念解析
1. NGINX 基础能力
静态资源配置
NGINX 的核心能力在于其静态配置文件(nginx.conf),通过定义 server 和 location 块实现 HTTP/HTTPS 路由和负载均衡。例如:
server {listen 80;server_name example.com;location /api/ {proxy_pass http://backend-service:8080;}
}
这种静态配置在传统架构中已足够灵活,但在 Kubernetes 环境中,动态调整配置的需求催生了 Ingress 机制。
动态模块扩展
NGINX 支持通过 Lua 脚本(OpenResty)或动态模块实现高级功能。例如,使用 Lua 脚本实现请求限流:
-- limit-req.lua
local rate_limit = require "resty.limit.req"
local lim, err = rate_limit.new("my_limit", 100, 1)
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
2. Kubernetes Ingress 核心组件
Ingress 资源定义
Ingress 资源通过 rules 字段定义路由规则,支持基于 Host 和 Path 的匹配。例如:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: my-ingress
spec:rules:- http:paths:- path: /apipathType: Prefixbackend:service:name: api-serviceport:number: 80
- TLS 配置:通过
tls字段绑定证书,实现 HTTPS 终止:tls: - hosts:- example.comsecretName: tls-secret
Ingress Controller 的作用
Ingress Controller 是 Kubernetes 控制平面的一部分,负责监听 Ingress 资源并动态更新反向代理配置。其核心职责包括:
- 监听 Kubernetes API:通过 Informer 机制实时感知 Ingress、Service、Endpoints 的变化。
- 配置生成:将 Ingress 规则转换为 NGINX 配置。
- 热更新:通过
nginx -s reload实现配置平滑切换。
3. NGINX Ingress Controller 的特殊性
定制化适配
NGINX Ingress Controller 通过 ConfigMap 和注解(annotations)实现高度定制化。例如:
- ConfigMap:修改默认配置参数:
apiVersion: v1 kind: ConfigMap metadata:name: nginx-ingress-config
