跟唐老師學習雲網絡 - Kubernetes網絡實現

首先要搞懂k8s與docker直接的關係,前幾天給同事舉了個例子,一個是物業,一個是業務,相互依賴生存的

 

當今K8s獨霸天下之時,咱們站在更高的角度,好好的看看K8s的網絡是以什麼理念構築的。以及一個容器集羣的好保姆,是如何分別照顧 南北流量和東西流量的。

 

1      簡單介紹下Kubernetes

略。。容器集羣管理的事實標準了,不知道要打屁股。

(ps:本章節可參考唐老師的《K8S前世今生》文章)

2      世界上的集羣都一個樣

有點標題黨哈,不過我接觸過的各種集羣也不少,各種各樣:

Ø  OpenStack:在一大堆物理機上面,管理(啓動/停止)VM的。

Ø  SGE,Slurm,PBS:在一大堆電腦集羣裏面,管理(啓動/停止)App的。

Ø  Yarn:在一大堆電腦集羣裏面,管理(啓動/停止)大數據App的。

Ø  CloudFoundry:在一大堆電腦集羣裏面,管理(啓動/停止)容器的

Ø  Kubernetes:在一大堆電腦集羣裏面,管理(啓動/停止)容器的。

它們都有一些共同特點:

2.1      跨節點跑xx程序

這個xx程序一定是首先單機可以運行的。比如OpenStack:單機上面可以用qemu啓動VM,想跨節點管理VM,就引入了OpenStack。Kubernetes也一樣:單機上面可以跑Docker容器;想跨節點管理容器,就得引入集羣管理老大的概念。

2.2      有一個管事的老大

A)集羣管理的老大,負責讓手下的某個小弟幹活。別管是命令式(直接下命令)的,還是申明式(發告示)的,小弟收到命令後,乖乖幹活就是了。

B)       同時,這個集羣管理的老大,需要有腦子,不然小弟數量多了管不好。所以它需要拿筆記一記。比如OpenStack的老大得帶個Mysql數據庫;Kubernetes把筆記記在了ETCD裏面(不過ETCD這個本子太小,記得東西不能太大,這是另話)。

C)       不管哪種老大,都得有個軍師。一個新活來到老大這裏,那麼多小弟,指派給誰不是幹呀。這活實際分配給哪個小弟,這得軍師說了算,所以每中集羣軟件都自己寫了一套 Scheduler 算法,可謂程序員間浪費重複輪子之典型代表。

2.3      小弟上面都有一個Agent

這個小弟上面的Agent,時刻向老大彙報自己的狀態:活不活着,忙還是閒,方便老大派活。同時,Agent也就是那臺電腦裏面的地頭蛇了,幫忙老大負責各種臨時事物。只是大家的取名不一樣:

OpenStack:取名Nova

Kubernetes:取名Kubelet

Yarn:取名NodeManager

2.4      老大怎麼給小弟發號施令

一般老大都是通過:消息隊列來,給小弟發號施令的,而不是親自上門(直連)下達命令。原因麼,當然是小弟可能臨時出門(故障)了唄~ 直接上門可能不通,放消息隊列裏面就可靠多了。等小弟出差回來,還能看到老大下達的任務令。

Ø  OpenStack:用 RabbitMQ 發號施令

Ø  Kubernetes:用 ETCD 發號施令

Ø  CloudFoundry:用 NATS 發號施令

上面這些組件都是帶消息通知的功能,區別有些有名,有些沒那麼出名罷了。

比如我們的K8s:

特別需要提一下:K8s這個老大不簡單,找了個ETCD這個好幫手。這小傢伙挺神,既能當筆記本記點事情(代替OpenStack中的Mysql),又能當公告牌,通知點消息(代替OpenStack中的Rabbit)。所以K8s這個容器集羣管理相對OpenStack這個虛機管理不需要數據庫,666~

3      K8s怎麼設計容器網絡的呢

3.1      南北流量

要看到K8s誕生的時候,那時是有CloudFoundry和Docker的,且都已經比較成熟。那時作爲PaaS一哥的CF對容器網絡的抽象:

主要考慮平臺外部,怎麼訪問容器裏面的App。而平臺內部的App之間如何互相訪問,幾乎沒有太多的設計。

由上圖所示,可以看到,平臺外部訪問,一般都是上下畫的,所以也叫做南北流量。我們這麼叫,也是便於程序員之間溝通和理解。

Ps:PaaS的基本原型大致都這樣:

3.2      東西流量

K8s吸取了前輩們的精華,除了平臺外部訪問App,還新增考慮了平臺內部,App之間如何互相訪問。

即K8s通過增加一個負載均衡的“LB”設備,來搞定平臺內部的App間互相訪問。給每個App取個別名,在LB上面登記一下,就可以被內部其他App訪問。

由上圖所示,可以看到,平臺內部訪問,一般都是水平畫的,所以也叫做東西流量。一個完整的PaaS平臺,就是需要南北流量+東西流量,全套治理的。

3.3      Docker原生訪問方式

還記得唐老師的《Docker網絡實現》章節吧,Docker容器可以通過“節點IP+節點Port”的方式訪問到容器。原理的容器所在節點,設置了NAT規則。報文一到達節點,根據目的端口,轉發進入容器。

3.4      小結:K8s中3種訪問容器的通道

