k8s中的網絡(較詳細匯總)


本文參考戳該鏈接可以看原文,原文作者整理非常好

一、網絡前提條件-網絡模型

  • k8s組網要求
    • 所有的Pods之間可以在不使用NAT網絡地址轉換的情況下相互通信
    • 所有的Nodes之間可以在不使用NAT網絡地址轉換的情況下相互通信
    • 每個Pod自己看到的自己的ip和其他Pod看到的一致
  • k8s網絡模型設計原則
    • 每個Pod都擁有一個獨立的 IP地址,而且 假定所有 Pod 都在一個可以直接連通的、扁平的網絡空間中 。
    • 不管它們是否運行在同 一 個 Node (宿主機)中,都要求它們可以直接通過對方的 IP 進行訪問。
    • 設計這個原則的原因 是,用戶不需要額外考慮如何建立 Pod 之間的連接,也不需要考慮將容器端口映射到主機端口等問題。

由於 Kubemetes 的網絡模型假設 Pod 之間訪問時使用的是對方 Pod 的實際地址,所以一個Pod 內部的應用程序看到的自己的 IP 地址和端口與集群內其他 Pod 看到的一樣。它們都是 Pod 實際分配的IP地址 (從dockerO上分配的)。將IP地址和端口在Pod內部和外部都保持一致, 我們可以不使用 NAT 來進行轉換,地址空間也自然是平的。

二、需要解決的網絡問題

根據以上的一些要求,需要解決的問題

  • Docker容器和Docker容器之間的網絡
  • Pod與Pod之間的網絡
  • Pod與Service之間的網絡
  • Internet與Service之間的網絡

1.容器和容器之間的網絡

pod有多個容器,它們之間怎么通信?

pod中每個docker容器和pod在一個網絡命名空間內,所以ip和端口等等網絡配置,都和pod一樣,主要通過一種機制就是,docker的一種網絡模式,container,新創建的Docker容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等

2.pod與pod之間的網絡

pod與pod之間的網絡:首先pod自身擁有一個IP地址,不同pod之間直接使用IP地址進行通信即可

同一台node節點上pod和pod通信

疑問:那么不同pod之間,也就是不同網絡命名空間之間如何進行通信(現在還是,同一台node節點上)

解決

簡單說veth對就是一個成對的端口,所有從這對端口一端進入的數據包,都將從另一端出來。

為了讓多個Pod的網絡命名空間鏈接起來,我們可以讓veth對的一端鏈接到root網絡命名空間(宿主機的),另一端鏈接到Pod的網絡命名空間。

嗯,那么繼續。

還需要用到一個Linux以太網橋,它是一個虛擬的二層網絡設備,目的就是把多個以太網段連接起來,它維護一個轉發表,通過查看每個設備mac地址決定轉發,還是丟棄數據

  • pod1-->pod2(同一台node上),pod1通過自身eth0網卡發送數據,eth0連接着veth0,網橋把veth0和veth1組成了一個以太網,然后數據到達veth0之后,網橋通過轉發表,發送給veth1,veth1直接把數據傳給pod2的eth0。

不同node節點上pod和pod通信

CIDR的介紹:

CIDR(Classless Inter-Domain Routing,無類域間路由選擇)它消除了傳統的A類、B類和C類地址以及划分子網的概念,因而可以更加有效地分配IPv4的地址空間。它可以將好幾個IP網絡結合在一起,使用一種無類別的域際路由選擇算法,使它們合並成一條路由從而較少路由表中的路由條目減輕Internet路由器的負擔。

看圖,接着往下捋。

k8s集群中,每個node節點都會被分配一個CIDR塊,(把網絡前綴都相同的連續地址組成的地址組稱為CIDR地址塊)用來給node上的pod分配IP地址,另外還需要把pod的ip和所在nodeip進行關聯

  • 比如node1上pod1和node2上的pod4進行通信
    1. 首先pod1上網卡eth0將數據發送給已經管理到root命名空間的veth0上,被虛擬網橋收到,查看自己轉發表之后,並沒有pod4的mac地址。
    2. 就會把包轉發到默認路由,(root命名空間的eth0上,也就是已經到了node節點的往卡上)通過eth0,發送到網絡中。
    3. 尋址轉發后包來到了node2,首先被root命名空間的eth0設備接受,查看目標地址是發往pod4的,交給虛擬網橋路由到veth1,最終傳給pod4的eth0上。

