Ingress-Nginx 的任务

前置条件

安装 ingress-nginx

最大连接数

Max-Worker-Connections

请求超时

配置请求超时

会话亲和性(Sticky Sessions)

配置 Sticky Sessions

Header 修改

actionlink
在请求中设置 headerproxy-set-header
在请求中移除 header在请求中设置一个空 header
在响应中设置 header带有 more-set-header 指令的 configuration-snippets
在响应中移除 headerhide-headers

URL 重写

rewrite

HSTS(HTTP Strict Transport Security)

配置 HSTS

限流

配置限流

WAF

modsecurity

转发 Header 控制

x-forwarded-prefix-header

HTTPS

TLS 重新加密并验证后端证书

验证后端 HTTPS 证书

TLS 边缘终止

backend protocol

透传

ssl-passthrough

默认证书

使用以下 YAML 部署带有默认证书的 ingress-nginx

apiVersion: ingress-nginx.alauda.io/v1
kind: IngressNginx
metadata:
  name: demo
spec:
  controller:
    extraArgs:
      default-ssl-certificate: $DEFAULT_CERT_NAMESPACE/$DEFAULT_CERT_NAME

请参阅 default-ssl-certificate

在 IngressNginx 中添加 Pod 注解

添加 Pod 注解

保留源 IP

当流量经过负载均衡器或代理时,由于 NAT(Network Address Translation,网络地址转换),原始客户端 IP 地址可能会丢失。保留源 IP 对以下场景很重要:

  • 访问控制和安全策略
  • 准确的日志记录和分析
  • 按客户端进行限流
  • 基于地理位置的路由

通过 HAProxy Proxy Protocol

工作原理

PROXY protocol 是一种网络协议,用于在代理 TCP 连接时保留客户端连接信息。它通过在 TCP 连接前添加一个 header 来携带原始源 IP 和端口。

流量流程:

  1. 客户端连接到 HAProxy 负载均衡器
  2. HAProxy 在连接前添加包含原始客户端 IP 的 PROXY protocol header
  3. Ingress-Nginx 接收连接并解析 PROXY protocol header
  4. Ingress-Nginx 从 header 中提取真实客户端 IP
  5. 后端应用在 X-Forwarded-ForX-Real-IP headers 中接收到正确的客户端 IP

优点:

  • 适用于任何支持 PROXY protocol 的负载均衡器(HAProxy、AWS NLB 等)
  • 可在多个代理层之间保留源 IP
  • 不影响路由或节点选择

注意事项:

  • 负载均衡器和 Ingress-Nginx 都必须配置为使用 PROXY protocol
  • 启用后,所有流向 Ingress-Nginx 的流量都必须使用 PROXY protocol(混合使用 PROXY 和非 PROXY 流量会导致连接失败)

配置方法

配置 HAProxy 负载均衡器以发送 PROXY protocol headers,然后部署启用了 proxy-protocol 支持的 ingress-nginx:

apiVersion: ingress-nginx.alauda.io/v1
kind: IngressNginx
metadata:
  name: demo
  namespace: ingress-nginx-operator
spec:
  controller:
    config:
      use-proxy-protocol: "true" # enable proxy-protocol support
frontend tcp_front_80
    bind *:80
    mode tcp
    default_backend ingress_tcp_80
    
frontend tcp_front_443
    bind *:443
    mode tcp
    default_backend ingress_tcp_443
    
backend ingress_tcp_80
    mode tcp
    balance roundrobin
    server node1 192.168.133.46:80 check send-proxy-v2
    
backend ingress_tcp_443
    mode tcp
    balance roundrobin
    server node1 192.168.133.46:443 check send-proxy-v2

更多详情请参阅 PROXY protocol 文档

注意:HAProxy 可以使用 TCP 模式转发流量,而无需处理 TLS 证书。由于 PROXY protocol 工作在 TCP 层,你可以让 Ingress-Nginx 直接处理 HTTPS 终止和证书管理,从而无需在 HAProxy 中配置证书。

通过带有 externalTrafficPolicy=Local 的 MetalLB

工作原理

当使用 type: LoadBalancer 的 Kubernetes Service 时,默认行为(externalTrafficPolicy: Cluster)会执行源 NAT,从而将客户端 IP 替换为节点的 IP。将 externalTrafficPolicy: Local 设置为通过以下方式保留源 IP:

  1. 直接路由:流量只会被路由到接收该流量的同一节点上的 Pod
  2. 不进行 SNAT:kube-proxy 不执行源 NAT,从而保留原始客户端 IP
  3. 健康检查:只有本地 Pod 健康的节点才会被纳入负载均衡器池

流量流程:

  1. 客户端连接到 MetalLB 虚拟 IP
  2. MetalLB 将流量直接路由到具有 Ingress-Nginx Pod 的节点
  3. 流量直接到达本地 Ingress-Nginx Pod,不经过 SNAT
  4. Ingress-Nginx 看到真实的客户端 IP
  5. 后端应用在 headers 中接收到正确的客户端 IP

优点:

  • 配置简单,不需要额外协议
  • 原生 Kubernetes 功能
  • 更低的延迟(没有额外的代理跳转)

注意事项:

  • 负载分布不均:流量只能进入拥有本地 Pod 的节点,可能导致负载不均衡
  • Pod 调度:Ingress-Nginx Pod 必须调度到 MetalLB 可以路由到的节点上(使用 nodeSelector 确保对齐)
  • 健康检查行为:如果所有本地 Pod 都不健康,该节点会被完全移出负载均衡

配置方法

部署一个设置了 externalTrafficPolicy: Local 的 ingress-nginx,并确保 Pod 放置与 MetalLB 配置一致:

apiVersion: ingress-nginx.alauda.io/v1
kind: IngressNginx
metadata:
  name: demo
  namespace: ingress-nginx-operator
spec:
  controller:
    service:
      type: LoadBalancer                    # Use MetalLB to provision a LoadBalancer service
      externalTrafficPolicy: Local          # Preserve source IP by routing traffic only to local pods
      annotations:
        metallb.universe.tf/address-pool: demo-pool  # Specify the MetalLB IP address pool to use
    nodeSelector:                           # Schedule pods only on nodes matching these labels. This selector must match the MetalLB address pool's node selector
      ingress-nginx: "true"  

重要nodeSelector 必须与 MetalLB 地址池配置中的节点匹配,以确保 Ingress-Nginx Pod 被调度到能够接收来自 MetalLB 流量的节点上。

更多详情,请参阅 externalTrafficPolicy 文档