(1)       通過南北流量(從集羣外部訪問App)訪問App容器

(2)       通過東西流量(集羣內App之間)訪問App容器

(3)       通過Docker原生自帶的方式,訪問App容器

下一章節,我們簡單介紹下每種方式,K8s分別怎麼去實現的。

4      K8s怎麼實現容器訪問

雖然K8s上面,有多種訪問App容器的方法。但是不管用什麼方式訪問,一個App想要能被訪問,就得得到K8s的同意。K8s把這個許可證叫做“Service”:也就是不管什麼南北流量、東西流量,你的App想要能被訪問,就得先申請Service許可證。

4.1      南北流量

要實現一個App的訪問通道,一定要2個東西:(1)LB負載均衡器 + (2)註冊映射關係。

映射關係就是:報文來了,應該轉發給哪個App實例? 即:找到 “哪個App + 哪個實例”。

負載均衡器呢,一般大家愛用Nginx,不過也有其他類型的實現。

K8s比CF聰明的地方是,沒有自己去實現LB。而只定義了App需要怎麼樣才能登記到LB上面。即只定規範,不限制實現(這種思路,在k8s裏面好多,比如存儲的CSI,運行時的CRI的,容器網絡的CNI 都是這樣。)

Ø  4層LB

最簡單的4層LB實現,K8s取了個名字:LoadBalancer(1

即定義:xx協議+xx端口 =》xx應用,具體規則自己去看資料。

Ø  7層LB

爲了定義7層LB的規則,K8s給規範取了名字:Ingress(2

即定義:xx網址+xx-URL路徑 =》xx應用,具體規則也自己看K8s資料。

南北LB都是全局級的,即:全局一個(HA多實例,咱也當一個整體)就行;不需要每個Slaver節點上一個。

4.2      東西流量

東西流量,也一樣,需要LB+規則注入。這裏,K8s設計就比較有意思。

邏輯上,如上圖所示。在LB部分的實現上,K8s很巧妙的要求每個節點上面都一個“小LB”。

所以實現上,大致如上圖所示。

Ø  本地LB

本地LB,要求每個節點都有。所以最開始的版本,K8s使用了Linux使用廣泛的iptables來實現。

後面由於iptables性能不是特別給力,又有了 IPVS 實現。然後其他各式各樣的民間實現也有。

Ø  本地控制器

LB需要一個控制器,每個本地“小LB”帶配備一個小控制器,一樣的,也是每個節點一個。和小LB一一對應。K8s給它取了個名字:Kube-proxy

Ø  假IP地址

每個K8s上的App,都可以申請“行走江湖的名號”,用來代表自己。K8s就會給你的App分配一個Service許可證,許可證上面帶着“影子IP”,任何集羣內部只要訪問這個IP,就等於訪問你的App。

實現上:

1.     先到K8s那登記,說我想要個“名號”

2.     通過後,K8s會告知每個節點上的本地LB

3.     從此以後,每個LB都認識這個“影子IP”了,訪問它,就代表訪問對應App。

由於這個“名號”是集羣頒佈的,所以僅在集羣內有效。K8s取名:ClusterIP(3

關於東西流量的故事,還可以去看看唐老師之前的《網絡騙子》篇。

4.3      Docker原生訪問方式

除了上面幾種訪問方式,K8s也爲原生的Docker訪問通道留了個名字:NodePort(4

這種方式,在《Docker網絡實現》裏面說過,靠主機Host轉發實現。既然是主機搞定,所以這條路和本地LB實現,就合併一起搞定了。

如上圖,K8s下發規則的時候,順便把這條路的規則也下發下去。

ps:由於每個本地LB都收到了K8s的通告小皮鞭,所以每個K8s的節點,都開通了NodePort通道哦。即:無論哪個Slaver節點的Port都可以通往該App。

4.4      小結

K8s在實現容器網絡的時候,造了很多概念:

(1)       LoadBalancer

(2)       Ingress

(3)       ClusterIP

(4)       NodePort

本質都是一樣的,就是LB+登記規範。 如果你看過《DNS篇》+《Docker網絡實現》,這些就比較好理解。

ps:具體本地LB怎麼實現?真有興趣可以去搜搜Kube-proxy的代碼解讀。我本身不是很關心,因爲其實你給每個節點安裝一個 Nginx 也可以做到的。

5      總結

K8s的網絡概念,特別是Service,是K8s裏面的精華,務必需要搞明白。

(1)       K8s南北流量,用Loadbalancer(4層)和Ingress(7層)搞定。

(2)       K8s的東西流量,用Service概念搞定。特別的,還給了個“行走江湖用的名號”,取名ClusterIP(一個不存在的假IP地址)。

(3)       容器所在Host組網,存在Docker原生通道,K8s給重新包裝了個名字:NodePort。所以只要報文到達Slaver節點,就能通到容器裏面。

另外,提一下一直沒有說的東西(怕概念太多,影響理解):K8s的整個網絡底座,是要求節點IP和容器IP是能互相連通的(即:在節點上面ping容器IP,是可以通的)。具體則是通過容器網絡實現的。這個實現很多,Flannel,Calico等,本質要麼隧道,要麼子網(可以看看物理網絡裏面的《VLAN和Vxlan》篇,關於如何劃分門派的篇章)。

 

作者:華爲云云享專家  tsjsdbd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章