如何用Apache代理替代Ingress将本地客户端IP传递至远程Minikube
问题描述
我需要将本地计算机的客户端IP传递到部署在远程Debian 11虚拟机(无GUI)的Minikube集群中。集群内运行MySQL和phpmyadmin服务,我的PHP应用文件存放在phpmyadmin容器的/var/www/html/my_path/路径下。
当前访问方式:
- 通过远程VM的端口转发,本地访问phpmyadmin服务(映射VM的80端口)和Ingress服务(映射VM的443端口)
- 由于NodePort、LoadBalancer、
minikube tunnel均无法正常工作,端口转发是唯一可行的访问方案
问题表现:
PHP应用中获取到的客户端IP始终是127.0.0.1,相关请求头也显示为127.0.0.1:
Client IP Address: 127.0.0.1 X-Real-IP: 127.0.0.1 X-Forwarded-For: 127.0.0.1
已尝试操作:
- 修改Ingress YAML配置
- 调整Ingress Pod内的nginx.conf
- 更换Ingress安装方式(从
minikube addons enable ingress改为Helm安装) - 修改phpmyadmin配套的Ingress及ConfigMap YAML
解决方案
1. 修正远程VM的端口转发配置,保留源IP
SSH本地端口转发(ssh -L)会将客户端源IP替换为VM的127.0.0.1,需改用iptables DNAT转发来保留真实IP:
- 开启VM的IP转发:
echo 1 > /proc/sys/net/ipv4/ip_forward - 获取Ingress Controller的ClusterIP:
kubectl get svc -n kube-system ingress-nginx-controller - 添加iptables DNAT规则(以80端口为例,替换
<INGRESS_CLUSTER_IP>为实际IP):
HTTPS端口(443)重复上述步骤,替换端口号即可。# 将VM的80端口请求转发到Ingress Controller iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination <INGRESS_CLUSTER_IP>:80 # 配置返回流量路由 iptables -t nat -A POSTROUTING -p tcp --dport 80 -d <INGRESS_CLUSTER_IP> -j MASQUERADE
2. 配置Ingress Controller传递真实客户端IP
确保Ingress Controller信任VM的IP,并启用转发头处理:
针对minikube自带Ingress
- 修改kube-system命名空间下的nginx-configuration ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-configuration namespace: kube-system data: use-forwarded-headers: "true" proxy-real-ip-cidr: "<VM_IP>/32" # 替换为远程VM的实际IP,例如192.168.1.100/32 - 重启Ingress Controller Pod:
kubectl rollout restart deployment ingress-nginx-controller -n kube-system
针对Helm安装的Ingress
- 在values.yaml中添加配置:
controller: config: use-forwarded-headers: true proxy-real-ip-cidr: "<VM_IP>/32" - 执行Helm升级:
helm upgrade ingress-nginx ingress-nginx/ingress-nginx -n kube-system -f values.yaml
3. 配置phpmyadmin容器内的Nginx传递真实IP
phpmyadmin容器的Nginx需要将真实IP传递给PHP:
- 进入phpmyadmin Pod:
kubectl exec -it <PHPMYADMIN_POD_NAME> -- bash - 编辑Nginx配置文件(通常为
/etc/nginx/conf.d/default.conf),在location ~ \.php$块中添加:fastcgi_param REMOTE_ADDR $http_x_real_ip; fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for; - 重启容器内的Nginx:
nginx -s reload - (可选)通过ConfigMap挂载修改后的配置文件,实现持久化。
4. 修正PHP获取IP的代码
修复代码中的笔误,并正确解析转发头:
$clientIP = $_SERVER['REMOTE_ADDR']; // 优先读取X-Real-IP,其次是X-Forwarded-For的第一个IP if (isset($_SERVER['HTTP_X_REAL_IP'])) { $clientIP = $_SERVER['HTTP_X_REAL_IP']; } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $clientIP = trim($ips[0]); } echo "<br><br>Client IP Address: " . $clientIP. "<br>"; // 打印所有请求头用于调试 foreach (getallheaders() as $name => $value) { echo "$name: $value <br>"; }
内容的提问来源于stack exchange,提问作者Nikola84
相关产品推荐
相关产品推荐

