Kubernetes Ingress获取用户真实IP

概述

在使用Kubernetes的Ingress时,获取用户的真实IP地址是一个常见的需求。由于Ingress控制器在处理请求时会执行代理操作,因此默认情况下,后端服务只能获得Ingress控制器的IP地址,而无法获取到用户的真实IP地址。本文将介绍如何通过一系列的步骤来实现获取用户真实IP的功能。

流程图

flowchart TD
    A[用户请求] --> B{Ingress控制器}
    B --> C[Nginx配置]
    C --> D[反向代理]
    D --> E[后端服务]
    E --> F[获取真实IP]

步骤

步骤 操作 代码示例 说明
1 安装Ingress控制器 无需代码 使用合适的Ingress控制器进行安装,如Nginx Ingress Controller或Traefik等
2 配置Ingress资源 无需代码 在Kubernetes集群中创建Ingress资源,并将其与后端服务关联
3 修改Nginx配置 无需代码 针对Nginx Ingress Controller,需要修改Nginx的配置文件
4 添加配置注解 无需代码 在Ingress资源的metadata中添加配置注解,以指定是否使用真实IP
5 重启Ingress控制器 无需代码 重启Ingress控制器以使配置生效
6 后端服务获取真实IP 无需代码 在后端服务中通过读取HTTP请求的特定Header来获取真实IP

具体操作

1. 安装Ingress控制器

根据你的需求选择合适的Ingress控制器进行安装,这里以Nginx Ingress Controller为例。可以使用如下的命令来安装Nginx Ingress Controller:

$ kubectl apply -f 

2. 配置Ingress资源

在Kubernetes集群中创建Ingress资源,并将其与后端服务关联。例如,创建一个名为 example-ingress 的Ingress资源,并将其与后端服务 example-service 关联:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

3. 修改Nginx配置

针对Nginx Ingress Controller,需要修改Nginx的配置文件以支持获取真实IP。找到Nginx配置文件所在的位置(例如:/etc/nginx/nginx.conf),并修改配置文件中的 http 部分,添加如下配置:

real_ip_header X-Real-IP;
set_real_ip_from 0.0.0.0/0;

4. 添加配置注解

在Ingress资源的metadata中添加配置注解,以指定是否使用真实IP。例如,在 example-ingress 中添加如下注解:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/enable-real-ip: "true"
spec:
  ...

5. 重启Ingress控制器

重启Ingress控制器以使配置生效。可以通过如下的命令重启Nginx Ingress Controller:

$ kubectl rollout restart deployment ingress-nginx-controller -n ingress-nginx

6. 后端服务获取真实IP

在后端服务中通过读取HTTP请求的特定Header来获取真实IP。例如,在使用Go语言编写的后端服务中,可以使用如下代码来获取真实IP:

package main

import (
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		// 获取真实IP
		realIP := r.Header.Get("X-Real-IP")
		log.Printf("Real IP: %s", realIP)