1. 程式人生 > >OpenStack虛機網絡卡的建立過程

OpenStack虛機網絡卡的建立過程

OpenStack最基本和常用的操作就是啟動虛機。虛機啟動的過程中涉及很多內容,其中非常重要的一個環節就是建立並繫結虛機的虛擬網絡卡。虛機的建立和管理是Nova的任務,虛機網路的建立和管理是Neutron的任務,而虛機網絡卡,作為連線虛機和虛機網路的橋樑,其建立和管理則同時涉及了Nova和Neutron。這次介紹一下,OpenStack中虛機的網絡卡的建立過程。雖然本文的介紹將基於OpenVSwitch,但是你可以發現,很少有特殊於OpenVSwitch的地方,所以其他的二層機制(例如:Linux Bridge)過程都是類似的。

注:本文的所有分析都是基於OpenStack 17年上半年的程式碼(Pike版本),因此本文只反應OpenStack在那個時間點的行為。

先假設我們有一個典型的基於OpenVSwitch的OpenStack環境,服務的分佈如下。
這裡寫圖片描述

Neutron L2 Agent上線

首先是所有的服務上線,看 neutron-openvswitch-agent 的啟動。
● OpenVSwitch agent 啟動,註冊一個定時程式:

neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.__init__

● 在定時程式內部,通過RPC向Neutron Server定時上報自己的狀態:

neutron.plugins
.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent._report_state

● 在Neutron Server,對應的RPC處理方法中,Neutron Server將Agent上報的狀態寫入自己的DB:

 neutron.db.agents_db.AgentExtRpcCallback.report_state

到此為止,Neutron Server 知道了Neutron OpenVSwitch Agent的狀態及相關資訊,這一步的示意圖如下所示。
這裡寫圖片描述

設想有這麼一個場景,如果同時有N個計算節點,由於電源問題,這些計算節點同時斷電重啟。那麼當這些計算節點上的OpenVSwitch Agent恢復之後,由於啟動時間比較集中,它們會在一個相對集中的時間點,定時向Neutron Server上報自己的狀態。這涉及到Neutron Server處理RPC請求,寫DB,還有一些邏輯處理。所以當N足夠大時,會週期性的給Neutron Server帶來高負荷。這是實際應用和優化需要注意的一個地方。

建立一個虛機,OpenStack建立邏輯埠(port)

接下來通過呼叫Nova的REST API建立一個虛機,並且nova scheduler將虛機分佈到了計算節點。Nova計算節點上的nova-compute程序會:
● 呼叫Neutron REST API建立埠(port):

nova.network.neutronv2.api.API.allocate_for_instance

這裡建立埠只是邏輯驗證,Neutron Server會在自己的DB裡面建立一個相應的,基本為空的埠
● 根據Nova掌握的資訊,更新埠:

nova.network.neutronv2.api.API._update_ports_for_instance

這裡nova向Neutron傳遞的埠資訊包括(列舉一部分):
device_id: 虛機的uuid
device_owner: 由compute+虛機所在的Nova Availability Zone組成的字串,例如“compute: nova”
dns_name: 虛機的hostname, 通常為虛機name
binding:host_id: nova-compute所在的host id,可以是hostname,也可以是IP地址
binding:profile: 一些額外的資訊,例如SRIOV資訊

