【編者按】已經成為IaaS事實標準的OpenStack,仍然面臨穩定性、易用性等一系列的難題,新近推出的IaaS開源項目ZStack,號稱要借鑒IaaS先輩的經驗,通過新的技術架構解決OpenStack難以解決的技術問題,并得到了OpenStack社區的關注。那么,ZStack有何特色?能否實現目標?ZStack的發起者和總架構師張鑫(Frank),撰文從架構層面全面介紹了ZStack的設計理念和技術實現,并就ZStack的市場目標和社區規劃進行了解答。以下為文章內容:
ZStack作為一款新開源IaaS軟件,自發布后就迅速引起了技術圈的關注,許多朋友都對它架構特點很感興趣。雖然在ZStack主頁有16篇博客詳細介紹了它的主要架構特點,但仍要花一定時間進行閱讀才能把握其設計要點。筆者作為ZStack的發起者和總架構師,希望通過這篇文章對所有架構要點進行一次梳理,圍繞它要解決的問題出發,為讀者進行一個詳細的介紹。
ZStack的架構特點
ZStack從誕生之初沒有急于實現各種炫目的功能,而是花了大部分精力做架構設計,希望從架構上解決四個問題:易用性,穩定性,高性能,以及擴展性。ZStack的所有的架構設計,全部圍繞這四個方面展開:
易用性
在易用性方面,ZStack首先考慮的是軟件的安裝部署與升級,其次是在長期使用的過程中的營運和維護。對于安裝和部署,ZStack是一個Java項目,在編譯的完成后,所有的文件都會被打包到一個Java的WAR文件中。部署ZStack實際就是部署一個標準的Java WAR文件到Apache Tomcat這樣的web container中。這種部署是Java web應用的標準部署方法,非常簡單且廣為熟知。即使沒有IaaS經驗的的用戶,也可以很容易學會安裝。同時ZStack對外部的依賴非常少,僅僅需要MySQL數據庫,RabbitMQ消息總線,以及Ansible系統配置管理軟件,這些都是Linux各個發行版提供的軟件。一個單管理節點的ZStack部署如圖所示:
如果把MySQL和RabbitMQ放到單獨的機器,單管理節點的部署可以很容易擴展成多節點部署:
由于IaaS軟件管理數據中心中大量的硬件,很多情況下需要安裝agent到硬件上,例如安裝agent到作為KVM計算節點的Linux機器。為了讓用戶從手動安裝配置硬件的枯燥工作中解脫出來,ZStack跟Ansible無縫集成,當用戶添加一個計算節點時,ZStack調用Ansible自動安裝agent并配置系統,整個過程對用戶透明。用戶無需閱讀冗長的文檔去了解agent需要什么依賴包,需要怎么配置,這些全部由ZStack負責。用戶只需調用一個API即可。類似的設計應用在所有需要安裝agent的服務,例如負責提供網絡功能的虛擬機(Virutal Router VM)。
KVM agent的Ansible的配置文件如圖所示:
配置文件和KVM agent的Python包都包含在Java WAR文件中,在用戶調用API添加一個計算節點時,ZStack會自動找到對應的配置文件并調用Ansible去部署agent,用戶甚至都不知道這個過程的存在。此外,對于高級用戶,可以通過擴展Ansible配置文件來實現運維過程中的系統維護和升級。例如為了升級KVM機器的某個安裝包修復一個安全漏洞,用戶只需要在KVM的配置文件中加上相關內容,再調用ZStack的ReconnectHost API,就可以自動實現升級功能。
在監控方面,ZStack目前提供對關鍵的系統資源比如物理機,虛擬機的狀態進行監控,任何在ZStack控制外的狀態變化,例如虛擬機的意外宕機,都會在一定的時間內被檢測到并同步到數據庫。此外ZStack還通過Java的JMX協議對外暴露監控自身的接口,例如監控當前系統運行的任務,系統正在處理的消息,消息的平均處理時間和最大處理時間等。讓用戶可以實時了解系統動態。
豐富的查詢API是ZStack為用戶運維提供的一個重要功能。ZStack的查詢API提供超過400萬單項查詢條件,400萬階乘的組合查詢條件。用戶在API層面就可以完成數據庫級別的資源查詢。查詢API帶來的意義是可以打造真正企業級的UI。在優秀的企業軟件中,例如微軟outlook,JIRA中,用戶都可以根據自己的需求創建不同的視圖。在IaaS中也有同樣的需求。用戶可能需要視圖顯示所有在同一三級網絡中的虛擬機,顯示所有內存容量低于2G的物理服務器等。在沒有完善的查詢API支持下,UI就只能提供幾個默認視圖,而無法允許用戶自定義視圖。
ZStack的查詢API的一個獨特之處在于,查詢框架在接收到API后可以自動生成SQL語句,無需編寫代碼。開發人員只要在數據庫中定義了表,然后在Java程序中用annotation描述新表與其它表之間的foreign key,再為新表繼承一個查詢API的基礎類,所有工作就完成了。用戶使用新API時,查詢框架可以自動感知,根據用戶的查詢條件生成單表SQL以及多表Join的SQL語句。
穩定性
IaaS軟件本身是個集成項目,管理了數據中心中大量的子系統,它實際上管理著所有子系統和所有設備的狀態。加之IaaS中每一個任務的執行路徑非常長,例如創建一個虛擬機就涉及到計算節點,網絡節點,存儲節點狀態的變化,其中任何一個步驟都可能出錯。一旦錯誤發生,由于當前IaaS缺乏回退機制,某些子系統會遺留在中間狀態。比如一個虛擬機最后創建失敗了,但它的DHCP信息卻可能遺留在網絡節點,導致將來可能的DHCP沖突。為此,ZStack設計了一個workflow引擎,將任務的每個操作都封裝到flow中,一旦某個操作出錯,workflow引擎會回退(rollback)所以已經執行的flow,保證不會系統遺留在中間狀態。
例如在上圖的創建虛擬機workflow中,假設任務在VmCreateOnHypervisorFlow這一步失敗了,workflow引擎會回退前面已執行的6個flow,包括子workflow(圖中計算節點分配workflow,創建網絡節點虛擬機的workflow)。例如刪除已創建的網絡節點虛擬機,刪除已創建的虛擬磁盤,歸還已分配的計算資源到計算節點等。最大程度保證系統狀態的完整性。
除了可以回退外,workflow引擎還可以允許開發人員通過XML文件來配置關鍵任務。例如在上圖中,創建虛擬機的workflow包含一個創建網絡節點虛擬機的子workflow(Creating Appliance VM sub-workflow)。這個子workflow跟創建用戶虛擬機的workflow類似,只有分配網卡這個flow不同。ZStack通過配置XML文件替換掉該條flow(圖中綠色部分),就實現了創建網絡節點虛擬機的邏輯。這種通過XML文件配置workflow的方式被大量運用,例如計算節點分配器(host allocator),存儲分配器(storage allocator),IP地址分配器(IP allocator)都是通過這種方式實現的。開發人員甚至不用寫新代碼,只需重新組合一些flow的順序就可以實現新的業務邏輯。例如計算節點分配器里的一些實現,就是通過組合已有的flow實現的。這種方式使ZStack的組件復用度非常高,幫助整個架構實現了松耦合。
除了workflow,ZStack在設計最初期就引入了一個類似于Eclipse的插件系統,所有核心功能都是以小插件的形式搭建起來的,保證無論是添加新功能還是移除舊功能,都不會修改已有代碼,從而保證在快速實現新功能的同時,整體系統可以保持穩定。這個插件系統的核心是擴展點(extension point)。每個組件都可以定義自己的擴展點允許其它組件接入,從而擴展業務邏輯。
例如上圖所示的安全組(security group)功能,它需要在虛擬機的不同生命期對防火墻規則進行編程。但對于虛擬機本身來說,安全組只是一個附加功能,所以并不應該實現在虛擬機自身的邏輯當中?;赯Stack的插件系統,安全組通過虛擬機模塊,網絡模塊等定義的擴展點插入到了虛擬機生命期,網絡配置等業務邏輯中,在不修改任何已有模塊的情況下,實現成一個單獨的Java JAR文件。也就是說,安全組本身不會對現有功能造成任何影響,即使刪除安全組對應的JAR文件,整個系統也只是失去了這個功能而已。通過插件系統,ZStack本身架構完全實現了松耦合。
Tag system也是ZStack一個創新。雖然很多IaaS軟件也有tag的概念,但大多只是幫助用戶管理資源。ZStack定義一種稱為system tag的概念,插件可以通過定義system tag,在不修改已有數據庫表的情況下,實現為現有表添加新的字段。例如在虛擬機表中并不存在一個字段叫hostname,ZStack的一個插件通過定義一個vm::hostname的system tag,為虛擬機表增加了這個字段,從而允許用戶在創建虛擬機時指定它的hostname。通過這種方式,插件在擴展已有功能時,無需對現有數據庫表格式進行修改,從而減輕了軟件升級過程中數據庫遷移的負擔。
Workflow引擎,插件系統,system tag設計的核心思想是最大程度的松耦合架構,保證已有系統在快速添加新功能的情況下也能保證整體架構穩定,避免因實現新功能而反復修改已有代碼,導致產品始終沒有一個穩定內核的情況。
最后,ZStack從誕生開始就是測試驅動的。在ZStack中驗證功能點的唯一方法就是寫測試用例。我們有三個全自動化的測試系統:Integration testing system, System testing system,以及Model-based testing system來保證整個項目的質量。其中Model-based testing system可以隨機組合API生成測試用例,測試出很多正常使用情況下無法觸及的死角。為了能夠快速重現Model-based testing system發現的死角,我們還開發了一個回放工具,它能讀入Model-based測試用例產生的日志而生成一個新測試用例,通過回放失敗用例來產生一個供開發人員調試的環境,避免了人工手動重試數千個API來重現失敗用例(因為Model-based測試用例可能隨機執行數日,產生數以千計甚至萬計的API調用)。下面是測試系統運行過程中的一個截圖:
高性能
ZStack是目前開源軟件中,唯一一款號稱能夠以單管理節點管理幾十萬物理機器,數百萬虛擬機,以及響應數萬并發API調用的軟件。通過我們的軟件模擬器,我們測試過管理10萬物理機,通過1萬到3萬并發API創建百萬虛擬機的情況。此外我們還進行了虛擬機創建的性能測試,數據如下表:
在測試中我們只使用了單網絡節點,發現DHCP/DNS軟件Dnsmasq成為了性能的瓶頸。在跟Dnsmasq社區溝通后,通過打補丁的Dnsmasq,我們能將創建10000虛擬機的時間縮短到11分鐘。在使用多網絡節點(多租戶)的環境下,我們相信這個數據還可以進一步的提高。
ZStack的高性能受益于三個架構設計:全異步架構,無狀態服務架構,無鎖架構。
全異步架構保證一個任務從API調用開始,到最后在外部設備上執行的過程都是全異步的,從而任何線程都不會因等待一個操作完成而阻塞。在我們的壓力測試中,單管理節點響應10000 API調用只用了1000個線程就可以完成。ZStack的全異步架構由三部分組成:異步消息,異步函數調用,異步HTTP調用。其中異步消息是服務之間調用時使用的。宏觀上看,ZStack的功能劃分成了多個獨立的服務,服務之間通過消息通信,連API都是以消息的形式實現。例如有虛擬機服務,網絡服務,存儲服務等。在服務的內部存在許多組件,他們協作完成一個服務的功能。這些組件之間的調用使用的是傳統的函數調用方式,通過回調函數(callback)實現異步。最后,服務與外部agent通信時采用的是異步 HTTP調用。例如在創建KVM虛擬機時,虛擬機服務將請求提交給KVM agent后就返回了。KVM agent在虛擬機創建完成后,會通過回調HTTP鏈接通知虛擬機服務。
無狀態服務是指通過一致性哈希環(consistent hashing ring),服務本身可以和它所管理的具體資源分離開來,服務相互之間也無需交換所管理資源的信息。例如在多管理節點部署中會存在多個虛擬機服務,他們共同管理系統中的所有虛擬機。但每個服務自身是不需要知道哪些虛擬機是自己管理的,哪些是其它人管理的。當其它服務向虛擬機服務發送請求時,會用虛擬機的UUID通過一致性哈希環算出管理這個虛擬機的服務,從而保證無論請求在哪個管理節點發起,最終都會被發送到相同的服務去處理。
得益于無狀態服務,ZStack的所有業務邏輯無需通過鎖相互競爭資源,資源競爭完全通過隊列控制。由于一致性哈希環會把針對某一個資源的操作全部轉發到同一個服務,ZStack允許每個服務在內存中創建FIFO隊列,以請求到達的順序響應。對于所有操作只能順序執行的資源,例如虛擬機,服務可以創建并發度為1的隊列,保證同一時間只有一個操作在執行。
對于允許并發操作的資源,例如物理服務器可以允許同時執行多個操作,可以創建并發度大于1的隊列。
通過基于隊列的無鎖架構,ZStack即實現了對關鍵資源的操作同步,又實現了對操作并發度的控制,在提高系統的吞吐性同時,又保證了系統在大吞吐量時的穩定性。例如物理服務器(host)資源的默認并發度是10,在系統大負荷的情況下,ZStack保證物理服務器最多響應10個請求,多的請求排隊,避免了過多的請求造成資源的崩潰。當然,資源的并發度完全是可配置的,用戶可以通過API配置例如物理服務器的并發度,根據系統的負荷調整參數。
擴展性
ZStack在設計之初就考慮到了不同的用戶對云的使用模式的差異性。例如公有云提供商,服務提供商,傾向于亞馬遜的模式。而傳統企業用戶,則更喜歡VMWare的企業虛擬化模式(Enterprise Virtualization)?;诓寮到y,ZStack將每個功能實現成小插件,默認是亞馬遜的EC2模式,也就是各種資源池化。然后在這個基礎上,通過一些輔助插件,ZStack可以在EC2的模式上組合出VMWare這種以虛擬機為中心的模式。這樣不同的用戶就可以根據自己的需求選擇相應的模式。并且兩種模式還可以互通,比如以虛擬機為中心的模式也可以使用EC2模式所提供的安全組(security group),彈性IP(EIP)這樣的網絡服務。
除了插件系統外,ZStack也認識到很多IaaS的功能可以實現成單獨的服務,并且允許開發者用他們熟悉的語言來實現。這種創建單獨服務的方法在ZStack中稱為進程外插件(out-of-process plugin)。開發者可以根據自己的喜好選用自己喜歡的語言,創建與ZStack管理節點進程分離的服務。如果服務本身功能單一,可以訂閱ZStack管理節點組播到消息總線的事件(canonical events),例如賬單系統就可以監聽各種資源的創建和銷毀事件,完全實現獨立開發。對于功能復雜的服務,例如需要訪問數據庫的服務,可以通過寫一個輕量級的插件安裝在管理節點中,然后跟進程外服務通信。第二種方式有點類似應用程序通過在操作系統中安裝驅動,來實現對內核的訪問。ZStack的web UI就是以這種進程外插件的方式實現的。
基于插件系統和進程外服務,ZStack可以在持續創新,開發出各種適應用戶需求的應用場景的同時,保持架構的穩定和松耦合。
總結
ZStack的整個架構并非離散的功能點的組合,而是在經過精密設計后相輔相成的。例如要實現查詢API自動化,數據模型就必須預先定義完備;又比如要實現無鎖架構,就必須要有無狀態服務的基礎。通過對架構的縝密思考,ZStack有信心解決當前IaaS行業面臨的困難,為用戶提供一款優秀的開源軟件。
附:ZStack架構PPT下載
對話張鑫
CSDN:OpenStack生態已經比較成熟,公有云私有云的成功案例都有了,我們為何還需要ZStack項目?
張鑫:IaaS領域是時候需要新鮮血液了。
自亞馬遜2006年發布EC2公有云以來,IaaS(基礎架構即服務)領域持續創新,先后出現了Eucalyptus, CloudStack,OpenNebula這樣的開源軟件。到2010年OpenStack出現,整個創新達到了一個高潮。從業者都認為云計算的春天來了,認為傳統企業可以很快的從上個世紀的IT架構中解脫出來,迅速遷移到由軟件定義的數據中心。但讓人大跌眼鏡的是,5年過去了,Eucalyptus, CloudStack,OpenNebula已漸漸淡出人們的視線,OpenStack一統天下,卻遲遲打不開企業軟件的市場。就在去年,OpenStack的發起者Rackspace,宣布不再以純IaaS提供商的身份進入市場,而是轉向專注于核心業務“為客戶管理服務”,在跟以亞馬遜為首的公有云巨頭的競爭中敗下陣來。最近,著名OpenStack公司Nebula倒閉,給出的理由是“市場不成熟”,更是給整個IaaS產業澆了一盆冷水。一時間各種悲觀論調四起,例如認為企業云市場根本不存在,又例如公有云最終統治世界,企業不再需要自己維護數據中心。
我于2010年加入Cloud.com,作為CloudStack前核心開發人員,一直緊密的關注整個產業以及各個開源IaaS軟件,深深感到市場的需求是巨大的,但當前的產品離市場的要求差距很遠。隨著時間的推移,這個鴻溝越來越大,絲毫沒有減小的跡象。
當前開源IaaS軟件的痛點可以概括為四個方面:易用性差,不穩定,性能差,難擴展。而這四個方面又是阻礙市場接受IaaS軟件的至關重要的因素。根據我多年來對各個項目的觀察,認為導致目前狀況的原因,并不是開源社區缺乏有才能的開發人員,而是這些項目起源太早,缺乏對市場的足夠理解。這些項目早期都是盲目模仿亞馬遜EC2模式,在快速開發功能的同時自然生長,用俗話說就是“摸著石頭過河”,導致了在架構設計方面思考過少,累積了大量欠賬。而前述的幾個方面,又正是不從架構入手重新設計,就不能解決的問題。但我們又不能期望像OpenStack這樣擁有幾百萬行代碼的項目從底部推到重來?;谶@樣的現實,我認為不重新設計一款IaaS軟件是無法解決已有的問題的。在退出了原來CloudStack的工作后,我跟搭檔一起建立了ZStack,希望從根源上解決當今IaaS軟件遇到的各種問題,為整個行業帶來一款真正能打開企業市場的軟件
CSDN:能否介紹一下ZStack的市場目標,以及社區規劃?
張鑫:ZStack的最終目的,并不是為喧鬧的云市場添加更多的噱頭,而是解決數據中心管理的一個剛需:即面對越來越多的硬件,如何管理它們,以及如何自動化這個管理的過程。我們相信終有一天,傳統企業會擺脫人工手動配置或寫腳本這種上個世紀的技術,將自身的IT架構遷移到完全通過API管理的,軟件定義的數據中心中。此外,隨著企業軟件技術的不斷創新,最終會是以SaaS(軟件即服務)的方式在IT設施中部署。到那個時候,企業軟件再不是為某個操作系統所設計的單機程序,而是為某個云設計的分布式程序。IaaS以及之上的PaaS就是這些企業軟件的入口。依托ZStack的插件架構,我們完全相信我們可以逐步完善成一個涵蓋IaaS和PaaS的平臺,并且由于我們是IaaS和PaaS高度集成,提供的用戶體驗也必然優于同類軟件間的第三方集成,從而成為未來企業軟件的部署入口。
ZStack是一個開源項目,并且會一直堅持開源。我從2006年加入XEN社區到現在,就一直在開源領域工作,經歷過不少成也開源敗也開源的例子。例如OpenStack發跡于社區,但現在遇到了很多困難也源于社區。對于ZStack,我們歡迎任何形式的,基于Apache 2.0許可證的貢獻。同時我們會負責維護ZStack核心穩定,對于提交到核心服務的代碼進行嚴格控制。這樣的代碼會是少量的,因為在插件架構下,大部分功能會是以單獨的插件方式實現。我們會推出兩個目錄:plugins和contribs。凡是ZStack自己的測試架構可以保證質量的插件,我們會放到plugins目錄去,由我們承諾質量。對于測試架構無法保證的插件,例如需要特殊外設配合的插件,我們會放到contribs目錄,表示用戶在使用時需要自擔風險。
總而言之,ZStack是個年輕的項目,是IaaS領域的一個新兵。但我們繼承了先行者的經驗,學到了先行者的教訓,所以相信我們能比先行者走的更遠。對于現有的IaaS項目,我們也不是扮演一個挑戰者,而是為這個領域提供多一個選擇。用我搭檔的話說:我們不是螞蟻與大象跳舞,我們是站在大象背上的螞蟻,所以能看得更遠。
編輯點評:作為“站在大象背上的螞蟻”,ZStack的插件式架構設計確有可圈可點之處。根據初步測試者的評價,ZStack也沿承了CloudStack的一些亮點。只是目前OpenStack的社區生態已經很成熟,雖然遇到各種難題,OpenStack還是在不斷的實踐中得到進步,被應用于各種公有云、私有云之中。例如金山云合伙人宋偉將在“2015 OpenStack技術大會”上分享“Openstack 在公有云中的運用”,分享金山云解決了哪些問題以及如何解決。已經將OpenStack應用在生產環境中的用戶,不太可能改換門庭。這意味著,雖有機遇,ZStack的初期發展同時還是會遇到很大的挑戰。但正如張鑫所說,為這個領域提供多一個選擇,總是一件好事。祝ZStack好運!