如何做容器化集群管理?保障容器能被有序訪問是關鍵

原標題:如何做容器化集群管理?保障容器能被有序訪問是關鍵

在上一篇《容器化實踐指南 | 邁出容器化的第一步:集群管理(上)》中,我們介紹了Kubernetes的節(jié)點如何構成一個集群。本篇將在此基礎上,繼續(xù)介紹Kubernetes集群的容器網(wǎng)絡架構。

當Kubernetes集群完成搭建后,用戶的容器就可以運行在眾多的工作節(jié)點之中,那么接下來就需要確保這些容器之間可以互相訪問或接受來自外部的訪問。雖然我們在搭建集群時就已經(jīng)確保了所有工作節(jié)點在網(wǎng)絡上是互通的,但是由于同一個節(jié)點上可能同時運行多個容器,并且容器本身也隨時可能在節(jié)點之間移動,因此Kubernetes需要一套容器網(wǎng)絡方案來保障訪問某個指定容器的流量可以正確地到達該容器,并且不同容器在接收請求時不會出現(xiàn)路由沖突。

Kubernetes網(wǎng)絡基本的部署調(diào)度單元:Pod

在說明常見的容器網(wǎng)絡方案之前,我們需要先理解一個Kubernetes中最基礎的概念:Pod。

簡單來說,Kubernetes中的基本管理單元并不是一個個獨立的容器,而是一個或多個相關容器組成的容器組,稱為Pod。通常情況下,一個Pod即用戶部署的一個服務單元,比如一個數(shù)據(jù)庫服務、一個Web服務等。如果用戶的一個服務單元中存在多個獨立運行的組件,那么這些組件就可以部署在該Pod的不同容器中,從而在組件解耦的基礎上便于對多個容器進行統(tǒng)一管理。

Pod在英文中的原意是豌豆莢,也非常形象地表達出了Pod(豆莢)與容器(豆子)之間的關系。

關于Pod的管理未來我們將會進行更多的闡述,單從容器網(wǎng)絡的角度來看,每一個Pod即是一個獨立的最終訪問單元。因此Kubernetes的網(wǎng)絡架構中有一個最基本的設計原則:每個Pod擁有唯一的IP地址。這個Pod IP將被Pod中的所有容器共享,而集群內(nèi)的其它Pod則可以通過該Pod IP正確訪問到對應容器。

在理解這個基本原則之后,我們也就不難理解,容器網(wǎng)絡方案需要解決的問題其實包括以下3個:

  • 同一個Pod中的多個容器如何通訊
  • 同一個工作節(jié)點上的Pod之間如何通訊
  • 跨不同工作節(jié)點的Pod之間如何通訊

同一個Pod中的多個容器間通訊

在Kubernetes的設計中,一個Pod內(nèi)的所有容器共享同一個網(wǎng)絡命名空間(Network Namespace,后文中簡稱為netns),因此它們之間可以直接通過"localhost" + 端口互相訪問。

但需要注意的是,由于Pod內(nèi)的容器共享同一個netns,因此為了避免訪問沖突,這些容器各自使用的端口必須唯一。比如說容器A占用了80端口,那么同一個Pod中的容器B就不能再使用該端口了。

為了便于理解,我們通過一個簡單的例子說明:

  • 我們創(chuàng)建一個Pod,Pod中存在兩個容器,其中一個運行Nginx作為反向代理,另外一個運行簡單的Web應用程序
  • 可以定義Nginx的容器端口為80,定義Web應用程序的容器端口為9000,假設外部訪問該Pod的請求都使用80端口
  • 在Nginx容器中通過配置文件定義:通過80端口輸入的請求將被轉發(fā)到本地端口9000
  • 所有訪問該Pod 80端口的請求,都將被發(fā)往Nginx容器,然后再被轉發(fā)到Web應用容器的9000端口

同一個工作節(jié)點上的Pod間通訊

在Kubernetes集群中的每一個工作節(jié)點(針對Linux操作系統(tǒng)),都會有一個根網(wǎng)絡命名空間(root netns),工作節(jié)點上的根網(wǎng)絡設備(eth0)就在這個root netns下。對于每一個部署在節(jié)點上的Pod,其自身都有一個獨立的netns(即前文提到的由Pod內(nèi)所有容器共享的網(wǎng)絡命名空間),Pod本身不需要感知到節(jié)點主機上真實的網(wǎng)絡設備,而是擁有自己的虛擬根網(wǎng)絡設備(同樣叫做eth0)。

Pod自身的netns通過一個Linux虛擬網(wǎng)絡設備 veth 連接到root netns中,該虛擬網(wǎng)絡設備通常被命名為veth***,在節(jié)點中通過ifconfig或者ip a等命令就可以列出該節(jié)點上所有的veth。同時每個節(jié)點中會創(chuàng)建一個專用的以太網(wǎng)橋(通常稱為 cbr0),這個網(wǎng)橋的作用類似于交換機,通過mac尋址,將訪問節(jié)點內(nèi)Pod IP的請求投遞到正確的物理地址。