Neutron Server在收到這些資訊之後,主要處理流程如下:
● nova-compute呼叫Neutron Server更新埠,請求在這裡處理:neutron.plugins.ml2.plugin.Ml2Plugin.update_port
● 之後處理port bind:neutron.plugins.ml2.plugin.Ml2Plugin._bind_port
● 呼叫到Neutron ML2的Mechanism Manger做port bind:neutron.plugins.ml2.manager.MechanismManager._bind_port_level
● 再呼叫到Neutron ML2的OpenVSwitch Mechanism Driver做實際的port bind:neutron.plugins.ml2.drivers.mech_agent.AgentMechanismDriverBase.bind_port
1. 雖然這是個通用類,但是OVS Mechanism Driver繼承自這個類。
2. 在這個方法裡面,會檢查在指定的host上有沒有相應的L2 Agent,所以這一步依賴之前一步的Neutron OpenVSwitch Agent狀態上報
3. 這裡的host資訊來自於nova-compute傳遞過來的binding:host_id
● 將OVS對應的vif_typevif_details兩個屬性傳遞給port:neutron.plugins.ml2.drivers.mech_agent.SimpleAgentMechanismDriverBase.try_to_bind_segment_for_agent
● OVS的vif_typevif_details在OVS Mechanism Driver的初始化函式裡面定義:neutron.plugins.ml2.drivers.openvswitch.mech_driver.mech_openvswitch.OpenvswitchMechanismDriver.__init__
這裡,定義了OVS對應的vif_type是“ovs”,而vif_details包含了一些輔助資訊

vif_details裡面包含了一個欄位OVS_HYBRID_PLUG,如果這個欄位為True,則最後虛機的網絡卡和 br-int 之間會有一個 Linux Bridge 來應用 iptables 規則。如果你瞭解過OpenStack底層OpenVSwitch網絡卡連線方式,那麼你一定見過下面這張圖,其中淺紫色的qbrXXX,就是因為這個欄位為True才會在後面的步驟被建立。
這裡寫圖片描述

這部分Neutron的行為都是在ML2中完成。這部分除了更新Neutron自身的資料之外,比較重要的就是將vif_typevif_details作為port的一部分資料,返回給nova-compute。到此為止,虛機的網絡卡還沒有建立,所有的操作都還只是在邏輯層面,只有資料庫的資料發生了變化。並且,在Neutron的資料庫中,port的狀態現在是Down。但是,Nova和Neutron都知道了接下來要建立的網絡卡的具體資訊,這一步的實際意義在於兩個相對獨立的專案之間的資料同步。現在,OpenStack整體示意圖如下所示:
這裡寫圖片描述

Nova-compute建立虛擬網絡卡

雖然說Neutron是OpenStack裡面的網路服務專案,但是OpenStack裡面的虛機網絡卡,卻是由Nova建立的。nova-compute在從Neutron Server拿到了埠的資訊之後(通過update port的返回資料):
● 呼叫相應的虛擬化Driver,繼續建立虛機:nova.compute.manager.ComputeManager._build_and_run_instance
● 在Driver內部,建立網路相關內容:nova.virt.libvirt.driver.LibvirtDriver.spawn
● 在Driver內部,通過呼叫os-vif庫,建立虛機網絡卡。由於nova-compute現在已經知道了虛機網絡卡的所有資訊,適用於虛機的網絡卡被創建出來:nova.virt.libvirt.driver.LibvirtDriver.plug_vifs
至此,虛機的虛擬網絡卡真正的創建出來了。但是,在Neutron的資料庫中,port的狀態現在是Down。到此為止,OpenStack的整體示意圖如下所示:
這裡寫圖片描述

Neutron檢測虛擬網絡卡狀態並更新port狀態

虛機的虛擬網絡卡被插入到OVS網橋上,對於Neutron來說,接下來就是接管這個網絡卡。
● Neutron OpenVSwitch Agent程序中會監聽OVS網橋的狀態:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.rpc_loop
● 當發現有新增的虛擬網絡卡時,先從Neutron Server獲取詳細的網絡卡資訊:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.treat_devices_added_or_updated

nova-compute在建立虛擬網絡卡的時候,已經將Neutron port id和一些其他資訊寫入到OVS port/interface中,因此Neutron從新增的虛擬網絡卡就能知道對應的port是那個,下圖是擷取的OVS資料,裡面的iface-id就是Neutron port對應的ID
這裡寫圖片描述
● Neutron OpenVSwitch Agent本地更新完虛擬網絡卡之後,再通過RPC通知Neutron Server埠上線:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent._bind_devices
至此,Neutron已經接管了虛擬網絡卡,並且在Neutron的資料庫中,port的狀態現在是Active。Neutron從這個時候開始正式接管虛機網路。OpenStack整體示意圖如下所示:
這裡寫圖片描述

