自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Openstack源碼閱讀的正確姿勢(shì)

開(kāi)發(fā) 開(kāi)發(fā)工具 OpenStack
最開(kāi)始容器服務(wù)也是由Nova提供支持的,作為Nova的driver之一來(lái)實(shí)現(xiàn),而后遷移到Heat,到現(xiàn)在已經(jīng)分離成獨(dú)立的項(xiàng)目Magnum,后來(lái)Magnum主要提供容器編排服務(wù),單純的容器服務(wù)由Zun項(xiàng)目負(fù)責(zé)。最開(kāi)始Openstack并沒(méi)有認(rèn)證功能,從E版開(kāi)始才加入認(rèn)證服務(wù)Keystone,至此Openstack 6個(gè)核心服務(wù)才終于聚齊了。

1. 談?wù)凮penstack的發(fā)展歷史

OpenStack是一個(gè)面向IaaS層的云管理平臺(tái)開(kāi)源項(xiàng)目,用于實(shí)現(xiàn)公有云和私有云的部署及管理。最開(kāi)始Openstack只有兩個(gè)組件,分別為提供計(jì)算服務(wù)的Nova項(xiàng)目以及提供對(duì)象存儲(chǔ)服務(wù)的Swift,其中Nova不僅提供虛擬機(jī)服務(wù),還包含了網(wǎng)絡(luò)服務(wù)、塊存儲(chǔ)服務(wù)、鏡像服務(wù)以及裸機(jī)管理服務(wù)。之后隨著項(xiàng)目的不斷發(fā)展,從Nova中拆分成多個(gè)獨(dú)立的項(xiàng)目各自提供不同的服務(wù),如拆分為Cinder項(xiàng)目提供塊存儲(chǔ)服務(wù),拆分為Glance項(xiàng)目,提供鏡像服務(wù),nova-network則是neutron的前身,裸機(jī)管理也從Nova中分離出來(lái)為Ironic項(xiàng)目。最開(kāi)始容器服務(wù)也是由Nova提供支持的,作為Nova的driver之一來(lái)實(shí)現(xiàn),而后遷移到Heat,到現(xiàn)在已經(jīng)分離成獨(dú)立的項(xiàng)目Magnum,后來(lái)Magnum主要提供容器編排服務(wù),單純的容器服務(wù)由Zun項(xiàng)目負(fù)責(zé)。最開(kāi)始Openstack并沒(méi)有認(rèn)證功能,從E版開(kāi)始才加入認(rèn)證服務(wù)Keystone,至此Openstack 6個(gè)核心服務(wù)才終于聚齊了。

  • Keystone 認(rèn)證服務(wù)。
  • Glance 鏡像服務(wù)。
  • Nova 計(jì)算服務(wù)。
  • Cinder 塊存儲(chǔ)服務(wù)。
  • Neutorn 網(wǎng)絡(luò)服務(wù)。
  • Swift 對(duì)象存儲(chǔ)服務(wù)。

E版之后,在這些核心服務(wù)之上,又不斷涌現(xiàn)新的服務(wù),如面板服務(wù)Horizon、服務(wù)編排服務(wù)Heat、數(shù)據(jù)庫(kù)服務(wù)Trove、文件共享服務(wù)Manila、大數(shù)據(jù)服務(wù)Sahara以及前面提到的Magnum等,這些服務(wù)幾乎都依賴于以上的核心服務(wù)。比如Sahara大數(shù)據(jù)服務(wù)會(huì)先調(diào)用Heat模板服務(wù),Heat又會(huì)調(diào)用Nova創(chuàng)建虛擬機(jī),調(diào)用Glance獲取鏡像,調(diào)用Cinder創(chuàng)建數(shù)據(jù)卷,調(diào)用Neutron創(chuàng)建網(wǎng)絡(luò)等。還有一些項(xiàng)目圍繞Openstack部署的項(xiàng)目,比如Puppet-openstack、Kolla、TripleO、Fuel等項(xiàng)目。