3.pod與service之間的網絡

pod的ip地址是不持久的,當集群中pod的規模縮減或者pod故障或者node故障重啟后,新的pod的ip就可能與之前的不一樣的。所以k8s中衍生出來Service來解決這個問題。

Service管理了多個Pods,每個Service有一個虛擬的ip,要訪問service管理的Pod上的服務只需要訪問你這個虛擬ip就可以了,這個虛擬ip是固定的,當service下的pod規模改變、故障重啟、node重啟時候,對使用service的用戶來說是無感知的,因為他們使用的service的ip沒有變。

當數據包到達Service虛擬ip后,數據包會被通過k8s給該servcie自動創建的負載均衡器路由到背后的pod容器。

  • 在k8s里,iptables規則是由kube-proxy配置,kube-proxy監視APIserver的更改,因為集群中所有service(iptables)更改都會發送到APIserver上,所以每台kubelet-proxy監視APIserver,當對service或pod虛擬IP進行修改時,kube-proxy就會在本地更新,以便正確發送給后端pod
  • pod到service包的流轉:

  1. 數據包從pod1所在eth0離開,通過veth對的另一端veth0傳給網橋cbr0,網橋找不到service的ip對應的mac,交給了默認路由,到達了root命名空間的eth0
  2. root命名空間的eth0接受數據包之前會經過iptables進行過濾,iptables接受數據包后使用kube-proxy在node上配置的規則響應service,然后數據包的目的ip重寫為service后端指定的pod的ip了
  • service到pod包的流轉
  1. 收到包的pod會回應數據包到源pod,源ip是發送方ip,目標IP是接收方,數據包進行回復時經過iptables,iptables使用內核機制conntrack記住它之前做的選擇,又將數據包源ip重新為service的ip,目標ip不變,然后原路返回至pod1的eth0

4.Internet與service之間的網絡

將k8s集群服務暴露給互聯網上用戶使用,有兩個問題;(1)從k8s的service訪問Internet,以及(2)從Internet訪問k8s的service.

根據參考文章,通過Internet網關,node可以將流量路由到Internet,但是pod具有自己的IP地址,Internet王冠上的NAT轉換並不適用。參考方案:就是node主機通過iptables的nat來解決

  • node到internet包的流轉

  1. 數據包源自pod1網絡命名空間,通過veth對連接到root網絡命名空間,緊接着,轉發表里沒有IP對應的mac,會發送到默認路由,到達root網絡命名空間的eth0
  2. 那么在到達root網絡明明空間之前,iptables會修改數據包,現在數據包源ip是pod1的,繼續傳輸會被Internet網關拒絕掉,因為網關NAT僅轉發node的ip,解決方案:使iptables執行源NAT更改數據包源ip,讓數據包看起來是來自於node而不是pod
  3. iptables修改完源ip之后,數據包離開node,根據轉發規則發給Internet網關,Internet網關執行另一個NAT,內網ip轉為公網ip,在Internet上傳輸。
  4. 數據包回應時,也是按照:Internet網關需要將公網IP轉換為私有ip,到達目標node節點,再通過iptables修改目標ip並且最終傳送到pod的eth0虛擬網橋。

Internet到k8s的流量

讓Internet流量進入k8s集群,這特定於配置的網絡,可以在網絡堆棧的不同層來實現:

(1) NodePort

(2)Service LoadBalancer

(3)Ingress控制器。

這里只介紹第三種,如果想看詳細的,文章開始有一個鏈接

  • 第七層流量入口:Ingress Controller

通過一個公開的ip地址來公開多個服務,第7層網絡流量入口是在網絡堆棧的HTTP / HTTPS協議范圍內運行,並建立在service之上。

工作:客戶端現針對www.1234.com執行dns解析,DNS服務器返回ingress控制器的ip,客戶端拿到ip后,向ingress控制器發送http的get請求,將域名加在host頭部發送。控制器接收到請求后,從host頭部就知道了該訪問哪一個服務,通過與該service關聯的endpoint對象查詢podIP地址,將請求進行轉發

第7層負載均衡器的一個好處是它們具有HTTP感知能力,因此它們了解URL和路徑。 這允許您按URL路徑細分服務流量。 它們通常還在HTTP請求的X-Forwarded-For標頭中提供原始客戶端的IP地址。

參考

https://www.jianshu.com/p/3f2401d14c78


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM