1. 程式人生 > >基於flannel的叢集網路_Kubernetes中文社群

基於flannel的叢集網路_Kubernetes中文社群

1、Docker網路模式

在討論Kubernetes網路之前,讓我們先來看一下Docker網路。Docker採用外掛化的網路模式,預設提供bridge、host、none、overlay、maclan和Network plugins這幾種網路模式,執行容器時可以通過–network引數設定具體使用那一種模式。

  • bridge:這是Docker預設的網路驅動,此模式會為每一個容器分配Network Namespace和設定IP等,並將容器連線到一個虛擬網橋上。如果未指定網路驅動,這預設使用此驅動。
  • host:此網路驅動直接使用宿主機的網路。
  • none:此驅動不構造網路環境。採用了none 網路驅動,那麼就只能使用loopback網路裝置,容器只能使用127.0.0.1的本機網路。
  • overlay:此網路驅動可以使多個Docker daemons連線在一起,並能夠使用swarm服務之間進行通訊。也可以使用overlay網路進行swarm服務和容器之間、容器之間進行通訊,
  • macvlan:此網路允許為容器指定一個MAC地址,允許容器作為網路中的物理裝置,這樣Docker daemon就可以通過MAC地址進行訪問的路由。對於希望直接連線網路網路的遺留應用,這種網路驅動有時可能是最好的選擇。
  • Network plugins:可以安裝和使用第三方的網路外掛。可以在Docker Store或第三方供應商處獲取這些外掛

在預設情況,Docker使用bridge網路模式,bridge網路驅動的示意圖如下,此文以bridge模式對Docker的網路進行說明。

1.1 bridge網路的構建過程如下:

1)安裝Docker時,建立一個名為docke0的虛擬網橋,虛擬網橋使用“10.0.0.0 -10.255.255.255 “、”172.16.0.0-172.31.255.255″和“192.168.0.0——192.168.255.255”這三個私有網路的地址範圍。

通過 ifconfig 命令可以檢視docker0網橋的資訊:

通過 docker network inspect bridge 可以檢視網橋的子網網路範圍和閘道器:

2)執行容器時,在宿主機上建立虛擬網絡卡veth pair裝置,veth pair裝置是成對出現的,從而組成一個數據通道,資料從一個裝置進入,就會從另一個裝置出來。將veth pair裝置的一端放在新建立的容器中,命名為eth0

;另一端放在宿主機的docker0中,以veth為字首的名字命名。通過 brctl show 命令檢視放在docker0中的veth pair裝置

1.2 外部訪問

bridge的docker0是虛擬出來的網橋,因此無法被外部的網路訪問。因此需要在執行容器時通過-p和-P引數對將容器的埠對映到宿主機的埠。實際上Docker是採用 NAT的 方式,將容器內部的服務監聽埠與宿主機的某一個埠port 進行繫結,使得宿主機外部可以將網路報文傳送至容器。

1)通過-P引數,將容器的埠對映到宿主機的隨機埠:

$ docker run -P {images}

2)通過-p引數,將容器的埠對映到宿主機的制定埠:

$ docker run -p {hostPort}:{containerPort} {images}

2、Kubernetes網路模式

Kubernetes與Docker網路有些不同。Kubernetes網路需要解決下面的4個問題:

  • 叢集內:
    • 容器與容器之間的通訊
    • Pod和Pod之間的通訊
    • Pod和服務之間的通訊
  • 叢集外:
    • 外部應用與服務之間的通訊

因此,Kubernetes假設Pod之間能夠進行通訊,這些Pod可能部署在不同的宿主機上。每一個Pod都擁有自己的IP地址,因此能夠將Pod看作為物理主機或者虛擬機器,從而能實現埠設定、命名、服務發現、負載均衡、應用配置和遷移。為了滿足上述需求,則需要通過叢集網路來實現。

在本文主要分析容器與容器之間,以及Pod和Pod之間的通訊;Pod和服務之間,以及外部應用與服務之間的通訊請參考《Kubernetes-核心資源之Service》和《Kubernetes-核心資源之Ingress》。

2.1 同一個Pod中容器之間的通訊

這種場景對於Kubernetes來說沒有任何問題,根據Kubernetes的架構設計。Kubernetes建立Pod時,首先會建立一個pause容器,為Pod指派一個唯一的IP地址。然後,以pause的網路名稱空間為基礎,建立同一個Pod內的其它容器(–net=container:xxx)。因此,同一個Pod內的所有容器就會共享同一個網路名稱空間,在同一個Pod之間的容器可以直接使用localhost進行通訊。

2.2 不同Pod中容器之間的通訊