截至現(xiàn)在(2016年11月27日),Openstack已經(jīng)走過(guò)了6年半的歲月,***發(fā)布的版本為第14個(gè)版本,代號(hào)為Newton,Ocata版已經(jīng)處在快速開(kāi)發(fā)中。

Openstack服務(wù)越來(lái)越多、越來(lái)越復(fù)雜,并且不斷變化發(fā)展。以Nova為例,從最開(kāi)始使用nova-conductor代理數(shù)據(jù)庫(kù)訪問(wèn)增強(qiáng)安全性,引入objects對(duì)象模型來(lái)支持對(duì)象版本控制,現(xiàn)在正在開(kāi)發(fā)Cell項(xiàng)目來(lái)支持大規(guī)模的集群部署以及將要分離的Nova-EC2項(xiàng)目,截至到現(xiàn)在Nova包含nova-api、nova-conductor、nova-scheduler、nova-compute、nova-cell、nova-console等十多個(gè)組件。這么龐大的分布式系統(tǒng)需要深刻理解其工作原理,理清它們的交互關(guān)系非常不容易,尤其對(duì)于新手來(lái)說(shuō)。

2.工欲善其事,必先利其器

由于Openstack使用python語(yǔ)言開(kāi)發(fā),而python是動(dòng)態(tài)類型語(yǔ)言,參數(shù)類型不容易從代碼中看出,因此首先需要部署一個(gè)allinone的Openstack開(kāi)發(fā)測(cè)試環(huán)境,建議使用RDO部署:Packstack quickstart,當(dāng)然樂(lè)于折騰使用devstack也是沒(méi)有問(wèn)題的。

其次需要安裝科學(xué)的代碼閱讀工具,圖形界面使用pycharm沒(méi)有問(wèn)題,不過(guò)通常在虛擬機(jī)中是沒(méi)有圖形界面的,***vim,需要簡(jiǎn)單的配置使其支持代碼跳轉(zhuǎn)和代碼搜索,可以參考我的vim配置GitHub - int32bit/dotfiles: A set of vim, zsh, git, and tmux configuration files。

掌握python的調(diào)試技巧,推薦pdb、ipdb、ptpdb,其中ptpdb***用,不過(guò)需要手動(dòng)安裝。打斷點(diǎn)前需要注意代碼執(zhí)行時(shí)屬于哪個(gè)服務(wù)組件,nova-api的代碼,你跑去nova-compute里打斷點(diǎn)肯定沒(méi)用。另外需要注意打了斷點(diǎn)后的服務(wù)必須在前端運(yùn)行,不能在后臺(tái)運(yùn)行,比如我們?cè)趎ova/compute/manager.py中打了斷點(diǎn),我們需要kill掉后臺(tái)進(jìn)程:

  1. systemctl stop openstack-nova-compute 

然后直接在終端運(yùn)行nova-compute即可。

  1. su -c 'nova-compute' nova 

3 .教你閱讀的正確姿勢(shì)

學(xué)習(xí)Openstack的***步驟是:

  • 看文檔
  • 部署allineone
  • 使用之
  • 折騰之、怒斥之
  • 部署多節(jié)點(diǎn)
  • 深度使用、深度吐槽
  • 閱讀源碼
  • 混社區(qū),參與社區(qū)開(kāi)發(fā)

閱讀源碼的首要問(wèn)題就是就要對(duì)代碼的結(jié)構(gòu)了然于胸,需要強(qiáng)調(diào)的是,Openstack項(xiàng)目的目錄結(jié)構(gòu)并不是根據(jù)組件劃分的,而是根據(jù)功能劃分的,以Nova為例,compute目錄并不是一定在nova-compute節(jié)點(diǎn)上運(yùn)行的代碼,而主要是和compute相關(guān)(虛擬機(jī)操作相關(guān))的功能實(shí)現(xiàn),同樣的,scheduler目錄代碼并不全在scheduler服務(wù)節(jié)點(diǎn)運(yùn)行,但主要是和調(diào)度相關(guān)的代碼。好在目錄結(jié)構(gòu)并不是完全混亂的,它是有規(guī)律的。

