文档首页> 云容器引擎 CCE> 最佳实践> 网络> 不同场景下容器内获取客户端源IP
更新时间:2023-09-27 GMT+08:00
分享

不同场景下容器内获取客户端源IP

在容器化场景下,客户端和容器服务器之间可能存在多种不同形式的代理服务器,外部请求在经过多次转发后,客户端源IP无法透传至容器,导致容器中的业务无法获取到客户端真实的源IP。

场景介绍

图1 容器中获取源IP

七层转发:

Ingress:应用在七层访问时,客户端源IP默认保存在HTTP头部的“X-Forwarded-For”字段,无需其他操作。

  • ELB型:自研ELB型Ingress基于弹性负载均衡服务ELB实现公网和内网(同一VPC内)的七层网络访问。
  • Nginx型:基于nginx-ingress插件实现七层网络访问,后端服务支持ClusterIP和NodePort类型。

四层转发:

  • 负载均衡:ELB访问方式,是通过弹性负载均衡ELB产品来实现负载均衡。共享型负载均衡四层监听器(TCP/UDP)支持开启“获取客户端IP”功能。而独享型负载均衡的四层监听器(TCP/UDP)默认开启源地址透传功能,无需手动开启。
  • 节点访问:NodePort访问方式,是将容器端口映射到节点端口,如果“服务亲和”选择“集群级别”需要经过一次服务转发,无法实现获取客户端源IP,而“节点模式”不经过转发,可以获取客户端源ip。

若已使用Istio服务网格,获取源IP地址的方法请参见服务加入Istio后,如何获取客户端真实源IP?

支持获取源IP地址的场景

由于网络模型差异,CCE在部分使用场景下暂不支持获取源IP,如表1,若在集群使用过程中需要获取源IP,请尽量避免此类场景。表中“-”代表无此场景。

表1 支持获取源IP地址的场景分类

一级分类

二级分类

负载均衡类型

VPC、容器隧道网络模型

云原生网络2.0模型(CCE Turbo集群)

操作指导

七层转发(Ingress)

ELB型

共享型

支持

支持

ELB Ingress

独享型

支持

支持

Nginx型(对接nginx-ingress插件)

共享型

支持

暂不支持

Nginx Ingress

独享型

支持

支持

四层转发(Service)

负载均衡(LoadBalancer)

共享型

支持

暂不支持(使用hostNetwork的工作负载支持)

负载均衡( LoadBalancer )

独享型

支持

支持

节点访问(NodePort)

-

支持

暂不支持(使用hostNetwork的工作负载支持)

节点访问 ( NodePort )

ELB Ingress

对于ELB Ingress(即使用HTTP/HTTPS协议),ELB默认会开启获取客户端源IP,无需其他操作。

真实的来访者IP会被负载均衡放在HTTP头部的X-Forwarded-For字段,格式如下:

X-Forwarded-For: 来访者真实IP, 代理服务器1-IP,  代理服务器2-IP, ...

当使用此方式获取来访者真实IP时,获取的第一个地址就是来访者真实IP。

Nginx Ingress

对于Nginx Ingress,开启获取源IP的方式如下:

