K8S中應(yīng)用無法獲取用戶真實ip問題排查過程
現(xiàn)象
領(lǐng)導(dǎo)反饋生產(chǎn)環(huán)境的用戶ip有問題。登陸到這個頁面,發(fā)現(xiàn)是所有的用戶ip都是*.*.94.97,這是個內(nèi)部網(wǎng)絡(luò)ip.
排查過程
1 登陸到應(yīng)用前端nginx, 查看nginx的請求日志
*.*.94.97 - - [17/Jul/2024:02:02:54 +0000] "POST /***/notify/my-page HTTP/1.1" 200 182 "/report/home?type=2&id=2612&lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" "*.*.44.200" *.*.94.97 - - [17/Jul/2024:02:02:54 +0000] "POST /***/notify/my-page HTTP/1.1" 200 182 "/home?lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" "*.*.140.102" *.*.94.97 - - [17/Jul/2024:02:02:56 +0000] "POST /***/msg/notify/my-page HTTP/1.1" 200 59 "/user/message/info?lang=zh_CN" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "*.*.52.192"
發(fā)現(xiàn)第一列展示的ip正好是我們的Java應(yīng)用代碼拿到的iP,而真實的ip展示在最后一列
2 查看nginx的日志輸出格式。第一列取的是remote_addr變量,說明這個變量是有問題的 。我們要取的是最后一列http_x_forwarded_for變量
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
3 查看Java代碼獲取客戶ip的邏輯。Java代碼從6個Header變量中依次找可以用的ip。
public static String getClientIP(HttpServletRequest request, String... otherHeaderNames) { String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; if (ArrayUtil.isNotEmpty(otherHeaderNames)) { headers = (String[])ArrayUtil.addAll(new String[][]{headers, otherHeaderNames}); } return getClientIPByHeader(request, headers); }
4 查看nginx傳遞過來了哪些Header變量。nginx傳遞過來了X-Real-IP和X-Forwarded-For,其中X-Real-IP取的是有問題的remote_addr,正好我們Java代碼取到的是這個變量。X-Forwarded-For沒有值。
location ~ ^/(admin-api|rpc-api)/ { client_max_body_size 32m; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://***:30001; }
5 根據(jù)第二步的分析,將remote_addr
修改為http_x_forwarded_for
6 重啟nginx,問題解決
K8S網(wǎng)絡(luò)拓?fù)?/h2>
所有的外部流量一定會通過一個ingress controller進(jìn)入到K8S的內(nèi)部。
ingress controller的一個常見實現(xiàn)是Nginx,正好我們的k8s選擇的就是Nginx。
也就是說我們的業(yè)務(wù)前端nginx前面還有一個nginx。所以我們的前端nginx的remote_addr拿到的是k8s入口ingress的內(nèi)部ip地址。
總結(jié)
用戶請求經(jīng)過兩層nginx轉(zhuǎn)發(fā)才到達(dá)后端java業(yè)務(wù)應(yīng)用。remote_addr僅存儲上一個轉(zhuǎn)發(fā)節(jié)點的ip,所以我們的業(yè)務(wù)應(yīng)用一直拿的是ingress的ip。http_x_forwarded_for存儲的是原始用戶的請求ip。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Centos?8.2?升級內(nèi)核通過elrepo源的方法
這篇文章主要介紹了Centos?8.2?升級內(nèi)核通過elrepo源,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10Google?Kubernetes?Engine?集群實戰(zhàn)詳解
這篇文章主要為大家介紹了Google?Kubernetes?Engine?集群實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08超詳細(xì)的Kubernetes?(k8s)常用命令整理
這篇文章主要介紹了Kubernetes?(k8s)常用命令整理的相關(guān)資料,講解了Kubernetes集群管理、節(jié)點資源查看、Pod管理、部署管理、命名空間管理、服務(wù)負(fù)載均衡、調(diào)試排錯以及備份恢復(fù)等操作的命令,需要的朋友可以參考下2025-03-03k8s?Service?實現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡
這篇文章主要為大家介紹了k8s?Service?實現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡的工作原理及使用方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Rainbond功能架構(gòu)及應(yīng)用管理官方文檔介紹
這篇文章主要為大家介紹了Rainbond功能機(jī)構(gòu)及使用官方文檔,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04