通常一個(gè)服務(wù)的目錄都會(huì)包含api.py、rpcapi.py、manager.py,這個(gè)三個(gè)是最重要的模塊。

  • api.py: 通常是供其它組件調(diào)用的庫(kù)。換句話說(shuō),該模塊通常并不會(huì)由本模塊調(diào)用。比如compute目錄的api.py,通常由nova-api服務(wù)的controller調(diào)用。
  • rpcapi.py:這個(gè)是RPC請(qǐng)求的封裝,或者說(shuō)是RPC實(shí)現(xiàn)的client端,該模塊封裝了RPC請(qǐng)求調(diào)用。
  • manager.py: 這個(gè)才是真正服務(wù)的功能實(shí)現(xiàn),也是RPC的服務(wù)端,即處理RPC請(qǐng)求的入口,實(shí)現(xiàn)的方法通常和rpcapi實(shí)現(xiàn)的方法對(duì)應(yīng)。

前面提到Openstack項(xiàng)目的目錄結(jié)構(gòu)是按照功能劃分的,而不是服務(wù)組件,因此并不是所有的目錄都能有對(duì)應(yīng)的組件。仍以Nova為例:

  • cmd:這是服務(wù)的啟動(dòng)腳本,即所有服務(wù)的main函數(shù)??捶?wù)怎么初始化,就從這里開(kāi)始。
  • db: 封裝數(shù)據(jù)庫(kù)訪問(wèn),目前支持的driver為sqlalchemy。
  • conf:Nova的配置項(xiàng)聲明都在這里。
  • locale: 本地化處理。
  • image: 封裝Glance調(diào)用接口。
  • network: 封裝網(wǎng)絡(luò)服務(wù)接口,根據(jù)配置不同,可能調(diào)用nova-network或者neutron。
  • volume: 封裝數(shù)據(jù)卷訪問(wèn)接口,通常是Cinder的client封裝。
  • virt: 這是所有支持的hypervisor驅(qū)動(dòng),主流的如libvirt、xen等。
  • objects: 對(duì)象模型,封裝了所有實(shí)體對(duì)象的CURD操作,相對(duì)以前直接調(diào)用db的model更安全,并且支持版本控制。
  • policies: policy校驗(yàn)實(shí)現(xiàn)。
  • tests: 單元測(cè)試和功能測(cè)試代碼。

根據(jù)進(jìn)程閱讀源碼并不是什么好的實(shí)踐,因?yàn)楣饫斫夥?wù)如何初始化、如何通信、如何發(fā)送心跳等就不容易,各種高級(jí)封裝太復(fù)雜了。而我認(rèn)為比較好的閱讀源碼方式是追蹤一個(gè)任務(wù)的執(zhí)行過(guò)程,比如追蹤啟動(dòng)一臺(tái)虛擬機(jī)的整個(gè)流程。

不管任何操作,一定是先從API開(kāi)始的,RESTFul API是Openstack服務(wù)的唯一入口,也就是說(shuō),閱讀源碼就從api開(kāi)始。而api組件也是根據(jù)實(shí)體劃分的,不同的實(shí)體對(duì)應(yīng)不同的controller,比如servers、flavors、keypairs等,controller通常對(duì)應(yīng)有如下方法:

  • index: 獲取資源列表,一般對(duì)應(yīng)RESTFul API的URL為“GET /resources”,如獲取虛擬機(jī)的列表API為“GET /servers”。
  • get: 獲取一個(gè)資源,比如返回一個(gè)虛擬機(jī)的詳細(xì)信息API為”GET /servers/uuid“。
  • create: 創(chuàng)建一個(gè)新的資源,通常對(duì)應(yīng)為POST請(qǐng)求。比如創(chuàng)建一臺(tái)虛擬機(jī)為 “POST /servers”, 當(dāng)然POST的數(shù)據(jù)為虛擬機(jī)信息。
  • delete: 刪除指定資源,通常對(duì)應(yīng)DELETE請(qǐng)求,比如刪除一臺(tái)虛擬機(jī)為“DELETE/servers/uuid”。
  • update: 更新資源信息,通常對(duì)應(yīng)為PUT請(qǐng)求,比如更新虛擬機(jī)資源為”PUT /servers/uuid,body為虛擬機(jī)數(shù)據(jù)。