總結

所以,簡單來說,在OpenStack中,首先需要各個服務上線;之後Nova會建立邏輯網絡卡,但是Nova只知道虛機所在的host;Neutron會根據所在的host,判斷出相應的網路虛擬化機制,例如ovs,linuxbridge,Neutron會把這些資訊回傳給Nova;Nova拿到這些資訊,呼叫相應的方法建立虛擬網絡卡,並接入到虛機;Neutron會監聽網橋上埠的變化,發現有上線的埠,與自己本身的資料進行匹配,匹配到了之後接管這個虛擬網絡卡。對於Neutron來說,它不關心虛擬網絡卡接的是虛機還是容器還是別的什麼,它只能看到虛擬網絡卡。

作者簡介:肖巨集輝,畢業於中科院研究生院,8年的工作經驗,其中6年雲端計算開發經驗,OpenStack社群積極活躍,有超過300個commit和超過30000行程式碼的貢獻。目前關注SDN/NFV等虛擬網路技術。本文所有觀點僅代表作者個人觀點,與作者現在或者之前所在的公司無關。

轉載自 SDNLAB 微信公眾號。

相關推薦

OpenStack建立過程

OpenStack最基本和常用的操作就是啟動虛機。虛機啟動的過程中涉及很多內容,其中非常重要的一個環節就是建立並繫結虛機的虛擬網絡卡。虛機的建立和管理是Nova的任務,虛機網路的建立和管理是Neutron的任務,而虛機網絡卡,作為連線虛機和虛機網路的橋樑,其建立

KVM修改模式:由NAT模式改為Bridge模式

1)關閉虛機# virsh  shutdown  vm1 2)編輯虛機配置檔案# virsh  edit  vm1 <interface type='default'> 改為<interface type='bridge'> 

如何使用筆記本無線建立無線熱點?

使用筆記本無線網絡卡做為熱點,為其他無線裝置(手機,平板)提供上網服務,主要滿足兩個條件 1.作業系統為 win7(win8未做測試) 2.筆記本無線網絡卡的【支援的承載網路】項顯示為【是】,見下圖。 如果不支援可以嘗試更新網絡卡驅動來進一步測試。本人的筆記本就是因為驅動較老不支援

如何使用筆記本無線建立無線熱點補充(本地連線)

最近因為公司無線網路出現故障,筆記本暫時無法通過無線網路上網,但是本地連線網路可用,還是挺愉快的,想了下,是否可以通過筆記本的本地網路來實現手機上網?雖然意義不大,但還是測試了下,下面將步驟記錄下來。 1.將無線網絡卡裝置開啟。 2.啟動熱點服務,以管理員身份執行下面的啟動指令碼。 &n

linux程式設計獲取本資訊

轉自:https://blog.csdn.net/shaderdx/article/details/78403437 ifaddrs結構體定義如下: struct ifaddrs    {      &

C++ 捕獲本的IP包並對其解析的實現

程式設計要求:捕獲本機網絡卡的IP包,對捕獲的IP包進行解析。要求必須輸出以下欄位:版本號、總長度、標誌位、片偏移、協議、源地址和目的地址。 TCP/IP協議定義了一個在因特網上傳輸的包,稱為IP資料報(IP Datagram).這是一個與硬體無關的虛擬包,由首部和資料兩

openstack 例項增加

openstack中某個例項新增加一個網絡卡有兩種方式 一種是用通過openstack增加 這種增加不但會增加一個虛擬網絡卡,還會自動分配一個ip ##設定環境變數 source .admin_openrc.sh ##檢視網路 neutron net-list neutron CLI

Openstack中單使用多ip

