1. 程式人生 > >【華為雲技術分享】跟唐老師學習雲網絡 : Kubernetes網路實現

【華為雲技術分享】跟唐老師學習雲網絡 : Kubernetes網路實現

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

一、簡單介紹下Kubernetes

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

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

二、世界上的叢集都一個樣

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

Ø 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~

三、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分別怎麼去實現的。

四、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 也可以做到的。

五、總結

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

 

點選關注,第一時間瞭解華為雲新鮮技