在 Kubernetes 集群中,Ingress 是管理外部访问的核心组件,通常用于 HTTP/HTTPS 路由。默认情况下,Ingress 基于 Host 头或路径(path)进行流量分发,但在某些场景下,我们可能需要更细粒度的控制,例如:
本文将以一个实际案例为基础,详细介绍如何通过 Nginx Ingress 实现基于客户端 IP 的路由控制,并对比不同方案的优缺点。
假设我们有一个 Kubernetes 集群,并通过 Ingress 暴露了多个服务,其配置如下(简化版):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
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: 8010.206.0.49)会进入 default-service。10.206.0.50 的请求固定进入 zeroone-service,而其他 IP 仍走默认逻辑。server-snippet 动态路由Nginx Ingress 支持通过 server-snippet 插入自定义 Nginx 配置,我们可以利用 $remote_addr(客户端 IP)进行动态路由。
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;
}configuration-snippet 限制 IP 访问更清晰的方式是单独添加一条规则,并限制仅允许特定 IP 访问。
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方案 | 适用场景 | 复杂度 | 可维护性 |
|---|---|---|---|
server-snippet | 需要动态路由(如 IP 段、变量) | 高 | 中 |
configuration-snippet | 固定 IP 访问控制 | 低 | 高 |
推荐优先使用 configuration-snippet,除非需要复杂路由逻辑。
10.206.0.50 的请求curl --interface 10.206.0.50 http://10.206.0.49预期结果:返回 zeroone-service 的响应。
curl http://10.206.0.49预期结果:返回 default-service 的响应。
在 configuration-snippet 中可配置多个 allow:
allow 10.206.0.50;
allow 10.206.0.51;
deny all;可以,但需额外部署 Nginx GeoIP 模块:
if ($geoip_country_code = "CN") {
set $target_backend "china-service";
}本文通过实际案例,介绍了两种基于客户端 IP 的 Ingress 路由方案:
server-snippet:适合动态路由,但维护成本较高。configuration-snippet:适合固定 IP 访问控制,推荐优先使用。最终建议:
configuration-snippet。server-snippet + Nginx 变量。通过合理使用 Ingress 注解,可以实现更精细的流量管理,满足业务需求。