對於此場景,情況現對比較複雜一些,這就需要解決Pod間的通訊問題。在Kubernetes通過flannel、calic等網路外掛解決Pod間的通訊問題。本文以flannel為例說明在Kubernetes中網路模型,flannel是kubernetes預設提供網路外掛。Flannel是由CoreOs團隊開發社交的網路工具,CoreOS團隊採用L3 Overlay模式設計flannel, 規定宿主機下各個Pod屬於同一個子網,不同宿主機下的Pod屬於不同的子網。

flannel會在每一個宿主機上執行名為flanneld代理,其負責為宿主機預先分配一個子網,併為Pod分配IP地址。Flannel使用Kubernetes或etcd來儲存網路配置、分配的子網和主機公共IP等資訊。資料包則通過VXLAN、UDP或host-gw這些型別的後端機制進行轉發。

看一下flannel在Kubernetes中執行的整體過程:

1)設定叢集網路

flannel預設使用etcd作為配置和協調中心,首先使用etcd設定叢集的整體網路。通過如下的命令能夠查詢網路配置資訊:

$ etcdctl ls /coreos.com/network/config

2)設定Node節點上的子網

基於在etcd中設定的網路,flannel為每一個Node分配IP子網。

#獲取子網列表

$ etcdctl ls /coreos.com/network/subnets

#獲取子網資訊

$ etcdctl ls /coreos.com/network/subnets/{IP網段}

3)在每個Node上啟動flannelid

flannel在每個Node上啟動了一個flanneld的服務在flanneld啟動後,將從etcd中讀取配置資訊,並請求獲取子網的租約。所有Node上的flanneld都依賴etcd cluster來做集中配置服務,etcd保證了所有node上flanned所看到的配置是一致的。同時每個node上的flanned監聽etcd上的資料變化,實時感知叢集中node的變化。flanneld一旦獲取子網租約、配置後端後,會將一些資訊寫入/run/flannel/subnet.env檔案。

$ cat /var/run/flannel/subnet.env

4)建立虛擬網絡卡

在Node節點上,會建立一個名為flannel.1的虛擬網絡卡。

$ ip addr show flannel.1

5)建立Docker網橋

併為容器配置名為docker0的網橋,實際是通過修改Docker的啟動引數–bip來實現的。通過這種方式,為每個節點的Docker0網橋設定在整個叢集範圍內唯一的網段,從保證創建出來的Pod的IP地址是唯一。

$ ip addr show docker0

6)修改路由表

flannel會對路由表進行修改,從而能夠實現容器跨主機的通訊。

$ route -n

2.3 資料傳遞過程

在源容器宿主機中的資料傳遞過程:

1)源容器向目標容器傳送資料,資料首先發送給docker0網橋

在源容器內容檢視路由資訊:

$ kubectl exec -it -p {Podid} -c {ContainerId} -- ip route

2)docker0網橋接受到資料後,將其轉交給flannel.1虛擬網絡卡處理

docker0收到資料包後,docker0的核心棧處理程式會讀取這個資料包的目標地址,根據目標地址將資料包傳送給下一個路由節點:

檢視源容器所在Node的路由資訊:

$ ip route

3)flannel.1接受到資料後,對資料進行封裝,併發給宿主機的eth0

flannel.1收到資料後,flannelid會將資料包封裝成二層以太包。

Ethernet Header的資訊:

  • From:{源容器flannel.1虛擬網絡卡的MAC地址}
  • To:{目錄容器flannel.1虛擬網絡卡的MAC地址}

4)對在flannel路由節點封裝後的資料,進行再封裝後,轉發給目標容器Node的eth0

由於目前的資料包只是vxlan tunnel上的資料包,因此還不能在物理網路上進行傳輸。因此,需要將上述資料包再次進行封裝,才能源容器節點傳輸到目標容器節點,這項工作在由linux核心來完成。

Ethernet Header的資訊:

  • From:{源容器Node節點網絡卡的MAC地址}
  • To:{目錄容器Node節點網絡卡的MAC地址}

IP Header的資訊:

  • From:{源容器Node節點網絡卡的IP地址}
  • To:{目錄容器Node節點網絡卡的IP地址}

通過此次封裝,就可以通過物理網路傳送資料包。

在目標容器宿主機中的資料傳遞過程:

5)目標容器宿主機的eth0接收到資料後,對資料包進行拆封,並轉發給flannel.1虛擬網絡卡;

6)flannel.1 虛擬網絡卡接受到資料,將資料傳送給docker0網橋;

7)最後,資料到達目標容器,完成容器之間的資料通訊。

參考資料

作者簡介:
季向遠,北京神舟航天軟體技術有限公司產品經理。本文版權歸原作者所有。