国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

聊聊部署在K8S的項目如何獲取客戶端真實IP

這篇具有很好參考價值的文章主要介紹了聊聊部署在K8S的項目如何獲取客戶端真實IP。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

最近部門有個需求,需要對一些客戶端IP做白名單,在白名單范圍內(nèi),才能做一些業(yè)務(wù)操作。按我們的部門的一貫做法,我們會封裝一個client包,提供給業(yè)務(wù)方使用。(注: 我們的項目是運行在K8S上)本以為這是一個不是很難的功能,部門的小伙伴不到一天,就把功能實現(xiàn)了,他通過本地調(diào)試,可以獲取到正確的客戶端IP,但是發(fā)布到測試環(huán)境,發(fā)現(xiàn)獲取到的客戶端IP一直是節(jié)點的IP,后面那個小伙伴排查了很久,一直沒頭緒,就找到我?guī)兔σ恢迸挪橐幌?。今天文章主要就是來?fù)盤這個過程

排查過程

首先先排查了一下他獲取客戶端IP的實現(xiàn)邏輯

public class IpUtils {
    private static Logger logger = LoggerFactory.getLogger(IpUtils.class);
    private static final String IP_UTILS_FLAG = ",";
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST_IP = "0:0:0:0:0:0:0:1";
    private static final String LOCALHOST_IP1 = "127.0.0.1";

