OpenvSwitch實現kubernetes依賴的底層網絡


kubernetes網絡模型設計的一個基礎原則是:每個Pod都擁有一個獨立的IP地址,而且假定所有Pod都在一個可以直接連通的、扁平的網絡空間中(在GCE里面是現成的網絡模型)。在kubernetes中,IP是以Pod為單位進行分配的。一個Pod內部的所有容器共享一個網絡堆棧(實際上就是一個網絡命名空間,包括它們的IP地址、網絡設備、配置等都是共享的)。按照這個網絡原則抽象出來的一個Pod一個IP的設計模型也被稱作IP-per-Pod模型。在我們搭建k8s集群的過程中,需要自己實現這個網絡假設,將不同節點上的Docker容器之間的互相訪問先打通,然后運行k8s。目前有許多開源組件支持容器網絡模型,比如說Flannel、OpenvSwitch和Calico等。在本文中,我們利用OVS作為實現底層網絡(如下圖所示),僅實現了不同節點之間的docker0網橋之間的互通,沒有搭建基於OVS的完整kubernetes集群。

 

OpenvSwitch是一個開源的虛擬交換機軟件,OVS的網橋可以直接建立多種通信通道(隧道)如VxLAN,GRE,在k8s、Docker場景下,我們主要是建立L3到L3的隧道。在這里,我們采取VxLAN隧道的方式實現。

實驗拓撲如圖所示,在VMware上運行3台ubuntu16.04虛擬機。

當容器內的應用訪問另一個容器的地址時,數據包會通過容器內的默認路由發送給docker0網橋。OVS的網橋是作為docker0網橋的端口存在的,它會將數據發送給OVS網橋。OVS網絡已經通過配置建立了和其他OVS網橋的GRE/VxLAN隧道,自然能將數據送達對端的Node,並送往docker0及Pod。接下來進行實際操作。

1.安裝Docker

sudo apt-get install docker.io

2.安裝OpenvSwitch

sudo apt-get install openvswitch-switch

3.為docker0網橋重新分配IP

為了避免Docker創建的docker0地址產生沖突(因為Docker Daemon啟動且給docker0選擇子網時只有幾個備選列表,很容易產生沖突,我這里裝完docker,docker0網橋的地址都是172.17.0.1/16),所以我們要給docker0網橋重新分配IP地址,網上有很多種解決方案,眾說紛紜,我這里按照下面的步驟進行。首先,停止docker服務,然后將docker0網橋刪除,手動建立一個Linux網橋,然后手動給這個網橋配置IP地址范圍。

sudo service docker stop
sudo ip link set dev docker0 down
sudo brctl delbr docker0
sudo brctl addbr docker0
sudo ip addr add 172.17.30.1/24 dev docker0
sudo ip link set dev docker0 up

查看IP地址信息:

我這里配置是,master節點的docker0 IP地址為172.17.20.1,node1節點docker0 IP地址為172.17.10.1,node2節點docker0 IP地址為172.17.30.1。

4 .創建網橋和Vxlan隧道

建立OpenvSwitch的網橋br0,然后通過ovs-vsctl命令給ovs網橋增加VxLAN端口,添加端口時要將目標連接的NodeIP地址設置為對端的IP地址。(對於大型集群網絡,需要做自動化腳本來完成)

(1) 創建ovs網橋br0

分別在master,node1,node2節點上執行如下命令:

sudo ovs-vsctl add-br br0

(2) 創建Vxlan隧道連接到對端

首先建立master節點到node2節點之間的隧道:

在master節點執行:

sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan option:remote_ip=10.0.0.76

其中10.0.0.76是node2的ens33網卡地址。

在node2上執行:

sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan option:remote_ip=10.0.0.70

其中10.0.0.70是master的ens33網卡地址。

執行ovs-vsctl show可看到如下結果:

同理,建立master到node1之間的隧道,

在master上執行:

sudo ovs-vsctl add-port br0 vxlan2 -- set interface vxlan2 type=vxlan option:remote_ip=10.0.0.71

其中10.0.0.71是node1的地址,這里注意使用另外一個端口vxlan2來作為隧道的端口。

在node1上執行:

sudo ovs-vsctl add-port br0 vxlan2 -- set interface vxlan2 type=vxlan option:remote_ip=10.0.0.70

其中,10.0.0.70是master的IP地址。

執行ovs-vsctl可以看到:

master節點上的br0有兩個端口用來做隧道,vxlan1和vxlan2。對於node1和node2之間則不需要再建立額外的隧道了,后面可以看到二者之間的docker0網橋能夠相互ping通。

5.添加br0到本地docker0

sudo brctl addif docker0 br0

這個操作就相當於把兩個交換機給連上了,使得容器流量通過OVS流經tunnel。

6. 啟動br0與docker0網橋

sudo ip link set dev br0 up

sudo ip link set dev docker0 up

7. 添加路由規則

由於10.0.0.70與10.0.0.71以及10.0.0.76的docker0網段分別為172.17.20.1/24、172.17.10.1/24和172.17.30.1/24,這幾個網段的路由都需經過本機的docker0網橋路由,其中一個24網段是通過OVS的VxLAN隧道到達對端的,因此需要在每個node上添加通過docker0網橋轉發172.17.0.0/16段的路由規則:

sudo ip route add 172.17.0.0/16 dev docker0

8.清空Docker自帶的iptables規則以及Linux規則

#iptables –t nat –F; iptables –F

9.各節點上docker0之間的互通測試

master節點ping node1

 

 

master ping node2

 

node1 ping master和node2

 

node2 ping master和node1 :

 

10.wireshark抓包

監聽br0網橋,在br0網橋上並沒有VxLAN報文

在ens33上抓包,發現了VxLAN封裝的ping包報文通過,說明VxLAN是在承載網的物理網絡上完成的封包過程。

至此,基於OVS的網絡搭建成功。kubernetes還有許多優秀的開源網絡組件,大家各有優勢和缺點,有時間做一個匯總。

 

 

參考資料:

 《kubernetes權威指南》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM