天天看點

kubernetes的service開啟NodePort在主控端無法找到監聽端口?

作者:雲原生驿站

前言

不知道一直在玩k8的朋友有沒有發現一個問題,開啟了

ipvs

之後,

service

開啟

NodePort

之後,在主控端壓根找不到該監聽端口,本篇文章将帶着大家解開這層面紗。

iptable回顧

四表五鍊的處理順序是先作用鍊,再作用表!!!

四表五鍊的處理順序是先作用鍊,再作用表!!!

四表五鍊的處理順序是先作用鍊,再作用表!!!

鍊的通路順序是:

  1. 資料包到達網卡時,首先經過

    PREROUTING

    鍊,進行預路由處理。
  2. 然後,在經過

    PREROUTING

    鍊後,根據路由規則确定目标位址和接口,選擇目标主機或者進行轉發。
  3. 如果資料包是發往本地主機的,那麼接下來會經過INPUT鍊,進行輸入資料包的處理。
  4. 如果資料包是轉發的,那麼接下來會經過

    FORWARD

    鍊,進行資料包的轉發處理。
  5. 如果資料包是由本地主機發出的,那麼接下來會經過

    OUTPUT

    鍊,進行輸出資料包的處理。
  6. 最後,資料包離開網卡之前,會經過

    POSTROUTING

    鍊,進行後路由處理。

每條鍊上有什麼表呢?

  1. PREROUTING鍊:
    • raw表:用于處理連接配接跟蹤之前的資料包,可以修改資料包的源位址。
    • mangle表:用于處理資料包的特殊修改,如修改TTL(生存時間)字段、标記資料包等。
  2. INPUT鍊:
    • mangle表:用于處理資料包的特殊修改。
    • nat表:用于網絡位址轉換,通常用于

      DNAT

      (目标位址轉換)和

      MASQUERADE

      (源位址轉換)。
  3. FORWARD鍊:
    • mangle表:用于處理資料包的特殊修改。
    • filter表:用于過濾資料包,決定是否允許資料包通過路由轉發。
  4. OUTPUT鍊:
    • raw表:用于處理連接配接跟蹤之前的資料包,可以修改資料包的源位址。
    • mangle表:用于處理資料包的特殊修改。
    • nat表:用于網絡位址轉換,通常用于

      SNAT

      (源位址轉換)。
  5. POSTROUTING鍊:
    • mangle表:用于處理資料包的特殊修改。
    • nat表:用于網絡位址轉換,通常用于

      SNAT

      (源位址轉換)和

      MASQUERADE

      (源位址轉換)。

這些表的作用是在五個主要的鍊上進行資料包處理和轉換。根據規則的配置,

iptables

可以對資料包進行源位址轉換、目标位址轉換、标記、過濾等操作,進而實作網絡流量的控制和管理。每個鍊上可以同時使用多個表,可以根據需求組合不同的規則來實作複雜的網絡處理邏輯。

kube-proxy定義的鍊條

除了

iptable

本身的四表五鍊之外,

kube-proxy

也自定義了一系列鍊條,這裡我們隻基于

NodePort

并且開啟

ipvs

kube-proxy

進行讨論

[root@openeuler-controlplane-jtzv-0 ~]# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* cali:6gwbT8clXdHdC1b1 */
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
CNI-HOSTPORT-DNAT all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
......
Chain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-MARK-MASQ all -- !10.233.64.0/18 0.0.0.0/0 /* Kubernetes service cluster ip + port for masquerade purpose */ match-set KUBE-CLUSTER-IP dst,dst
KUBE-NODE-PORT all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 match-set KUBE-CLUSTER-IP dst,dst
......
Chain KUBE-NODE-PORT (1 references)
target prot opt source destination
KUBE-MARK-MASQ tcp -- 0.0.0.0/0 0.0.0.0/0 /* Kubernetes nodeport TCP port for masquerade purpose */ match-set KUBE-NODE-PORT-TCP dst
.....
           

在這裡我們可以看到一條鍊 PREROUTING ➡️ KUBE-SERVICES ➡️ KUBE-NODE-PORT

KUBE-NODE-PORT

鍊條的内容解析如下

  1. 鍊名稱:

    KUBE-NODE-PORT

  2. 目标:

    KUBE-MARK-MASQ

    ,表示如果規則比對成功,則執行名為

    KUBE-MARK-MASQ

    的目标規則。
  3. 協定:

    tcp

    ,表示該規則僅處理 TCP 協定的流量。
  4. 源位址 (

    source

    ):

    0.0.0.0/0

    ,表示任何源位址都會被比對。
  5. 目标位址 (

    destination

    ):

    0.0.0.0/0

    ,表示任何目标位址都會被比對。
  6. 注釋 (

    /* Kubernetes nodeport TCP port for masquerade purpose */

    ):對該規則的簡要說明,用于辨別該規則的用途。

該規則使用了

match-set

來比對集合

KUBE-NODE-PORT-TCP

中的目标端口(NodePort)。當外部請求到達 NodePort 時,該規則會将流量标記為

KUBE-MARK-MASQ

,以便進行後續的

MASQUERADE

處理。

在 Kubernetes 中,

KUBE-MARK-MASQ

是一個

iptables

鍊的标記,它用于标記要進行源位址轉換(

MASQUERADE

)的資料包。

MASQUERADE

是一種

Network Address Translation (NAT)

技術,它允許修改資料包的源 IP 位址,以便傳回的資料包能夠正确傳回給發起請求的用戶端。

具體來說,當請求從 Kubernetes 叢集中的

NodePort

(服務暴露在主控端上的端口)到達時,

KUBE-NODE-PORT

鍊的規則會比對該請求,并将其标記為

KUBE-MARK-MASQ

。然後,

KUBE-MARK-MASQ

鍊的規則将對這些标記的資料包進行

MASQUERADE

處理,将它們的源 IP 位址替換為主控端的 IP 位址,以確定響應的資料包能夠正确傳回到請求的用戶端。

這個過程確定了外部請求能夠正确路由到

Kubernetes

叢集中的

Service

Pod

,并在傳回時正确傳回給請求的用戶端。這是實作

Kubernetes Service

NodePort

類型所必需的一部分。

既然使用了

march-set

,我們不妨先看看

ipset

[root@openeuler-controlplane-jtzv-0 ~]# ipset list |grep KUBE-NODE-PORT-TCP -A 12
Name: KUBE-NODE-PORT-TCP
Type: bitmap:port
Revision: 3
Header: range 0-65535
Size in memory: 8296
References: 1
Number of entries: 4
Members:
30000
30090
31037
31428
           

可以看到我們的目标

NodePort(31037)

ipvs

工作在

input

鍊(核心空間)利用

ipvsadm

(使用者空間)定義的轉發規則對資料包進行校驗,或者說此時

INPUT

鍊不再生效了,

IPVS

會攔截進入本機的資料包,并根據負載均衡的規則将其轉發給後端的真實伺服器(

Real Server

)處理

我們可以通過

ipvsadm -S -n

映射内容,到這一步基本就已經知道原因了,可以看到你的

NodeIP:NodePort

映射到

PodIP

,往下分析無非就是走完這個鍊條,本篇文章就不再展開贅述了。