    /**
     * 獲取IP地址
     *
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            //以下兩個獲取在k8s中,將真實的客戶端IP,放到了x-Original-Forwarded-For。而將WAF的回源地址放到了 x-Forwarded-For了。
            ip = request.getHeader("X-Original-Forwarded-For");
            System.out.println("X-Original-Forwarded-For:" + ip);
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Forwarded-For");
            }
            //獲取nginx等代理的ip
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("x-forwarded-for");
                System.out.println("x-forwarded-for:" + ip);
            }
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            //兼容k8s集群獲取ip
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                System.out.println("getRemoteAddr:" + ip);
                if (LOCALHOST_IP1.equalsIgnoreCase(ip) || LOCALHOST_IP.equalsIgnoreCase(ip)) {
                    //根據(jù)網(wǎng)卡取本機配置的IP
                    InetAddress iNet = null;
                    try {
                        iNet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        logger.error("getClientIp error: {}", e);
                    }
                    ip = iNet.getHostAddress();
                }
            }
        } catch (Exception e) {
            logger.error("IPUtils ERROR ", e);
        }
        //使用代理,則獲取第一個IP地址
        if (!StringUtils.isEmpty(ip) && ip.indexOf(IP_UTILS_FLAG) > 0) {
            ip = ip.substring(0, ip.indexOf(IP_UTILS_FLAG));

        }

        return ip;
    }

}

這邏輯看著貌似沒問題,因為本地調(diào)試可以獲取到正確的客戶端IP,而測試環(huán)境獲取不到,大概率是環(huán)境有問題。于是就把方向轉(zhuǎn)為定位環(huán)境的差異性

環(huán)境定位

測試環(huán)境

我們測試環(huán)境的訪問流程為客戶端–> k8s service nodeport—>pod

通過搜索在https://kubernetes.io/zh-cn/docs/tutorials/services/source-ip/
在這篇文章找到答案。

Kubernetes Service 轉(zhuǎn)發(fā)場景下,無論使用 iptbales 或 ipvs 的負(fù)載均衡轉(zhuǎn)發(fā)模式,轉(zhuǎn)發(fā)時都會對數(shù)據(jù)包做 SNAT,即不會保留客戶端真實源 IP

整體流程

聊聊部署在K8S的項目如何獲取客戶端真實IP

上文的鏈接也貼了解法

聊聊部署在K8S的項目如何獲取客戶端真實IP
具體步驟就是

1、步驟一:業(yè)務(wù)pod的配置調(diào)度到指定節(jié)點

示例

spec:
   nodeName: node1    #指定pod節(jié)點配置
   containers:
      - name: pod-name

2、步驟二:將業(yè)務(wù)的service yaml 默認(rèn)配置的externalTrafficPolicy: Cluster改為 externalTrafficPolicy: Local

示例

spec:
  type: NodePort
  externalTrafficPolicy: Local

3、步驟三:通過指定在pod上的node節(jié)點 + nodeport進(jìn)行訪問

示例

http://node1:nodeport

假設(shè)部署了node1和node2節(jié)點,只能通過node1:nodeport才能訪問到具體業(yè)務(wù),如果通過node2:nodeport,則請求的數(shù)據(jù)包會被拋棄

聊聊部署在K8S的項目如何獲取客戶端真實IP
通過上述的方案,解決了在測試環(huán)境通過service nodeport獲取不到正確客戶端ip的問題

uat環(huán)境

當(dāng)測試環(huán)境沒問題后,將項目發(fā)布到UAT環(huán)境,然后不出意外的話,又出意外了。

uat的訪問流程為 客戶端- -> nginx+keepalive --> ingress --> pod

因為訪問方式不一樣,因此解法又有差異。通過搜索了解到*用戶ip的傳遞依靠的是X-Forwarded-參數(shù)。但是默認(rèn)情況下,ingress是沒有開啟的 因此我們需要開啟。開啟需要如下參數(shù)

聊聊部署在K8S的項目如何獲取客戶端真實IP

  • use-forwarded-headers: 如果設(shè)置為True時,則將設(shè)定的X-Forwarded-* Header傳遞給后端,
    當(dāng)Ingress在L7 代理/負(fù)載均衡器之后使用此選項。如果設(shè)置為 false 時,則會忽略傳入的X-Forwarded-*Header,
    當(dāng) Ingress 直接暴露在互聯(lián)網(wǎng)或者 L3/數(shù)據(jù)包的負(fù)載均衡器后面,并且不會更改數(shù)據(jù)包中的源 IP請使用此選項。
  • forwarded-for-header: 設(shè)置用于標(biāo)識客戶端的原始 IP 地址的 Header字段。默認(rèn)值X-Forwarded-For。如果想修改為自定義的字段名,則可以在configmap的data配置塊下添加:forwarded-for-header: “THE_NAME_YOU_WANT”
  • compute-full-forwarded-for: 將 remote address 附加到 X-Forwarded-For
    Header而不是替換它。當(dāng)啟用此選項后端應(yīng)用程序負(fù)責(zé)根據(jù)自己的受信任代理列表排除并提取客戶端 IP。

詳細(xì)的介紹可以查看官網(wǎng)

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers?

我們在Ingress Nginx Controller 的 Configmap添加如下內(nèi)容

apiVersion: v1
kind: ConfigMap
......
data:
  compute-full-forwarded-for: "true"
  use-forwarded-headers: "true"
  forwarded-for-header:"X-Forwarded-For"

配置后,發(fā)現(xiàn)沒鳥用,沒有效果。后面查了很多資料,發(fā)現(xiàn)網(wǎng)上都是那么配的,后面就覺得是不是nginx - keepalive 這一環(huán)節(jié)出了啥問題,于是就問了一下運維,看他nginx那邊是否有配置X-Forwarded-For,他說沒有,那我就問他能否配置一下,他的回答是因為nginx那邊啟用了 ssl_preread 模塊無法使用X-Forwarded-For
聊聊部署在K8S的項目如何獲取客戶端真實IP
后面就問他能否改下,他回答說是后面公司要采用F5了,到時候在配置一下就好。而他目前事情比較多,沒時間幫我弄這個。

由于業(yè)務(wù)比較趕,運維又沒空搞,于是就和業(yè)務(wù)那邊溝通,采取了折中方案,就是通過自定義請求頭,我們在client包配置了一個屬性,那個屬性用來讓業(yè)務(wù)將白名單ip填進(jìn)去,示例

lybgeek:
  whilte-ips: 192.168.1.1,192.168.2.1

在業(yè)務(wù)項目啟動的時候,client包會自動將配置的白名單塞入請求頭

   header("x-custom-forwarded-for",whilteIps)

服務(wù)端那邊獲取客戶端ip做如下改造

@Slf4j
public final class IPHelper {

    private IPHelper(){}

    private static final String IP_UTILS_FLAG = ",";
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST_IP = "0:0:0:0:0:0:0:1";
    private static final String LOCALHOST_IP1 = "127.0.0.1";


   private static final String[] headersToTry = {
           //在k8s中,將真實的客戶端IP,放到了x-Original-Forwarded-For。而將WAF的回源地址放到了 x-Forwarded-For了。
            "X-Original-Forwarded-For",
            "X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_X_FORWARDED_FOR",
            "HTTP_X_FORWARDED",
            "HTTP_X_CLUSTER_CLIENT_IP",
            "HTTP_CLIENT_IP",
            "HTTP_FORWARDED_FOR",
            "HTTP_FORWARDED",
            "HTTP_VIA",
            "REMOTE_ADDR",
            // 自定義請求頭
            "X-Custom-Forwarded-For",
    };

        /**
         * 獲取用戶的真正IP地址
         *
         * @param request request對象
         * @return 返回用戶的IP地址
         */
         @SneakyThrows
         public static String getIpAddr(HttpServletRequest request) {
             String ip = null;
            for (String header : headersToTry) {
                ip = request.getHeader(header);
                if (StringUtils.hasText(ip) && !UNKNOWN.equalsIgnoreCase(ip)){
                    log.info("hit the target client ip -> 【{}】 by header --> 【{}】",ip,header);
                    return ip;
                }
            }
             //兼容k8s集群獲取ip
             if (org.springframework.util.StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                 ip = request.getRemoteAddr();
                 if (LOCALHOST_IP1.equalsIgnoreCase(ip) || LOCALHOST_IP.equalsIgnoreCase(ip)) {
                     //根據(jù)網(wǎng)卡取本機配置的IP
                     InetAddress iNet = null;
                     try {
                         iNet = InetAddress.getLocalHost();
                     } catch (UnknownHostException e) {
                         log.error("getIpAddr error: {}", e);
                     }
                     ip = iNet.getHostAddress();
                 }
                 log.info("hit the target client ip -> 【{}】 by method 【getRemoteAddr】 ",ip);
             }

             //使用代理,則獲取第一個IP地址
             if (!org.springframework.util.StringUtils.isEmpty(ip) && ip.indexOf(IP_UTILS_FLAG) > 0) {
                 ip = ip.substring(0, ip.indexOf(IP_UTILS_FLAG));
             }
             return ip;
        }





}

