You need to enable JavaScript to run this app.
导航

通过 Ingress 获取真实客户端 IP 地址

最近更新时间2023.09.01 16:41:31

首次发布时间2022.11.22 10:26:39

本文主要介绍外部请求通过弹性负载均衡(CLB)访问工作负载时,工作负载后端 Pod 获取外部请求的真实 IP 地址的方法。

Flannel 容器网络模型集群

  1. 登录 容器服务控制台
  2. 单击左侧导航栏中的 集群,找到目标集群,然后单击集群名称,进入集群管理页面。
  3. 配置 ingress-nginx-controller 对应服务(Service)的转发外部流量策略(Spec.externalTrafficPolicy)为 Local

    说明

    • ingress-nginx-controller 是安装 ingress-nginx 组件后,生成的 Ingress 控制器对应的 Service。
    • Flannel 容器网络模型的集群,其后端业务 Pod 获取客户端真实 IP 时,需要将 LoadBalancer Service 的 externalTrafficPolicy 设置为 Local,用于将节点的 IPVS 只转发给本节点的 Nginx Ingress Pod。
    1. 在集群管理页面的左侧导航栏中,选择 服务与路由 > 服务
    2. kube-system 命名空间下,找到 ingress-nginx-controller,并在对应 操作 列中选择... > 编辑 Yaml
      alt
    3. 修改 Spec.externalTrafficPolicy(转发外部流量策略)的值为 Local,然后单击 确定 保存配置。
      alt
  4. 配置 ingress-nginx-controller 对应配置项(ConfigMap),增加获取真实客户端 IP 时必要的字段。
    1. 在集群管理页面的左侧导航栏中,选择 配置管理 > 配置项
    2. kube-system 命名空间下,找到 ingress-nginx-controller,并在对应 操作 列中选择... > 编辑 Yaml
      alt
    3. 在配置项中的 data 代码块中增加如下三行字段,然后单击 确定 保存配置。
      alt
      代码片段如下所示。
      apiVersion: v1
      kind: ConfigMap
      data:
        use-forwarded-headers: "true"
        compute-full-forwarded-for: "true"
        forwarded-for-header: X-Forwarded-For
      

VPC-CNI 容器网络模型集群

  1. 登录 容器服务控制台
  2. 单击左侧导航栏中的 集群,找到目标集群,然后单击集群名称,进入集群管理页面。
  3. 配置 ingress-nginx-controller 对应配置项(ConfigMap),增加获取真实客户端 IP 时必要的字段。
    1. 在集群管理页面的左侧导航栏中,选择 配置管理 > 配置项
    2. kube-system 命名空间下,找到 ingress-nginx-controller,并在对应 操作 列中选择... > 编辑 Yaml
      alt
    3. 在配置项中的 data 代码块中增加如下三行字段,然后单击 确定 保存配置。
      alt
      代码片段如下所示。
      apiVersion: v1
      kind: ConfigMap
      data:
        use-forwarded-headers: "true"
        compute-full-forwarded-for: "true"
        forwarded-for-header: X-Forwarded-For
      

验证结果

准备工作

本文通过 Nginx 镜像模拟真实客户端,因此验证操作前,您还需要准备如下工作:

  • 在目标集群中安装 ingress-nginx 组件。详细操作,请参见 安装组件
  • 在镜像仓库中上传开源 Nginx 镜像,用于验证操作结果时模拟后端服务。详细操作,请参见 推送和拉取镜像

    说明

    若您的镜像仓库中已存在 Nginx 镜像,无需重复上传。

  • 准备一台可以访问公网的执行机器,模拟外部真实客户端。该客户端必须在 Ingress 所在集群外。

    说明

    您可以创建一个可以访问公网的云服务器(ECS)实例,作为执行机器。详细操作,请参见 通过向导购买实例

验证步骤

请按照如下步骤,验证是否已获取真实客户端 IP。

说明

Flannel 容器网络模型的集群,将 LoadBalancer Service 的 externalTrafficPolicy 设置为 Local 后,若节点上没有 Nginx Ingress Pod,则该 LoadBalancer 地址无法被访问且会被会被当作 Service 的扩展 IP 地址,被 IPVS 拦截并转发,发生网络不通的问题。相关问题的更多信息,请参见 社区文档

因此下文使用无状态负载模拟后端服务的 Nginx Ingress Pod。

  1. 使用本文上方 准备工作 中已上传的 Nginx 镜像,创建用于模拟后端服务的无状态负载。详细操作,请参见 创建无状态负载
    alt
  2. 创建 LoadBalancer 类型的服务(Service),绑定步骤 1 中创建的无状态负载。详细操作,请参见 负载均衡(LoadBalancer)
    alt
  3. 创建路由规则(Ingress),关联步骤 2 中创建的 LoadBalancer 类型服务。详细操作,请参见 配置 Nginx Ingress

    注意

    路由规则的所属命名空间,需要与步骤 1 中创建的无状态负载所在的命名空间保持一致。

    alt
  4. 登录本文上方 准备工作 中准备的可以访问公网的执行机器。
  5. 执行如下命令,访问 Ingress 上配置的域名。
    curl -H "Host: ${Your-HostName}" http://${Your_LB_Service_Externalport}
    
    其中,将${Your-HostName}替换为您在步骤 3 中创建路由规则时配置的 转发规则域名(例如nginx.com);将${Your_LB_Service_Externalport}替换为您在步骤 2 中创建的 LoadBalancer 类型服务的 外部端点(例如180.**.**.**)。则完整的命令如下:
    curl -H "Host: nginx.com" http://180.**.**.**
    
    预期返回结果如下图所示。
    alt
  6. 到步骤 1 中创建的无状态负载详情页面 日志 页签,查看模拟后端服务的 Nginx Pod 日志,可以看到日志的 X-Forwarded-For IP 即为真实客户端 IP。
    alt