了解了代碼結(jié)構(gòu),找到了入口,再配合智能跳轉(zhuǎn),閱讀源碼勢(shì)必事半功倍。如果有不明白的地方,隨時(shí)可以加上斷點(diǎn)單步調(diào)試。

4.案例分析

接下來(lái)以創(chuàng)建虛擬機(jī)為例,根據(jù)組件劃分,一步步分析整個(gè)工作流程以及操作序列。請(qǐng)?jiān)俅位仡櫹耡pi.py、rpcapi.py、manager.py以及api下的controller結(jié)構(gòu),否則閱讀到后面會(huì)越來(lái)越迷糊。

S1 nova-api

入口為nova/api/openstack/compute/servers.py的create方法,該方法檢查了一堆參數(shù)以及policy后,調(diào)用compute_api的create方法,這里的compute_api即前面說(shuō)的nova/compute/api.py模塊的API。

compute_api會(huì)創(chuàng)建數(shù)據(jù)庫(kù)記錄、檢查參數(shù)等,然后調(diào)用compute_task_api的build_instances方法,compute_task_api即conductor的api.py。

conductor的api并沒(méi)有執(zhí)行什么操作,直接調(diào)用了conductor_compute_rpcapi的build_instances方法,該方法即時(shí)conductor RPC調(diào)用api,即nova/conductor/rpcapi.py模塊,該方法除了一堆的版本檢查,剩下的就是對(duì)RPC調(diào)用的封裝,代碼只有兩行:

  1. cctxt = self.client.prepare(version=version)  
  2. cctxt.cast(context, 'build_instances', **kw) 

其中cast表示異步調(diào)用,build_instances是遠(yuǎn)程調(diào)用的方法,kw是傳遞的參數(shù)。參數(shù)是字典類型,沒(méi)有復(fù)雜對(duì)象結(jié)構(gòu),因此不需要特別的序列化操作。

截至到現(xiàn)在,雖然目錄由api->compute->conductor,但仍在nova-api進(jìn)程中運(yùn)行,直到cast方法執(zhí)行,該方法由于是異步調(diào)用,因此nova-api不會(huì)等待遠(yuǎn)程方法調(diào)用結(jié)果,直接返回結(jié)束。

S2 nova-conductor

由于是向nova-conductor發(fā)起的RPC調(diào)用,而前面說(shuō)了接收端肯定是manager.py,因此進(jìn)程跳到nova-conductor服務(wù),入口為nova/conductor/manager.py的build_instances方法。

該方法首先調(diào)用了_schedule_instances方法,該方法調(diào)用了scheduler_client的select_destinations方法,scheduler_client和compute_api以及compute_task_api都是一樣對(duì)服務(wù)的client調(diào)用(即api.py),不過(guò)scheduler沒(méi)有api.py,而是有個(gè)單獨(dú)的client目錄,實(shí)現(xiàn)在client目錄的__init__.py模塊,這里僅僅是調(diào)用query.py下SchedulerQueryClient的select_destinations實(shí)現(xiàn),然后又很直接的調(diào)用了scheduler_rpcapi的select_destinations方法,終于又到了RPC調(diào)用環(huán)節(jié)。

毫無(wú)疑問(wèn),RPC封裝同樣是在scheduler的rpcapi中實(shí)現(xiàn)。該方法RPC調(diào)用代碼如下:

  1. return cctxt.call(ctxt, 'select_destinations', **msg_args) 

注意這里調(diào)用的call方法,即同步調(diào)用,此時(shí)nova-conductor并不會(huì)退出,而是堵塞等待直到nova-scheduler返回。

S3 nova-scheduler

