?絕大多數(shù)剛剛接觸k8s的同學都會被其中的網絡相關知識點搞得暈頭轉向扫尺!各種IP,包括:Node IP,ClusterIP,Node IP糾結是啥東東淳玩?internet是怎樣訪問k8s的直撤?k8s內部各個pod之間又是如何通信的非竿?本文就為大家來解決上述問題。如果您想了解k8s更為全面的核心概念谋竖,請參考文章:測試技能提升篇——k8s的核心概念
K8s中網絡核心概念介紹
Node IP
Node節(jié)點的IP地址红柱,即物理網卡的IP地址承匣。NodePort可以是物理機的IP(也可能是虛擬機IP)。每個Service都會在Node節(jié)點上開通一個端口锤悄,外部可以通過NodeIP:NodePort即可訪問Service里的Pod,和我們訪問服務器部署的項目一樣韧骗,IP:端口/項目名
Cluster IP
Service的IP地址,此為虛擬IP地址零聚。外部網絡無法ping通袍暴,只有k8s集群內部訪問使用。Cluster IP是一個虛擬的IP隶症,但更像是一個偽造的IP網絡政模,原因有以下幾點
1.Cluster IP僅僅作用于k8s Service這個對象,并由k8s管理和分配P地址
2.Cluster IP無法被ping蚂会,他沒有一個“實體網絡對象”來響應
3.Cluster IP只能結合Service Port組成一個具體的通信端口淋样,單獨的Cluster IP不具備通信的基礎,并且他們屬于k8s集群這樣一個封閉的空間胁住。
4.在不同Service下的pod節(jié)點在集群間相互訪問可以通過Cluster IP
Pod IP
Pod IP是每個Pod的IP地址趁猴,他是Docker Engine根據(jù)docker網橋的IP地址段進行分配的,通常是一個虛擬的二層網絡
同Service下的pod可以直接根據(jù)Pod IP相互通信
不同Service下的pod在集群間pod通信要借助于 cluster IP
pod和集群外通信彪见,要借助于node IP
簡單地總結:外部訪問時儡司,先到Node節(jié)點網絡,再轉到service網絡余指,最后代理給pod網絡枫慷。
K8s如何實現(xiàn)網絡通信
三條核心原則
默認情況下,Linux 將所有的進程都分配到 root network namespace浪规,以使得進程可以訪問外部網絡
K8s為每一個 Pod 都創(chuàng)建了一個 network namespace或听。
3.在 K8s中,Pod 是一組 docker 容器的集合笋婿,這一組 docker 容器將共享一個 network namespace誉裆。Pod 中所有的容器都使用該 network namespace 提供的同一個 IP 地址以及同一個端口空間。所有的容器都可以通過 localhost 直接與同一個 Pod 中的另一個容器通信缸濒。
容器與容器之間網絡通信
pod中每個docker容器和pod在一個網絡命名空間內足丢,所以ip和端口等等網絡配置,都和pod一樣庇配,主要通過一種機制就是斩跌,docker的一種網絡模式,container捞慌,新創(chuàng)建的Docker容器不會創(chuàng)建自己的網卡耀鸦,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等
pod與pod之間網絡通信
從 Pod 的視角來看袖订,Pod 是在其自身所在的 network namespace 與同節(jié)點上另外一個 network namespace 進程通信氮帐。在Linux上,不同的 network namespace 可以通過 Virtual Ethernet Device (opens new window) 或 veth pair (兩塊跨多個名稱空間的虛擬網卡)進行通信洛姑。為連接 pod 的 network namespace上沐,可以將 veth pair 的一段指定到 root network namespace,另一端指定到 Pod 的 network namespace楞艾。每一組 veth pair 類似于一條網線参咙,連接兩端,并可以使流量通過硫眯。節(jié)點上有多少個 Pod昂勒,就會設置多少組 veth pair。下圖展示了 veth pair 連接 Pod 到 root namespace 的情況:
?為了讓 Pod 可以互相通過 root network namespace 通信舟铜,我們將使用 network bridge(網橋)戈盈。Linux Ethernet bridge 是一個虛擬的 Layer 2 網絡設備,可用來連接兩個或多個網段谆刨。網橋的工作原理是塘娶,在源于目標之間維護一個轉發(fā)表,通過檢查通過網橋的數(shù)據(jù)包的目標地址和該轉發(fā)表來決定是否將數(shù)據(jù)包轉發(fā)到與網橋相連的另一個網段痊夭。橋接代碼通過網絡中具備唯一性的網卡MAC地址來判斷是否橋接或丟棄數(shù)據(jù)刁岸。網橋實現(xiàn)了ARP協(xié)議來發(fā)現(xiàn)鏈路層與 IP 地址綁定的 MAC 地址。當網橋收到數(shù)據(jù)幀時她我,網橋將該數(shù)據(jù)幀廣播到所有連接的設備上(除了發(fā)送者以外)虹曙,對該數(shù)據(jù)幀做出相應的設備被記錄到一個查找表中。后續(xù)網橋再收到發(fā)向同一個 IP 地址的流量時番舆,將使用查找表來找到對應的 MAC 地址酝碳,并轉發(fā)數(shù)據(jù)包。下圖中cbr0就是網橋恨狈。
不同Node間通信原理
通常疏哗,集群中每個節(jié)點都被分配了一個 CIDR 網段(簡單的理解CIDR可以把幾個標準網絡合成一個大的網絡),指定了該節(jié)點上的 Pod 可用的 IP 地址段禾怠。一旦發(fā)送到該 CIDR 網段的流量到達節(jié)點返奉,就由節(jié)點負責將流量繼續(xù)轉發(fā)給對應的 Pod。下圖展示了兩個節(jié)點之間的數(shù)據(jù)報文傳遞過程吗氏。
pod與service之間網絡通信
Pod 的 IP 地址并非是固定不變的芽偏,隨著 Pod 的重新調度(例如水平伸縮、應用程序崩潰弦讽、節(jié)點重啟等)污尉,Pod 的 IP 地址將會出現(xiàn)又消失。此時,Pod 的客戶端無法得知該訪問哪個 IP 地址十厢。k8s中等太,Service 的概念用于解決此問題捂齐。Service管理了多個Pods蛮放,每個Service有一個虛擬的ip,要訪問service管理的Pod上的服務只需要訪問你這個虛擬ip就可以了,這個虛擬ip是固定的奠宜,當service下的pod規(guī)模改變包颁、故障重啟、node重啟時候压真,對使用service的用戶來說是無感知的娩嚼,因為他們使用的service的ip沒有變。當數(shù)據(jù)包到達Service虛擬ip后滴肿,數(shù)據(jù)包會被通過k8s給該servcie自動創(chuàng)建的負載均衡器路由到背后的pod容器岳悟。
我們知道Service 是 k8s中的一種服務發(fā)現(xiàn)機制,總結核心功能如下:
通常通過service來關聯(lián)pod并提供對外訪問接口泼差;
Service 實現(xiàn)負載均衡贵少,可將請求均衡分發(fā)到選定這一組 Pod 中;
Service 通過 label selector 選定一組 Pod堆缘。
Service的ip分配策略
k8s的一個設計哲學是:盡量避免非人為錯誤產生的可能性滔灶。就設計 Service 而言,k8s應該將您選擇的端口號與其他人選擇的端口號隔離開吼肥。為此录平,k8s為每一個 Service 分配一個該 Service 專屬的 IP 地址。為了確保每個 Service 都有一個唯一的 IP 地址缀皱,k8s在創(chuàng)建 Service 之前斗这,先更新 etcd 中的一個全局分配表,如果更新失斊《贰(例如 IP 地址已被其他 Service 占用)涝影,則 Service 不能成功創(chuàng)建。k8s使用一個后臺控制器檢查該全局分配表中的 IP 地址的分配是否仍然有效争占,并且自動清理不再被 Service 使用的 IP 地址燃逻。
Service的dns解析
k8s集群中運行了一組 DNS Pod,配置了對應的 Service臂痕,并由 k8s將 DNS Service 的 IP 地址配置到節(jié)點上的容器中以便解析 DNS names伯襟。集群中的每一個 Service(包括 DNS 服務本身)都將被分配一個 DNS name。默認情況下握童,客戶端 Pod 的 DNS 搜索列表包括 Pod 所在的名稱空間以及集群的默認域姆怪。例如:
假設名稱空間 A中有一個 Service 名為 foo:
名稱空間 A中的 Pod 可以通過 nslookup foo 查找到該 Service
名稱空間 B中的 Pod 可以通過 nslookup foo.A 查找到該 Service
Internet與k8s的網絡通信
讓Internet流量進入k8s集群,這特定于配置的網絡,可以在網絡堆棧的不同層來實現(xiàn):
NodePort
NodePort 服務是引導外部流量到你的服務的最原始方式稽揭。NodePort俺附,正如這個名字所示,在所有節(jié)點(虛擬機)上開放一個特定端口溪掀,任何發(fā)送到該端口的流量都被轉發(fā)到對應服務事镣。
Service LoadBalancer
如果你想要直接暴露服務,這就是默認方式揪胃。所有通往你指定的端口的流量都會被轉發(fā)到對應的服務璃哟。它設有過濾條件,路由等功能。值得一提的是喊递,如果是在本地開發(fā)測試環(huán)境里頭搭建的K8s随闪,一般不支持Load Balancer也沒必要,因為通過NodePort做測試訪問就夠了骚勘。但是在生產環(huán)境或者公有云上的K8s铐伴,基本都支持自動創(chuàng)建Load Balancer。
Ingress控制器
它處于多個服務的前端俏讹,扮演著“智能路由”或者集群入口的角色当宴。它的本質上就是K8s集群中的一個比較特殊的Service(發(fā)布Kind: Ingress)。這個Service提供的功能主要就是7層反向代理(也可以提供安全認證藐石,監(jiān)控即供,限流和SSL證書等高級功能),功能類似Nginx于微。Ingress對外暴露出去是通過HostPort(80/443)逗嫡,可以和上面LoadBalancer對接起來。有了這個Ingress Service株依,我們可以做到只需購買一個LB+IP驱证,就可以通過Ingress將內部多個(甚至全部)服務暴露出去,Ingress會幫忙做代理轉發(fā)恋腕。