其實做的事情,就將原來的工具類稍微重構(gòu)了一下,并加入自定義請求頭X-Custom-Forwarded-For

總結(jié)

這次的復(fù)盤總結(jié)就是很多東西沒那么想當(dāng)然,有些簡單的東西,里面可能也有有坑。當(dāng)遇到跨部門合作時,如果遇到一些不可抗力因素,我們除了向上反饋之外,還要有兜底方案,不然會非常被動文章來源地址http://www.zghlxwxcb.cn/news/detail-500780.html

到了這里,關(guān)于聊聊部署在K8S的項目如何獲取客戶端真實IP的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 第13關(guān) 解決K8s中Ingress Nginx控制器無法獲取真實客戶端IP的問題

    第13關(guān) 解決K8s中Ingress Nginx控制器無法獲取真實客戶端IP的問題

    ------ 課程視頻同步分享在今日頭條和B站 大家好,我是博哥愛運維。 這節(jié)課帶大家探索并分享最全面的解決在使用Kubernetes(K8s)和Ingress-Nginx-Controller中無法獲取客戶端真實IP問題的視頻教程,幫助你快速理解并解決這一問題。 如果我們按下面網(wǎng)絡(luò)架構(gòu)圖,暴露我們服務(wù)到公

    2024年02月03日
    瀏覽(24)
  • nginx 多層代理 + k8s ingress 后端服務(wù)獲取客戶真實ip 配置

    nginx 多層代理 + k8s ingress 后端服務(wù)獲取客戶真實ip 配置

    1.nginx http 七層代理 修改命令空間: namespace: nginx-ingress : configmap:nginx-configuration 添加如上配置 compute-full-forwarded-for: “true” forwarded-for-header: X-Forwarded-For use-forwarded-headers: “true” 即可; 2. nginx stream 4層代理: nginx 需要編譯增加–with-stream_realip_module模塊,然后對應(yīng)的server塊

    2024年02月08日
    瀏覽(20)
  • Kubernetes(k8s)實戰(zhàn):Kubernetes(k8s)部署Springboot項目

    Kubernetes(k8s)實戰(zhàn):Kubernetes(k8s)部署Springboot項目

    wordpress是用于快速搭建博客系統(tǒng)。 該yaml文件創(chuàng)建一個mysql,并且生成一個service,service對外暴露的端口是3306 我們發(fā)現(xiàn),搭建成功了,用瀏覽器訪問192.168.56.101:30493,發(fā)現(xiàn)訪問成功了! 在集群中,pod之間可以通過service 的name進(jìn)行訪問,不僅僅是ip,這就意味著,service中不僅幫

    2024年02月12日
    瀏覽(32)
  • 【k8s完整實戰(zhàn)教程4】使用kubesphere部署項目到k8s

    【k8s完整實戰(zhàn)教程4】使用kubesphere部署項目到k8s

    系列文章:這個系列已完結(jié),如對您有幫助,求點贊收藏評論。 讀者寄語: 再小的帆,也能遠(yuǎn)航! 【k8s完整實戰(zhàn)教程0】前言 【k8s完整實戰(zhàn)教程1】源碼管理-Coding 【k8s完整實戰(zhàn)教程2】騰訊云搭建k8s托管集群 【k8s完整實戰(zhàn)教程3】k8s集群部署kubesphere 【k8s完整實戰(zhàn)教程4】使用

    2023年04月18日
    瀏覽(64)
  • k8s 部署Jenkins項目

    k8s 部署Jenkins項目

    要求:當(dāng)前集群配置了storageClass,并已指定默認(rèn)的storageClass,一般情況下,創(chuàng)建的storageClass即為默認(rèn)類 指定默認(rèn)storageClass的方式 1.1 部署helm 1.2 部署jenkins 1.3 檢查 jenkins 1.4 配置訪問 3.1 準(zhǔn)備ruoyi數(shù)據(jù) 3.2 準(zhǔn)備k8s證書 3.3 準(zhǔn)備maven配置文件 3.4 配置釘釘插件 在系統(tǒng)管理的下方有未

    2024年01月21日
    瀏覽(57)
  • K8s部署PHP項目

    ? ? ? ? 前端時間PHP項目部署升級需要 ,需要把Laravel開發(fā)的項目部署K8s上,下面以laravel項目為例,講解采用yaml文件方式部署項目。 一、部署步驟 Dockerfile是一個用來構(gòu)建鏡像的文本文件,在容器運行時,需要把項目文件和項目運行所必須的組件安裝其中。 Kubernetes使用命名

    2024年02月05日
    瀏覽(18)
  • k8s部署微服務(wù)項目

    k8s部署微服務(wù)項目

    之前用docker-compose部署微服務(wù)項目,但是只能單節(jié)點的(那你用微服務(wù)架構(gòu)干啥?),所以想搞一下k8s集群,網(wǎng)上找了下資料沒有視頻專門講這一塊,自己找了很多資料,搞了蠻長時間的,所以記錄一下 1.安裝k8s和管理界面kuboard 高版本的k8s已經(jīng)拋棄了docker,容器使用的話要安裝1

    2023年04月22日
    瀏覽(16)
  • k8s集群部署springboot項目

    k8s集群部署springboot項目

    本篇,我們將基于k8s集群,模擬一個比較接近實際業(yè)務(wù)的使用場景,使用k8s集群部署一個springboot的項目,我們的需求是: 部署SpringBoot項目到阿里云服務(wù)器?; 基于容器打包,推送私有鏡像倉庫 ; 采用K8S集群部署,對外暴露服務(wù),pod副本擴容,公網(wǎng)可以訪問 ; 基于阿里云服

    2024年02月02日
    瀏覽(24)
  • 【Go】K8s 管理系統(tǒng)項目[Jenkins Pipeline K8s環(huán)境–應(yīng)用部署]

    【Go】K8s 管理系統(tǒng)項目[Jenkins Pipeline K8s環(huán)境–應(yīng)用部署]

    考慮到實際工作中前后端可能是不同的同學(xué)完成,一般Api部分完成后改動會比較小,web部分改動會比較頻繁.于是將api和web分了2個pipeline實現(xiàn) docker目錄存放鏡像構(gòu)建相關(guān)文件 k8s-plantform-api 存放api部分代碼 Jenkinsfile用作pipeline配置 yaml用作生成k8s下k8s-plantform-api相關(guān)資源 1.1.1 docker目

    2023年04月08日
    瀏覽(38)
  • k8s的jenkins部署java項目到k8s集群cicd持續(xù)集成

    k8s的jenkins部署java項目到k8s集群cicd持續(xù)集成

    k8s1.16.0-k8s的jenkins部署java項目到k8s集群cicd(ci成,cd手動部署的) 注意: 本文檔只是實現(xiàn)了ci,cd是通過ci生成的鏡像,再手工再k8s-master執(zhí)行的部署(只因pod部署的jenkins連接k8s的認(rèn)證不知怎么操作,若jenkins是單獨部署在k8s-master機器上,能直接在master執(zhí)行kubectl命令就沒這個問題了

    2024年02月03日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包