同理找到scheduler的manager.py模塊的select_destinations方法,該方法會(huì)調(diào)用driver對(duì)應(yīng)的方法,這里的driver其實(shí)就是調(diào)度算法實(shí)現(xiàn),由配置文件決定,通常用的比較多的就是filter_scheduler,對(duì)應(yīng)filter_scheduler.py模塊,該模塊首先通過(guò)host_manager拿到所有的計(jì)算節(jié)點(diǎn)信息,然后通過(guò)filters過(guò)濾掉不滿足條件的計(jì)算節(jié)點(diǎn),剩下的節(jié)點(diǎn)通過(guò)weigh方法計(jì)算權(quán)值,***選擇權(quán)值高的作為候選計(jì)算節(jié)點(diǎn)返回。nova-scheduler進(jìn)程結(jié)束。

S4 nova-condutor

回到scheduler/manager.py的build_instances方法,nova-conductor等待nova-scheduler返回后,拿到調(diào)度的計(jì)算節(jié)點(diǎn)列表,然后調(diào)用了compute_rpcapi的build_and_run_instance方法??吹絰xxrpc立即想到對(duì)應(yīng)的代碼位置,位于compute/rpcapi模塊,該方法向nova-compute發(fā)起RPC請(qǐng)求:

  1. cctxt.cast(ctxt, 'build_and_run_instance', ...) 

可見(jiàn)發(fā)起的是異步RPC,因此nova-conductor結(jié)束,緊接著終于輪到nova-compute登場(chǎng)了。

S5 nova-compute

到了nova-compute服務(wù),入口為compute/manager.py,找到build_and_run_instance方法,該方法調(diào)用了driver的spawn方法,這里的driver就是各種hypervisor的實(shí)現(xiàn),所有實(shí)現(xiàn)的driver都在virt目錄下,入口為driver.py,比如libvirt driver實(shí)現(xiàn)對(duì)應(yīng)為virt/libvirt/driver.py,找到spawn方法,該方法拉取鏡像創(chuàng)建根磁盤、生成xml文件、define domain,啟動(dòng)domain等。***虛擬機(jī)完成創(chuàng)建。nova-compute服務(wù)結(jié)束。

一張圖總結(jié)以上是創(chuàng)建虛擬機(jī)的各個(gè)服務(wù)的交互過(guò)程以及調(diào)用關(guān)系,需要注意的是,所有的數(shù)據(jù)庫(kù)操作,比如instance.save()以及update操作,如果配置use_local為false,則會(huì)向nova-conductor發(fā)起RPC調(diào)用,由nova-conductor代理完成數(shù)據(jù)庫(kù)更新,而不是由nova-compute直接訪問(wèn)數(shù)據(jù)庫(kù),這里的RPC調(diào)用過(guò)程在以上的分析中省略了。

整個(gè)流程用一張圖表示為:

【本文是51CTO專欄作者“付廣平”的原創(chuàng)文章,如需轉(zhuǎn)載請(qǐng)通過(guò)51CTO獲得聯(lián)系】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專欄
相關(guān)推薦

2015-07-03 09:55:48

陳沙克OpenStack開(kāi)源云平臺(tái)

2018-01-11 15:31:39

命令Linux關(guān)機(jī)

2017-02-23 15:37:44

OptionObject容器

2016-05-09 10:41:03

算法分析開(kāi)發(fā)

2017-07-10 13:09:45

前端Flexbox

2023-01-30 07:41:43

2017-10-12 11:30:34

Spark代碼PR

2021-01-08 08:10:34

MySQL表空間回收

2016-12-12 08:48:24

2019-12-27 15:58:57

大數(shù)據(jù)IT互聯(lián)網(wǎng)

2021-09-15 16:20:02

Spring BootFilterJava

2024-09-25 08:22:06

2016-10-11 16:28:11

源代碼

2019-10-30 17:06:50

AWS物聯(lián)網(wǎng)IoT

2016-01-05 11:28:20

按需付費(fèi)云計(jì)算docker

2019-01-02 10:49:54

Tomcat內(nèi)存HotSpot VM

2017-06-19 17:43:04

網(wǎng)絡(luò)帶寬網(wǎng)絡(luò)設(shè)計(jì)

2020-02-24 15:26:40

Python短信免費(fèi)

2025-03-11 00:55:00

Spring停機(jī)安全

2022-03-28 11:10:35

ShellBash forLinux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)