日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

深入 K8s 网络原理(二)- Service iptables 模式分析

發布時間:2023/12/24 windows 36 coder
生活随笔 收集整理的這篇文章主要介紹了 深入 K8s 网络原理(二)- Service iptables 模式分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄
  • 1. 概述
  • 2. 準備 Service 和 Pods 資源
  • 3. K8s 里 Service 的實現原理
    • 3.1 kube-proxy 組件
    • 3.2 iptables 簡介
    • 3.3 iptables 規則
      • 3.3.1 Service,Pod 和 Host 信息
      • 3.3.2 從 NodePort 入手尋找 iptables 規則
      • 3.3.3 從 PREROUTING 和 OUTPUT 鏈尋找 K8s 相關子鏈
      • 3.3.4 總結下
  • 4. 總結

1. 概述

接上一篇《深入 K8s 網絡原理(一)- Flannel VXLAN 模式分析》,今天我們繼續來分析 Kubernetes Service 的實現原理。

2. 準備 Service 和 Pods 資源

鏡像和上一篇一樣;

Deployment 的 YAML 如下:

  • nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:test1
        ports:
        - containerPort: 80

對應的 Service YAML 如下:

  • nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    nodePort: 30007

3. K8s 里 Service 的實現原理

Kubernetes 提供了幾種不同類型的 Service,包括:

  • ClusterIP:這是最常見的 Service 類型,為 Service 提供一個集群內部的 IP 地址,使得 Service 只能在集群內部訪問。
  • NodePort:這種類型的 Service 在每個節點上開放一個端口(NodePort),從而允許從集群外部通過 <NodeIP>:<NodePort> 訪問 Service。
  • LoadBalancer:這種類型的 Service 通常由云提供商支持,它會在集群外部創建一個負載均衡器,將外部流量分發到集群內的 Pods。
  • ExternalName:通過返回一個名字(而非 IP 地址)來指向外部服務。

接著具體來看 Service 的實現。

3.1 kube-proxy 組件

Kubernetes 集群中每個節點上會運行一個關鍵組件 kube-proxy,它負責為 Service 對象實現網絡代理,使得網絡流量可以透明地定向到后端 Pods。kube-proxy 支持幾種不同的代理模式,最常見的是 iptables 模式和 IPVS 模式。

  1. iptables 模式
  • 在這種模式下,kube-proxy 使用 iptables 規則來捕獲到達 Service 的流量,并將其重定向到后端 Pods。每當 Service 或 Pod 發生變化時,kube-proxy 都會更新 iptables 規則。
  • iptables 模式是最簡單且廣泛使用的,但在大規模集群中可能會面臨性能問題,因為每個網絡包都需要通過不短的規則鏈進行處理。
  1. IPVS (IP Virtual Server) 模式
  • IPVS 模式使用內核的 IPVS 功能,該功能提供了內置的負載均衡功能。與 iptables 相比,IPVS 可以處理更大規模的流量,擁有更好的性能和更復雜的負載均衡算法(最少連接等)。
  • 在這種模式下,kube-proxy 會創建一個虛擬服務器,為每個 Service 分配一個虛擬 IP(VIP),并將流量負載均衡到后端 Pods。

以 kube-proxy 的 iptables 模式為例,我們具體來看下 Service 創建后,iptables 是如何將 Service 流量轉到 pods 上的。

3.2 iptables 簡介

簡單介紹下 iptables:

iptables 是一種在 Linux 系統中廣泛使用的工具,它允許管理員配置內核的 netfilter 模塊,以控制網絡數據包的流入流出。這個工具提供了一個框架,用于定義規則,這些規則決定了如何處理經過網絡接口的數據包。

iptables 的核心功能主要包括:

  • 數據包過濾:iptables 最常用于過濾數據包,即決定哪些數據包可以通過網絡接口,哪些應該被阻止。
  • 網絡地址轉換 (NAT):它可以用于修改數據包的源或目的地址,常用于路由和隱藏內部網絡結構。
  • 端口轉發:iptables 可以重定向到特定端口的數據流,用于設置端口轉發。

剛從鋪灰的硬盤里發現一張三年前畫的 iptables 相關的圖(我都忘記這個圖應該叫啥名字了):

3.3 iptables 規則

下面具體看下 Service 對應的 iptables 規則。

3.3.1 Service,Pod 和 Host 信息

前面創建了 Service 和 Deployment,對應的 Service 和 Pod 資源如下:

  • kgsvc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-service   NodePort    10.107.33.105   <none>        80:30007/TCP   152m
  • kgpoowide
NAME                                READY   STATUS    RESTARTS   AGE    IP           NODE
nginx-deployment-7fbb8f4b4c-89bds   1/1     Running   0          155m   10.244.2.4   minikube-m03
nginx-deployment-7fbb8f4b4c-d29zm   1/1     Running   0          155m   10.244.1.5   minikube-m02

此外,我的 K8s 集群包括3個節點,nodes 的 ip/hostname 信息如下:

192.168.49.2	minikube
192.168.49.3	minikube-m02
192.168.49.4	minikube-m03

3.3.2 從 NodePort 入手尋找 iptables 規則

現在進到 minikube 節點,也就是 K8s 主節點,查看下 nat 表的鏈信息,過濾下 NodePort 端口 30007:

  • sudo iptables -t nat -L | grep 30007
KUBE-EXT-V2OKYYMBY3REGZOG  tcp  --  anywhere anywhere /* default/nginx-service */ tcp dpt:30007

可以看到一條鏈:KUBE-EXT-V2OKYYMBY3REGZOG,具體看下這條鏈的信息:

  • sudo iptables -t nat -L KUBE-EXT-V2OKYYMBY3REGZOG -v
