在Docker中使用Open vSwitch建立跨主機的容器網路

語言: CN / TW / HK

本文介紹瞭如何使用Open vSwitch為Docker 1.9.0及以後版本提供網路支援。操作前請先確認你已經按照INSTALL.md編譯,或者通過包管理器安裝了Open vSwitch。

Docker從1.9.0版本之後提供了跨主機的網路支援。通過將Docker和Open vSwitch整合,則可以利用Open vSwitch virtual network(OVN)進行互聯互通。

安裝

要想使用OVN實現Docker的跨主機網路,Docker在啟動時必須指定分散式鍵值儲存服務,比如你打算使用Consul作為鍵值儲存,啟動Docker daemon時請使用如下引數:

docker daemon --cluster-store=consul://127.0.0.1:8500 \
--cluster-advertise=$HOST_IP:0

其中$HOST_IP是你主機本地IP。

OVN為容器提供了虛擬化的網路,目前OVN和Docker的整合,有兩種方式:即”underlay”模式和”overlay”模式。

在”underlay”模式下,OVN依賴於OpenStack為容器提供網路。此模式下,使用者可以讓虛擬機器中的容器、獨立虛擬機器(不執行任何容器)、物理機都連線到相同的邏輯網路下。這是種多租戶、多主機的解決方案。

在”overlay”模式下,OVN可以用來建立跨主機的容器間網路。此模式是單租戶(當然在不需要額外的網路隔離的情況下可以拓展成多租戶)、多主機的解決方案。此模式不依賴OpenStack。

無論哪種模式,想要讓容器使用OVN都必須在所有容器宿主機上安裝Open vSwitch。

Overlay模式

使用OVN的”overlay”模式要求的Open vSwitch最小版本是2.5。

初始化中心節點
在OVN的架構中,需要有一箇中心節點用來儲存網路定義。在需要部署的機器中選擇一臺作為中心節點,IP地址是$CENTRAL_IP。

通過以下命令啟動ovsdb-server,監聽在TCP的6640埠:

ovs-appctl -t ovsdb-server ovsdb-server/add-remote ptcp:6640

啟動ovn-northd守候程序,這個程序用來將Docker儲存在OVN_Northbound中的網路定義同步到OVN_Southbound中:

/usr/share/openvswitch/scripts/ovn-ctl start_northd

初始化各節點(僅需執行一次)
以下過程在每個你需要啟動容器的機器上僅執行一次(除非OVS資料庫清空後,任何其他清空執行多次都會帶來問題。)

下面的命令中,$LOCAL_IP指宿主機可以被訪問的IP地址,OVS將通過這個IP與其他宿主機通訊。$ENCAP_TYPE指通道型別。目前可選項是”geneve” 和 “stt”。(注意你的宿主機核心必須支援你選擇的$ENCAP_TYPE型別。這兩種型別都預設包含在了Open vSwitch的核心模組中。如果你的Open vSwitch核心模組來自於上游Linux發行版,那麼geneve最低支援的核心版本是3.18。發行版中的核心模組不支援stt。你可以通過lsmod | grep $ENCAP_TYPE來確認是否支援相應的模式。)

ovs-vsctl set Open_vSwitch . external_ids:ovn-remote="tcp:$CENTRAL_IP:6640" \
external_ids:ovn-encap-ip=$LOCAL_IP external_ids:ovn-encap-type="$ENCAP_TYPE"

最後,啟動ovn-controller,記得將啟動命令新增到系統啟動指令碼中。

/usr/share/openvswitch/scripts/ovn-ctl start_controller

啟動Open vSwitch驅動
預設情況下,Docker使用Linux bridge作為網路驅動,當然了它支援其他外部驅動。為了讓Docker使用Open vSwitch,你需要啟動Open vSwitch驅動。

Open vSwitch驅動使用了Python的flask模組來監聽Docker的網路API呼叫。所以如果你的主機還沒有安裝flask,使用以下命令安裝:

easy_install -U pip
pip install Flask

在所有準備執行Docker容器的機器上都要執行以下命令以啟動驅動:
ovn-docker-overlay-driver --detach

Docker內建的網路和OVN的網路概念非常一致,請查閱Docker的文件獲取更全面的命令指南,這裡只是個簡單的例子。

建立邏輯交換機
使用以下命令建立一個名為foo,子網為192.168.1.0/24的邏輯交換機。

NID=`docker network create -d openvswitch --subnet=192.168.1.0/24 foo`

列出所有邏輯交換機
docker network ls
你也可以在OVN的northbound資料庫中檢視邏輯交換機,通過以下命令:

ovn-nbctl --db=tcp:$CENTRAL_IP:6640 lswitch-list

將Docker容器連線到邏輯交換機
例如將一個busybox容器連線到邏輯網路foo上,只需要執行:

docker run -itd --net=foo --name=busybox busybox

列出所有邏輯埠
目前Docker尚未提供命令來列出交換機埠,所以你可以通過直接查詢OVN資料庫來檢視:

ovn-nbctl --db=tcp:$CENTRAL_IP:6640 lport-list $NID

建立邏輯交換機並將正在執行的容器連線

docker network create -d openvswitch --subnet=192.168.2.0/24 bar
docker network connect bar busybox

你可以通過如下命令斷開容器和邏輯交換機的連線
docker network disconnect bar busybox

刪除邏輯交換機
docker network rm bar

Underlay模式
此模式需要預先安裝執行OpenStack。

初始化各節點(僅需執行一次)
OpenStack租戶先要在他們的網路內建立單或多網路埠的虛擬機器。租戶需要先取得想要作為宿主機的埠ID(port-id)。可以通過以下命令取得虛擬機器關聯的網路埠ID:
nova list

然後執行:
neutron port-list --device_id=$id

在虛擬機器中,下載包含租戶資訊的OpenStack RC檔案(下文稱之為’openrc.sh’)。編輯並新增之前獲得的埠ID資訊到這個檔案中,例如:

#!/bin/bash
export OS_AUTH_URL=http://10.33.75.122:5000/v2.0
export OS_TENANT_ID=fab106b215d943c3bad519492278443d
export OS_TENANT_NAME="demo"
export OS_USERNAME="demo"
export OS_VIF_ID=e798c371-85f4-4f2d-ad65-d09dd1d3c1c9

建立Open vSwitch橋接
如果你的虛擬機器只有一個網絡卡(如’eth0′),你建立一個名為breth0的網橋,然後將eth0網絡卡上的IP和路由資訊全部轉移到網橋上。(如果有多塊網絡卡,你需要在想要傳送網路流量的那塊上進行這個操作。)

如果你使用DHCP服務獲取IP地址,首先需要停掉在物理網絡卡(如eth0)上監聽的DHCP客戶端,然後在新建立的網橋(如breth0)上啟動監聽。

根據你的虛擬機器的不同,你需要把以上操作設定到啟動指令碼中。

例如你的虛擬機器執行Debian/Ubuntu,可以參考openvswitch-switch.README.Debian。如果虛擬機器執行RHEL系統,參考README.RHEL。

啟動Open vSwitch網路驅動
Open vSwitch驅動使用了Python的flask模組來監聽Docker的網路API呼叫,也使用了OpenStack的python-neutronclient庫。如果你還沒有安裝他們,請先安裝:

easy_install -U pip
pip install python-neutronclient
pip install Flask

執行openrc檔案:
. ./openrc.sh

啟動網路驅動,並在詢問時提供你的OpenStack租戶密碼:

ovn-docker-underlay-driver --bridge breth0 --detach

接下來,你可以使用上文在Overlay模式中介紹的命令來使用Docker了。