> 技术文档 > Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践_ingress server-snippet

Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践_ingress server-snippet


个人名片
在这里插入图片描述
🎓作者简介:java领域优质创作者
🌐个人主页:码农阿豪
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[2435024119@qq.com]
📱个人微信:15279484656
🌐个人导航网站:www.forff.top
💡座右铭:总有人要赢。为什么不能是我呢?

  • 专栏导航:

码农阿豪系列专栏导航
面试专栏:收集了java相关高频面试题,面试实战总结🍻🎉🖥️
Spring5系列专栏:整理了Spring5重要知识点与实战演练,有案例可直接使用🚀🔧💻
Redis专栏:Redis从零到一学习分享,经验总结,案例实战💐📝💡
全栈系列专栏:海纳百川有容乃大,可能你想要的东西里面都有🤸🌱🚀

目录

  • Kubernetes Ingress 高级路由:基于客户端 IP 的流量分发实践
    • 引言
    • 1. 问题背景
      • 需求
    • 2. 解决方案
      • 方案 1:使用 `server-snippet` 动态路由
        • 修改后的 Ingress
        • 优点
        • 缺点
      • 方案 2:通过 `configuration-snippet` 限制 IP 访问
        • 修改后的 Ingress
        • 优点
        • 缺点
    • 3. 方案对比
    • 4. 测试验证
      • 测试 1:来自 `10.206.0.50` 的请求
      • 测试 2:来自其他 IP 的请求
    • 5. 扩展思考
      • Q1:如何支持多个 IP 或 IP 段?
      • Q2:能否结合 GeoIP 实现地域路由?
    • 6. 总结

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 需要动态路由(如 IP 段、变量) 高 中 configuration-snippet 固定 IP 访问控制 低 高

推荐优先使用 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 路由方案:

  1. server-snippet:适合动态路由,但维护成本较高。
  2. configuration-snippet:适合固定 IP 访问控制,推荐优先使用。

最终建议:

  • 简单场景 → configuration-snippet
  • 复杂逻辑 → server-snippet + Nginx 变量。

通过合理使用 Ingress 注解,可以实现更精细的流量管理,满足业务需求。