OpenStack虛機(jī)網(wǎng)卡的創(chuàng)建過程
時(shí)間:2023-06-25 18:45:01 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-06-25 18:45:01 來源:網(wǎng)站運(yùn)營
OpenStack虛機(jī)網(wǎng)卡的創(chuàng)建過程:Neutron 系列文章 Neutron Topic Tree:
OpenStack最基本和常用的操作就是啟動虛機(jī)。虛機(jī)啟動的過程中涉及很多內(nèi)容,其中非常重要的一個(gè)環(huán)節(jié)就是創(chuàng)建并綁定虛機(jī)的虛擬網(wǎng)卡。虛機(jī)的創(chuàng)建和管理是Nova的任務(wù),虛機(jī)網(wǎng)絡(luò)的創(chuàng)建和管理是Neutron的任務(wù),而虛機(jī)網(wǎng)卡,作為連接虛機(jī)和虛機(jī)網(wǎng)絡(luò)的橋梁,其創(chuàng)建和管理則同時(shí)涉及了Nova和Neutron。這次介紹一下,OpenStack中虛機(jī)的網(wǎng)卡的創(chuàng)建過程。雖然本文的介紹將基于OpenVSwitch,但是你可以發(fā)現(xiàn),很少有特殊于OpenVSwitch的地方,所以其他的二層機(jī)制(例如:Linux Bridge)過程都是類似的。
注:本文的所有分析都是基于OpenStack 17年上半年的代碼(Pike版本),因此本文只反應(yīng)OpenStack在那個(gè)時(shí)間點(diǎn)的行為。
先假設(shè)我們有一個(gè)典型的基于OpenVSwitch的OpenStack環(huán)境,服務(wù)的分布如下。
Neutron L2 Agent上線
首先是所有的服務(wù)上線,看neutron-openvswitch-agent的啟動。
- OpenVSwitch agent 啟動,注冊一個(gè)定時(shí)程序:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.__init__
- 在定時(shí)程序內(nèi)部,通過RPC向Neutron Server定時(shí)上報(bào)自己的狀態(tài):neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent._report_state
- 在Neutron Server,對應(yīng)的RPC處理方法中,Neutron Server將Agent上報(bào)的狀態(tài)寫入自己的DB:neutron.db.agents_db.AgentExtRpcCallback.report_state
到此為止,Neutron Server知道了Neutron OpenVSwitch Agent的狀態(tài)及相關(guān)信息,這一步的示意圖如下所示。
設(shè)想有這么一個(gè)場景,如果同時(shí)有N個(gè)計(jì)算節(jié)點(diǎn),由于電源問題,這些計(jì)算節(jié)點(diǎn)同時(shí)斷電重啟。那么當(dāng)這些計(jì)算節(jié)點(diǎn)上的OpenVSwitch Agent恢復(fù)之后,由于啟動時(shí)間比較集中,它們會在一個(gè)相對集中的時(shí)間點(diǎn),定時(shí)向Neutron Server上報(bào)自己的狀態(tài)。這涉及到Neutron Server處理RPC請求,寫DB,還有一些邏輯處理。所以當(dāng)N足夠大時(shí),會周期性的給Neutron Server帶來高負(fù)荷。這是實(shí)際應(yīng)用和優(yōu)化需要注意的一個(gè)地方。
創(chuàng)建一個(gè)虛機(jī),OpenStack創(chuàng)建邏輯端口(port)
接下來通過調(diào)用Nova的REST API創(chuàng)建一個(gè)虛機(jī),并且nova scheduler將虛機(jī)分布到了計(jì)算節(jié)點(diǎn)。Nova計(jì)算節(jié)點(diǎn)上的nova-compute進(jìn)程會:
- 調(diào)用Neutron REST API創(chuàng)建端口(port):nova.network.neutronv2.api.API.allocate_for_instance
- 這里創(chuàng)建端口只是邏輯驗(yàn)證,Neutron Server會在自己的DB里面創(chuàng)建一個(gè)相應(yīng)的,基本為空的端口
- 根據(jù)Nova掌握的信息,更新端口:nova.network.neutronv2.api.API._update_ports_for_instance
- 這里nova向Neutron傳遞的端口信息包括(列舉一部分):
- device_id: 虛機(jī)的uuid
- device_owner: 由compute+虛機(jī)所在的Nova Availability Zone組成的字符串,例如“compute: nova”
- dns_name: 虛機(jī)的hostname, 通常為虛機(jī)name
- binding:host_id: nova-compute所在的host id,可以是hostname,也可以是IP地址
- binding:profile: 一些額外的信息,例如SRIOV信息
Neutron Server在收到這些信息之后,主要處理流程如下:
- nova-compute調(diào)用Neutron Server更新端口,請求在這里處理:neutron.plugins.ml2.plugin.Ml2Plugin.update_port
- 之后處理port bind:neutron.plugins.ml2.plugin.Ml2Plugin._bind_port
- 調(diào)用到Neutron ML2的Mechanism Manger做port bind:neutron.plugins.ml2.manager.MechanismManager._bind_port_level
- 再調(diào)用到Neutron ML2的OpenVSwitch Mechanism Driver做實(shí)際的port bind:neutron.plugins.ml2.drivers.mech_agent.AgentMechanismDriverBase.bind_port
- 雖然這是個(gè)通用類,但是OVS Mechanism Driver繼承自這個(gè)類。
- 在這個(gè)方法里面,會檢查在指定的host上有沒有相應(yīng)的L2 Agent,所以這一步依賴之前一步的Neutron OpenVSwitch Agent狀態(tài)上報(bào)
- 這里的host信息來自于nova-compute傳遞過來的binding:host_id
- 將OVS對應(yīng)的vif_type和vif_details兩個(gè)屬性傳遞給port:neutron.plugins.ml2.drivers.mech_agent.SimpleAgentMechanismDriverBase.try_to_bind_segment_for_agent
- OVS的vif_type和vif_details在OVS Mechanism Driver的初始化函數(shù)里面定義:neutron.plugins.ml2.drivers.openvswitch.mech_driver.mech_openvswitch.OpenvswitchMechanismDriver.__init__
- 這里,定義了OVS對應(yīng)的vif_type是“ovs”,而vif_details包含了一些輔助信息
- vif_details里面包含了一個(gè)字段OVS_HYBRID_PLUG,如果這個(gè)字段為True,則最后虛機(jī)的網(wǎng)卡和br-int之間會有一個(gè)Linux Bridge來應(yīng)用iptables規(guī)則。如果你了解過OpenStack底層OpenVSwitch網(wǎng)卡連接方式,那么你一定見過下面這張圖,其中淺紫色的qbrXXX,就是因?yàn)檫@個(gè)字段為True才會在后面的步驟被創(chuàng)建。
這部分Neutron的行為都是在ML2中完成,如果你對其中一些概念不清楚,可以參考我之前介紹的ML2架構(gòu)。這部分除了更新Neutron自身的數(shù)據(jù)之外,比較重要的就是將vif_type和vif_details作為port的一部分?jǐn)?shù)據(jù),返回給nova-compute。到此為止,虛機(jī)的網(wǎng)卡還沒有創(chuàng)建,所有的操作都還只是在邏輯層面,只有數(shù)據(jù)庫的數(shù)據(jù)發(fā)生了變化。并且,
在Neutron的數(shù)據(jù)庫中,port的狀態(tài)現(xiàn)在是Down。但是,Nova和Neutron都知道了接下來要?jiǎng)?chuàng)建的網(wǎng)卡的具體信息,這一步的實(shí)際意義在于兩個(gè)相對獨(dú)立的項(xiàng)目之間的數(shù)據(jù)同步?,F(xiàn)在,OpenStack整體示意圖如下所示:
nova-compute創(chuàng)建虛擬網(wǎng)卡
雖然說Neutron是OpenStack里面的網(wǎng)絡(luò)服務(wù)項(xiàng)目,但是OpenStack里面的虛機(jī)網(wǎng)卡,卻是由Nova創(chuàng)建的。nova-compute在從Neutron Server拿到了端口的信息之后(通過update port的返回?cái)?shù)據(jù)):
- 調(diào)用相應(yīng)的虛擬化Driver,繼續(xù)創(chuàng)建虛機(jī):nova.compute.manager.ComputeManager._build_and_run_instance
- 在Driver內(nèi)部,創(chuàng)建網(wǎng)絡(luò)相關(guān)內(nèi)容:nova.virt.libvirt.driver.LibvirtDriver.spawn
- 在Driver內(nèi)部,通過調(diào)用os-vif庫,創(chuàng)建虛機(jī)網(wǎng)卡。由于nova-compute現(xiàn)在已經(jīng)知道了虛機(jī)網(wǎng)卡的所有信息,適用于虛機(jī)的網(wǎng)卡被創(chuàng)建出來:nova.virt.libvirt.driver.LibvirtDriver.plug_vifs
至此,虛機(jī)的虛擬網(wǎng)卡真正的創(chuàng)建出來了。但是,
在Neutron的數(shù)據(jù)庫中,port的狀態(tài)現(xiàn)在是Down。到此為止,OpenStack的整體示意圖如下所示:
Neutron檢測虛擬網(wǎng)卡狀態(tài)并更新port狀態(tài)
虛機(jī)的虛擬網(wǎng)卡被插入到OVS網(wǎng)橋上,對于Neutron來說,接下來就是接管這個(gè)網(wǎng)卡。
- Neutron OpenVSwitch Agent進(jìn)程中會監(jiān)聽OVS網(wǎng)橋的狀態(tài):neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.rpc_loop
- 當(dāng)發(fā)現(xiàn)有新增的虛擬網(wǎng)卡時(shí),先從Neutron Server獲取詳細(xì)的網(wǎng)卡信息:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent.treat_devices_added_or_updated
- nova-compute在創(chuàng)建虛擬網(wǎng)卡的時(shí)候,已經(jīng)將Neutron port id和一些其他信息寫入到OVS port/interface中,因此Neutron從新增的虛擬網(wǎng)卡就能知道對應(yīng)的port是那個(gè),下圖是截取的OVS數(shù)據(jù),里面的iface-id就是Neutron port對應(yīng)的ID
- Neutron OpenVSwitch Agent本地更新完虛擬網(wǎng)卡之后,再通過RPC通知Neutron Server端口上線:neutron.plugins.ml2.drivers.openvswitch.agent.ovs_neutron_agent.OVSNeutronAgent._bind_devices
至此,Neutron已經(jīng)接管了虛擬網(wǎng)卡,并且
在Neutron的數(shù)據(jù)庫中,port的狀態(tài)現(xiàn)在是Active。Neutron從這個(gè)時(shí)候開始正式接管虛機(jī)網(wǎng)絡(luò)。OpenStack整體示意圖如下所示:
總結(jié)
所以,簡單來說,在OpenStack中,首先需要各個(gè)服務(wù)上線;之后Nova會創(chuàng)建邏輯網(wǎng)卡,但是Nova只知道虛機(jī)所在的host;Neutron會根據(jù)所在的host,判斷出相應(yīng)的網(wǎng)絡(luò)虛擬化機(jī)制,例如ovs,linuxbridge,Neutron會把這些信息回傳給Nova;Nova拿到這些信息,調(diào)用相應(yīng)的方法創(chuàng)建虛擬網(wǎng)卡,并接入到虛機(jī);Neutron會監(jiān)聽網(wǎng)橋上端口的變化,發(fā)現(xiàn)有上線的端口,與自己本身的數(shù)據(jù)進(jìn)行匹配,匹配到了之后接管這個(gè)虛擬網(wǎng)卡。對于Neutron來說,它不關(guān)心虛擬網(wǎng)卡接的是虛機(jī)還是容器還是別的什么,它只能看到虛擬網(wǎng)卡