文章來自作者維護的社群微信公眾號【虛擬化雲端計算】)建立虛擬機器時主機上會有一條iptables 用來將ip和mac繫結,用來防止arp欺騙。在需要給單個網絡卡配置多個ip的場景下(例如keepalive)另外新增的ip地址是無法與外界通訊的。 兩種方法來解決。第一種是使用a

VMware克隆虛擬機器,克隆啟動不了解決方案

VMware裡面克隆了個虛擬機器,克隆機網絡卡啟動不了,啟動報錯: Device eth0 does not seem to be present, delaying initialization.[FAILED] 使用克隆後的虛擬機器時發現原來在基本系統中的網絡卡eth

VC++獲取本及網路流量

使用GetAdaptersInfo 和 GetIfTable獲取本機網絡卡資訊以及流量等資訊。 #include "stdafx.h" #include <WinSock2.h> #include <Iphlpapi.h>

C# 獲取本資訊、個數、描述資訊、型別、速度等

程式碼比較簡單,直接上圖上碼。實現程式碼有註釋,以下是該例子的完整程式碼。引入名稱空間:using System.Net.NetworkInformation; using System.Net;完整程式碼:namespace NetworkInterfaceExample

c++獲取本資訊(IP,MAC,閘道器,子掩碼)

int getIP_Mac_GateMac(int adapter, char** ip, int mac[6], int gateMac[6]) //adapter:選擇的網絡卡序號 {//PIP_ADAPTER_INFO結構體指標儲存本機網絡卡資訊PIP_ADAPT

獲取本IP及對應的mac

#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h>

IPv6通訊原理(1) - 不能忽略的啟動過程

本文主題:通過抓包分析,深入觀察網絡卡啟動過程的每個步驟,從而逐步掌握通訊原理。

通過設定雙實現VirtualBox上網及主宿互訪

最近,經過一些研究,終於調通了VirtualBox虛擬機器互連、主宿機互連、以及主宿機連線網際網路。下面分享一下。 1、VirtualBox中的虛擬網絡卡。VirtualBox安裝完成後,會在系統中裝一塊虛擬網絡卡,我們在管理->全域性設定中可以看到。這塊網絡卡是

給nova新增

場景 虛機只有一張網絡卡能通業務網,但是需要有另一張網絡卡能通管理網。 以下手動給虛機新增一張網絡卡。 VM有nic-1通過br-int連線到物理網絡卡eth0上,需要增加nic-2通過br-bond0連線到物理interface bond0.706上

VirtualBox下為Ubuntu新增第二塊

問題描述 因為做Docker網路實驗,需要將原先Ubuntu虛機的一塊“橋接”網絡卡改為“HostOnly”網絡卡,並且新增另一塊“NAT”網絡卡。幾經周折發現只有第一塊網絡卡可以正確配置,ifconfig里根本看不到有第二塊網絡卡。 查詢問題 於是上

Android5.1系統啟動過程中啟動有線併為其分配靜態IP地址

Android5.1系統啟動過程中啟動有線網絡卡併為其分配靜態IP地址 遇到這個問題的時候剛開始自己以為在init.rc中新增兩行命令就能解決問題,可是後來發現並非如此簡單,所以用下面的文字記錄一下自己解決這個問題的方法。 首先想到的方法是在init.rc中用ifup eth0命令將埠啟動起

安裝VMware後,本網路介面卡中沒有虛擬VMnet1、VMnet8

1、開啟本機服務,開啟相關的服務。   2、重置虛擬網路編輯器 1>開啟VMware,點選下圖左上角標註的"編輯",然後選中並進入"虛擬網路編輯器"。 2>還原預設設定   如果 "還原預設設定" 如上圖一

驅動收發包過程

網絡卡 網絡卡工作在物理層和資料鏈路層,主要由PHY/MAC晶片、Tx/Rx FIFO、DMA等組成,其中網線通過變壓器接PHY晶片、PHY晶片通過MII接MAC晶片、MAC晶片接PCI匯流排 PHY晶片主要負責:CSMA/CD、模數轉換、編解碼、串並轉換 MAC晶片主要