Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践_ingress server-snippet
个人名片
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?
- 专栏导航:
码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀
目录
- Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践
Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践
引言
在 Kubernetes 集群中,Ingress 是管理外部访问的核心组件,通常用于 HTTP/HTTPS 路由。默认情况下,Ingress 基于 Host
头或路径(path
)进行流量分发,但在某些场景下,我们可能需要更细粒度的控制,例如:
- 特定 IP 的请求固定路由到某个 Service
- 内部测试流量与生产流量分离
- 基于地理位置或网络环境的动态路由
本文将以一个实际案例为基础,详细介绍如何通过 Nginx Ingress 实现基于客户端 IP 的路由控制,并对比不同方案的优缺点。
1. 问题背景
假设我们有一个 Kubernetes 集群,并通过 Ingress 暴露了多个服务,其配置如下(简化版):
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: liantong-ingress annotations: nginx.ingress.kubernetes.io/proxy-read-timeout: \"180\"spec: rules: - host: ssp.example1.com # 示例域名,已脱敏 http: paths: - backend: service: name: service-a port: 80 - host: ssp.example2.com http: paths: - backend: service: name: service-b port: 80 # 默认规则(无 Host 头时生效) - http: paths: - backend: service: name: default-service port: 80
需求
- 默认情况下,直接访问 Ingress IP(如
10.206.0.49
)会进入default-service
。 - 现在希望来自
10.206.0.50
的请求固定进入zeroone-service
,而其他 IP 仍走默认逻辑。
2. 解决方案
方案 1:使用 server-snippet
动态路由
Nginx Ingress 支持通过 server-snippet
插入自定义 Nginx 配置,我们可以利用 $remote_addr
(客户端 IP)进行动态路由。
修改后的 Ingress
metadata: annotations: nginx.ingress.kubernetes.io/server-snippet: | set $target_backend \"default-service\"; if ($remote_addr = \"10.206.0.50\") { set $target_backend \"zeroone-service\"; } location / { proxy_pass http://$target_backend; }
优点
- 灵活,可支持复杂逻辑(如 IP 段匹配)。
- 不依赖额外的 Ingress 规则。
缺点
- 直接操作 Nginx 变量,调试较复杂。
- 可能影响默认路由逻辑。
方案 2:通过 configuration-snippet
限制 IP 访问
更清晰的方式是单独添加一条规则,并限制仅允许特定 IP 访问。
修改后的 Ingress
spec: rules: # 原有规则... - http: paths: - path: / pathType: Prefix backend: service: name: zeroone-service port: 80 metadata: annotations: nginx.ingress.kubernetes.io/configuration-snippet: | allow 10.206.0.50; deny all; # 默认规则 - http: paths: - backend: service: name: default-service port: 80
优点
- 配置更清晰,易于维护。
- 不影响其他路由规则。
缺点
- 仅适用于简单 IP 过滤,复杂逻辑需结合其他方案。
3. 方案对比
server-snippet
configuration-snippet
推荐优先使用 configuration-snippet
,除非需要复杂路由逻辑。
4. 测试验证
测试 1:来自 10.206.0.50
的请求
curl --interface 10.206.0.50 http://10.206.0.49
预期结果:返回 zeroone-service
的响应。
测试 2:来自其他 IP 的请求
curl http://10.206.0.49
预期结果:返回 default-service
的响应。
5. 扩展思考
Q1:如何支持多个 IP 或 IP 段?
在 configuration-snippet
中可配置多个 allow
:
allow 10.206.0.50;allow 10.206.0.51;deny all;
Q2:能否结合 GeoIP 实现地域路由?
可以,但需额外部署 Nginx GeoIP 模块:
if ($geoip_country_code = \"CN\") { set $target_backend \"china-service\";}
6. 总结
本文通过实际案例,介绍了两种基于客户端 IP 的 Ingress 路由方案:
server-snippet
:适合动态路由,但维护成本较高。configuration-snippet
:适合固定 IP 访问控制,推荐优先使用。
最终建议:
- 简单场景 →
configuration-snippet
。 - 复杂逻辑 →
server-snippet
+ Nginx 变量。
通过合理使用 Ingress 注解,可以实现更精细的流量管理,满足业务需求。