Chain KUBE-EXT-V2OKYYMBY3REGZOG (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SVC-V2OKYYMBY3REGZOG  all  --  any    any     anywhere             anywhere

從這里可以看到 KUBE-EXT-V2OKYYMBY3REGZOG 有一條子鏈 KUBE-SVC-V2OKYYMBY3REGZOG。繼續看 KUBE-SVC-V2OKYYMBY3REGZOG 鏈:

  • sudo iptables -t nat -L KUBE-SVC-V2OKYYMBY3REGZOG -v
Chain KUBE-SVC-V2OKYYMBY3REGZOG (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SEP-J2DHXTF62PN2AN4F  all  --  any    any     anywhere             anywhere             /* default/nginx-service -> 10.244.1.5:80 */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-A4R5AW5RLMEQF7RP  all  --  any    any     anywhere             anywhere             /* default/nginx-service -> 10.244.2.4:80 */

進一步可以找到兩條 KUBE-SVC-V2OKYYMBY3REGZOG 的子鏈 KUBE-SEP-J2DHXTF62PN2AN4F 和 KUBE-SEP-A4R5AW5RLMEQF7RP,這里對應2個 pods。以 KUBE-SEP-J2DHXTF62PN2AN4F 為例繼續跟:

  • sudo iptables -t nat -L KUBE-SEP-J2DHXTF62PN2AN4F -v
Chain KUBE-SEP-J2DHXTF62PN2AN4F (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             /* default/nginx-service */ tcp to:10.244.1.5:80

到這里 target 不再是其他鏈,而是 DNAT,也就是請求 Service 的 NodePort 最終流量被 DNAT 到了 10.244.1.5:8010.244.2.4:80 這兩個 Endpoints,它們分別對應2個 pods。

3.3.3 從 PREROUTING 和 OUTPUT 鏈尋找 K8s 相關子鏈

先看 PREROUTING:

  • sudo iptables -t nat -L PREROUTING -v
Chain PREROUTING (policy ACCEPT 5 packets, 300 bytes)
 pkts bytes target     prot opt in     out     source               destination
   99  5965 KUBE-SERVICES  all  --  any    any     anywhere             anywhere             /* kubernetes service portals */

可以看到入向流量全部都會經過 KUBE-SERVICES 鏈處理。繼續看 OUTPUT:

sudo iptables -t nat -L OUTPUT -v

Chain OUTPUT (policy ACCEPT 3355 packets, 202K bytes)
 pkts bytes target     prot opt in     out     source               destination
29961 1801K KUBE-SERVICES  all  --  any    any     anywhere             anywhere             /* kubernetes service portals */

同樣全部出向流量也被 KUBE-SERVICES 鏈處理。繼續看下 KUBE-SERVICES 鏈:

  • sudo iptables -t nat -L KUBE-SERVICES -v
Chain KUBE-SERVICES (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-SVC-V2OKYYMBY3REGZOG  tcp  --  any    any     anywhere             10.107.33.105        /* default/nginx-service cluster IP */ tcp dpt:http
 3391  203K KUBE-NODEPORTS  all  --  any    any     anywhere             anywhere             /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL

可以看到2條子鏈,一個是表示 Nginx Service 的 Cluster IP 的子鏈 KUBE-SVC-V2OKYYMBY3REGZOG,另外一個是表示集群 NodePort 的 KUBE-NODEPORTS 子鏈。KUBE-SVC-V2OKYYMBY3REGZOG 在前面已經具體看過了,那么 KUBE-NODEPORTS 子鏈具體又包含啥信息呢:

  • sudo iptables -t nat -L KUBE-NODEPORTS -v
Chain KUBE-NODEPORTS (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 KUBE-EXT-V2OKYYMBY3REGZOG  tcp  --  any    any     anywhere             anywhere             /* default/nginx-service */ tcp dpt:30007

可以看到當 TCP 流量的目的端口是 30007 的時候,就會匹配到 KUBE-EXT-V2OKYYMBY3REGZOG 子鏈,KUBE-EXT-V2OKYYMBY3REGZOG 子鏈的內容前面已經具體看過了。換言之,每多創建一個 NodePort 類型的 Service,kube-proxy 就會在 KUBE-NODEPORTS 子鏈下新掛一條 KUBE-EXT-XXX 子鏈。

3.3.4 總結下

IP 包進出主機都會經過 KUBE-SERVICES 鏈,進而根據 destination 地址匹配到不同的子鏈:

  1. 如果目的地址是某個 Service 的 Cluster IP,那么就匹配到具體的 KUBE-SVC-XXX 處理;
  2. 否則,就匹配到 KUBE-NODEPORTS 處理;流量匹配到 KUBE-NODEPORTS 后,會進一步根據 tcp 目的端口 來匹配具體的子鏈 KUBE-EXT-XXX;

如果流量匹配到 KUBE-EXT-XXX 子鏈,端口命中,那么下一條依舊是表示 Cluster IP 的 KUBE-SVC-XXX,所以兩條子鏈在這里匯合。而 KUBE-SVC-XXX 鏈上的規則會進一步將 IP 包匹配到 KUBE-SEP-XXX 子鏈上,這些子鏈表達的是“Service Endpoints”。默認情況下 KUBE-SVC-XXX 會根據 Pod 數量按照相等的概率將流量分流到多個 KUBE-SEP-XXX 上進一步匹配。而 KUBE-SEP-XXX 鏈會執行類似“DNAT to:10.244.1.5:80”過程,最終將一開始請求 Service 的流量就丟給了 Pod。

所以,當你通過 NodePort/ClusterIP 方式訪問 pods 的時候,以兩副本為例,整體流量匹配過程大致如下圖:

4. 總結

不總結。明天見。

總結

以上是生活随笔為你收集整理的深入 K8s 网络原理(二)- Service iptables 模式分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。