云原生网络2.0模型下(即CCE Turbo集群),Ingress开启对接nginx-ingress插件时使用共享型ELB暂不支持获取源IP,参见支持获取源IP地址的场景。如需获取源IP,请卸载nginx-ingress插件并在重新安装时使用独享型ELB。

  1. 以Nginx工作负载为例,未配置源IP访问前,使用以下命令查看访问日志,其中nginx-c99fd67bb-ghv4q为Pod名称:

    kubectl logs nginx-c99fd67bb-ghv4q

    回显如下:

    ...
    10.0.0.7 - - [17/Aug/2023:01:30:11 +0000] "GET / HTTP/1.1" 200 19 "http://114.114.114.114:9421/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203" "100.125.**.**"

    其中100.125.**.**为负载均衡的地址段,说明流量经过负载均衡转发。

  2. 前往ELB控制台,开启ELB实例对应监听器的“获取客户端IP”功能。独享型ELB默认开启源地址透传功能,无需手动开启。

    1. 登录弹性负载均衡ELB的管理控制台。
    2. 在管理控制台左上角单击图标,选择区域和项目。
    3. 选择“服务列表 > 网络 > 弹性负载均衡”。
    4. 在“负载均衡器”界面,单击需要操作的负载均衡名称。
    5. 切换到“监听器”页签,单击需要修改的监听器名称右侧的“编辑”按钮。如果存在修改保护,请在监听器基本信息页面中关闭修改保护后重试。
    6. 开启“获取客户端IP”开关。
      图2 开启开关

  3. 编辑nginx-ingress插件,在nginx配置参数处,需要添加的配置字段和信息(配置参数范围请参考社区文档)。配置完成后,更新插件。

    {
        "enable-real-ip": "true",
        "forwarded-for-header": "X-Forwarded-For",
        "proxy-real-ip-cidr": "100.125.0.0/16",
        "keep-alive-requests": "100"
    }

    proxy-real-ip-cidr参数为代理服务器的网段。

    • 共享型负载均衡的IP地址段 100.125.0.0/16(100.125.0.0/16是负载均衡服务保留地址,其他用户无法分配到该网段内,不会存在安全风险)和高防IP地址段。
    • 独享型负载均衡需要添加ELB实例关联的VPC子网网段。

    详情请参见如何获取来访者的真实IP?

  4. 重新访问工作负载,并查看新增的访问日志如下:

    ...
    10.0.0.7 - - [17/Aug/2023:02:43:11 +0000] "GET / HTTP/1.1" 304 0 "http://114.114.114.114:9421/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203" "124.**.**.**"

    显示成功获取到客户端源IP。

负载均衡( LoadBalancer )

负载均衡( LoadBalancer )的Service模式下,不同类型的集群获取源IP的场景不一,部分场景下暂不支持获取源IP,参见支持获取源IP地址的场景
  • CCE集群(VPC、容器隧道网络模型):使用共享型和独享型ELB均支持获取源IP。
  • CCE Turbo集群(云原生网络2.0模型):使用独享型ELB时支持获取源IP;使用共享型ELB时,仅开启hostNetwork的工作负载支持获取源IP。

VPC、容器隧道网络模型

开启获取源IP的步骤如下:

  1. 在CCE控制台创建负载均衡类型的Service,服务亲和选择“节点级别”而不是“集群级别”。

  2. 前往ELB控制台,开启ELB实例对应监听器的“获取客户端IP”功能。独享型ELB默认开启源地址透传功能,无需手动开启。

    1. 登录弹性负载均衡ELB的管理控制台。
    2. 在管理控制台左上角单击图标,选择区域和项目。
    3. 选择“服务列表 > 网络 > 弹性负载均衡”。
    4. 在“负载均衡器”界面,单击需要操作的负载均衡名称。
    5. 切换到“监听器”页签,单击需要修改的监听器名称右侧的“编辑”按钮。如果存在修改保护,请在监听器基本信息页面中关闭修改保护后重试。
    6. 开启“获取客户端IP”开关。
      图3 开启开关

云原生网络2.0模型(CCE Turbo集群)

云原生网络2.0模型下,使用共享型ELB创建负载均衡时服务亲和无法设置服务亲和选项为“节点级别”,因此无法获取源IP。如需获取源IP,必须使用独享型ELB,外部访问可不经过转发直通容器。

独享型ELB默认开启源地址透传,无需前往ELB控制台手动开启“获取客户端IP”开关,只需要在CCE控制台创建ENI负载均衡时选择独享型负载均衡,即可获取客户端源IP。

节点访问 ( NodePort )

节点访问(NodePort)类型的Service的服务亲和需选择“节点级别”而不是“集群级别”,即Service的spec.externalTrafficPolicy需要设置为Local

云原生网络2.0模型集群中使用节点访问(NodePort)类型的Service时,仅开启hostNetwork的工作负载支持获取源IP。

图4 服务亲和选择节点级别
分享:

    相关文档

    相关产品