當一個網(wǎng)絡數(shù)據(jù)包要從Pod1發(fā)送到Pod2,它會經(jīng)歷以下流程:

  • 首先數(shù)據(jù)由Pod1中netns的網(wǎng)絡接口eth0離開,通過veth-pod1進入root netns
  • 然后數(shù)據(jù)被轉到網(wǎng)橋cbr0中,cbr0通過ARP請求詢問:“誰擁有這個IP?”
  • verth-pod2答復說“我擁有這個IP”,于是cbr0將數(shù)據(jù)包投遞給verth-pod2
  • 最后數(shù)據(jù)包通過verth-pod2,被轉發(fā)到Pod2的netns

跨不同工作節(jié)點的Pod間通訊

最復雜的情況就是在不同節(jié)點上的Pod需要互相通訊,由于Pod本身會經(jīng)常在不同節(jié)點間漂移,因此Pod對應的IP地址也需要動態(tài)地路由到不同節(jié)點上。

在公有云環(huán)境下,最常用的方案就是直接通過VPC所提供的路由表功能幫助網(wǎng)絡流量到達正確的目的地。由于VPC內(nèi)的所有流量都通過VPC本身提供的虛擬交換機進行轉發(fā),當一個Pod需要訪問另一個Pod時,如果節(jié)點發(fā)現(xiàn)訪問對象的IP地址不在本節(jié)點上,流量就會通過節(jié)點的根網(wǎng)絡設備發(fā)送到VPC中的虛擬交換機,交換機再通過路由表規(guī)則將流量正確轉發(fā)到目標Pod IP所在的節(jié)點上,再由節(jié)點內(nèi)的netns轉發(fā)到目的Pod。

百度云容器引擎CCE即采用了這種方案,CCE服務將會幫助用戶動態(tài)維護路由表規(guī)則,將容器網(wǎng)絡中的地址通過路由表規(guī)則映射給集群內(nèi)的各個節(jié)點IP,從而確保訪問Pod的流量轉發(fā)到正確的節(jié)點中。這種方案無需經(jīng)過額外的Overlay網(wǎng)絡層,因此具備較高的網(wǎng)絡性能。

如果用戶不在公有云環(huán)境使用Kubernetes,或者不具備自動更新路由表規(guī)則的能力,就需要在Kubernetes中集成其它的網(wǎng)絡方案,其中最常見的包括Flannel和Calico。

  • Flannel是一種overlay網(wǎng)絡方案。簡單來講,就是通過在節(jié)點中部署一個叫做flanneld的進程來構建一個跨節(jié)點的容器網(wǎng)絡空間,該進程通過etcd來管理所有Pod的地址資源,記錄每個Pod所在的節(jié)點地址,然后將節(jié)點內(nèi)通過cbr0向外發(fā)送的數(shù)據(jù)包再次打包,利用集群網(wǎng)絡將數(shù)據(jù)包發(fā)送到目標flanneld上,從而實現(xiàn)Pod跨節(jié)點的通訊。但是由于flannel方案本身引入了多個網(wǎng)絡組件,且在通訊過程中需要對數(shù)據(jù)進行再次打包,因此會引入一些網(wǎng)絡的時延損耗。
  • Calico方案則是利用每個節(jié)點的Linux Kernel來實現(xiàn)一個vRoute進行數(shù)據(jù)轉發(fā),每個vRoute通過BGP協(xié)議把自己所在節(jié)點上運行的Pod路由信息向整個Calico網(wǎng)絡內(nèi)傳播,這樣保證最終所有的Pod間的通訊都可以直接通過IP路由的方式實現(xiàn)。Calico網(wǎng)絡方案直接利用節(jié)點所在的網(wǎng)絡結構,不需要額外的隧道或者Overlay網(wǎng)絡,因此同樣具備較高的網(wǎng)絡性能。但是Calico本身的部署相對來講比較復雜,對用戶的要求較高。

下期內(nèi)容預告

本期我們介紹了容器網(wǎng)絡所解決的問題以及常見的方案,希望可以幫助大家更好地理解Kubernetes的網(wǎng)絡架構。下期我們將帶來集群管理的最后一部分內(nèi)容:存儲管理。敬請期待!

關注百度云微信公眾號,了解和體驗百度云容器引擎CCE。

極客網(wǎng)企業(yè)會員

免責聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責。本網(wǎng)站對有關資料所引致的錯誤、不確或遺漏,概不負任何法律責任。任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權或存在不實內(nèi)容時,應及時向本網(wǎng)站提出書面權利通知或不實情況說明,并提供身份證明、權屬證明及詳細侵權或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關文章源頭核實,溝通刪除相關內(nèi)容或斷開相關鏈接。

2019-03-06
如何做容器化集群管理?保障容器能被有序訪問是關鍵
我們在搭建集群時就已經(jīng)確保了所有工作節(jié)點在網(wǎng)絡上是互通的,但是由于同一個節(jié)點上可能同時運行多個容器,并且容器本身也隨時可能在節(jié)點之間移動,因此Kubernetes需要一套容器網(wǎng)絡方案來保障訪問某個指定

長按掃碼 閱讀全文