kubernetes容器網路介面(CNI) midonet網路外掛的設計與實現

weixin_33840661發表於2017-03-23

相關原理概述

先來講講什麼是CNI?

CNI(容器網路介面)是一種操作容器網路規範,包含方法規範,引數規範等。
CNI只關心容器的網路連線,在容器建立時分配網路資源,並在刪除容器時刪除分配的資源。因為這個焦點,CNI有廣泛的支援,規格易於實現。CNI介面只需要實現兩個方法,一個建立容器時呼叫,一個刪除容器時呼叫。

image

Kubernetes如何支援和執行遵循CNI規範的外掛

kubernetes首先以外掛的形式完成(pod)容器的網路資源設定。內建的外掛包括:cni,kubenet,hostport等。這裡簡單說說kubenet。這是一個簡單的網路外掛,每臺機器上建立一個br0網橋,根據PodCIDR為每個pod設定ip連線到br0網橋上。次方式可結合一些網路路由工具完成一個小規模的叢集網路pod互聯。我們主要講CNI外掛。kubernetes以cni外掛來支援cni規範,呼叫其他廠商和個人開發的遵循cni規範的各種網路外掛,例如Calico,Flannel等。k8s預設情況下cni模式不支援埠對映等。k8s將容器網路設定none,完全交給外掛去管理容器網路資源。
image

上文多次提到的網路資源是什麼?

容器網路資源包括:虛擬網路卡,IP地址,DNS,網路路由等等。容器使用獨立的網路名稱空間,可以具有自己的網路資源資訊。這些資訊資料由不同的CNI外掛根據不同的SDN網路的實現給容器配置。

MidoNet SDN網路

MidoNet是由日本的SDN公司Midkura研發的一款網路虛擬化軟體,其基於底層物理設施來實現網路虛擬化,具有分散式、分散、多層次的特點,主要作為OpenStack中的預設網路元件,可以讓虛擬網路解決方案,特別是專為網路基礎設施設計的方案,為雲平臺如OpenStack服務,並且將其網路存貯棧虛擬化。MidoNet為每個租戶分配一個邏輯router,租戶與租戶之間是相互隔離的,租戶內部之間是能夠相互通訊的,Midonet支援L2交換、L3路由、L4負載均衡

有狀態和無狀態NAT,邏輯和分散式防火牆,BGP與ECMP支援。其架構主要包含以下元件:

Midolman(Midonet Agent):Midonet

Agent安裝在各個計算節點,負責建立網路流量控制和提供分散式Midonet網路服務,路由,NAT等他把相關的虛擬網路資訊存放到NSDB。

Network State

Database(NSDB):儲存網路配置和狀態,網路拓撲,路由,Midonet不集中處理網路功能,由Midonet Agent處理,Midonet Agent會跟NSDBs做實時同步當有變化時候會及時同步並且更新NSDB
MidoNet支援大規模SDN叢集,其架構理論上支援上萬節點。我們可以使用MidoNet完成k8s叢集內租戶內Pod網路互聯。

MidoNet多租戶下網路結構模型

SDN(軟體定義網路),Midonet軟體定義你所熟知的網路元件。以下簡單介紹幾個核心的軟體定義概念:

  • Router(路由器)
    一個租戶對應一個Router,連線到同一個Router的Bridge網路互通。Midonet會建立一個PrivierRouter,所有租戶Router連線到PrivierRouter與外網互通。等價於一個路由器內網互通,連線上級路由器接入公網。

  • Bridge(網橋)
    一個租戶下可以有多個Bridge,每個Bridge使用不同的網段。例如一個Bridge網段為192.168.0.0/24,最多可以有253個虛擬裝置連線到本Bridge。

  • Port(裝置通訊埠)
    Router與Router之間,Router與Bridge之間的通訊介面。

  • Route(路由)
    路由規則,給Router定義流量包轉發埠的規則。

  • Rule(過濾規則)
    定義包過濾條件。類似於iptables。

image

基於MidoNet的kubernetes CNI外掛實現

Midonet資料交換工作在三層,但是其本身不提供IP地址管理(IPAM),因此基於Midonet的cni外掛需要完成以下工作:IPAM,租戶Router、Bridge建立,容器網路卡建立,以及所有端到端連線和路由過濾規則建立。

IPAM

需要完成兩個層面的IP管理,Router級別的地址管理,每一個Router具有一個IP地址,且全域性唯一不衝突。每一個Bridge具有一個唯一網段,連線的虛擬網路卡具有全域性唯一IP 。
IPAM有很多實現方式,CNI外掛是無狀態應用,或許你需要一個守護程式來完成IPAM工作。基於簡化架構的思路,我們使用ETCD來儲存IP資料,直接由外掛來操作ETCD。完成IP的使用和釋放。

租戶網路初始化

當新租戶第一次建立容器時進行租戶虛擬裝置的初始化建立,上文我們已經介紹了一個租戶需要建立的虛擬裝置有哪些,這裡我講講細節。
Midonet提供了Rest-API來操作虛擬裝置。這裡注意,根據使用的不同版本的Midonet使用不同版本的API。
https://github.com/barnettZQG/golang-midonetclient
封裝了golang版的Midonet api操作方法,支援1.和5.API版本。
建立步驟如下:

  1. 建立租戶,呼叫Keystone API。

  2. 建立Router,幷包含建立進出Chain。

  3. 建立PrivierRouter Port並賦IP,建立Router Port並賦IP。建立PortLink連線兩個Port。

  4. 為前面建立的Chain建立對應的路由規則

  5. 為前面建立的Port建立包過濾規則

  6. 建立一個預設的Bridge。並建立Port連上Router。

  7. 儲存以上建立的相關資料進ETCD.

容器網路卡建立和網路繫結

Virtual Ethernet Pair

簡稱veth pair,是一個成對的埠,所有從這對埠一 端進入的資料包都將從另一端出來,反之也是一樣.其兩端可存在於不同的網路空間(Network Namespace)。容器建立成功後具有一個網路空間,k8s此時呼叫CNI外掛ADD方法進行網路設定。外掛首先建立一對Veth pair。將其一端置於宿主機網路空間,呼叫Midonet 繫結API將其與Bridge一個Port繫結。另一端在容器內並賦予IP地址,根據當前使用的Bridge網段。
與Docker0網路卡部分原理一致。

設定容器內路由規則

將預設路由設定到上文建立的網路卡上。例如上文建立的網路卡命名為eth0。

設定DNS

根據需要設定一些DNS資訊。

怎麼實現操作?

1.使用shell命令。

ip link *
ip netns *
ip address *
ip route *

以上命令詳細使用方法網上很多了,這裡不再描述。

  1. golang netlink library

https://github.com/vishvananda/netlink
定義了關於網路卡相關與linux核心通訊的使用者空間的相關介面。

CNI外掛實現的注意事項

  1. CNI外掛的新增和刪除操作應該具有冪等性,即同樣的引數傳入不管呼叫多少次都應該有相同的效果。

  2. CNI外掛應該支援併發性,主要是租戶相關元件的建立和IP地址分配的強一致性。

  3. CNI外掛有一定的規範,請參考:https://github.com/containernetworking/cni

好雨雲Midonet cni外掛開源

好雨雲開源基於ETCD版的的midonet cni外掛具有上文提到的所有功能和特性。
github:https://github.com/goodrain/midonet-cni

相關文章