做者 徐桂林 發佈於 2014年1月22日 前端
--------------------------------------------------------------------算法
在過去幾年裏,社交、移動和雲計算深入改變了整個互聯網的格局。做爲設計軟件領域的全球領導廠商,Autodesk也與2009年正式開始從傳統桌面設計軟件提供商向在線服務、協做和移動端設計轉型。在此次轉型中,公司充分利用現代雲計算的巨大優點給客戶帶來了大大超過傳統桌面軟件的處理能力、用戶體驗和性價比。其中AWS是目前公司服務的主要運行平臺,每一年在此投入千萬美金級別。後端
在過去的30多年裏,Autodesk擁有了很是多的桌面設計軟件(如AutoCAD,Maya,3dsMax等)。因爲設計軟件常常須要處理超大的數據集合(如整個上海中心的設計模型)和極其複雜的運算邏輯(如阿凡達電影畫面的繪製),其軟件尺寸通常都比較大(GB級別)。之前,客戶基本都是經過互聯網下載、快遞或者分銷商得到軟件安裝包,整個過程比較耗時。另外,軟件的升級、安裝和維護也是一個很是大的工做量(一些大的設計公司要購買上千份軟件拷貝)。儘管公司軟件已經支持基於應用程序虛擬化的集中管理模式,但它仍是有如前期基礎設施建設成本大,服務能力缺少彈性,仍須要專職運維人員等明顯的缺點。因此,提高軟件交付的用戶體驗成爲咱們必需要面對的一個問題。瀏覽器
如大多數人所猜想,SaaS成爲咱們的第一個嘗試方向。在2006年,Autodesk實驗室開始嘗試以SaaS提供設計軟件服務的可能性,而且取得了不錯的成績。可是,目前SaaS應用仍然面臨着瀏覽器能力限制、大數據傳輸慢等諸多問題,沒法給專業設計師提供傳統桌面軟件同樣的體驗和設計能力。 安全
隨着雲計算的興起,以AWS爲表明的基礎設施雲提供商讓咱們有可能以一種全新的方法去解決這個問題。咱們能夠利用基礎設施雲的強大後臺來幫助用戶運行虛擬化的軟件實例。用戶無需下載、安裝和維護這些軟件,只須要連接到互聯網上就能夠在線使用咱們的軟件。並且按需付費以下降使用成本。基於此,Autodesk實驗室在2009年開始這個嘗試(注:該服務已經於2013年成爲公司雲平臺產品的一部分),並選擇了AWS作做爲咱們的後臺雲服務提供商。選擇AWS有下面的幾個緣由:服務器
在完成服務的基本實現並上線服務後,整個後臺的維護和部署成本在不斷加大。尤爲考慮到咱們須要高頻(每月更新一次)、多地(多個AWS數據中心)部署服務並同時須要維持高的服務可用性,構建一個自動化的部署系統成爲必需要作的事情。網絡
做爲一個運行在AWS上的服務,咱們在設計之初就開始思考AWS給自動化部署帶來的新可能和挑戰。在咱們看來,針對AWS上服務的自動化部署須要特別關注到下面的一些特色:架構
結合上面的特色、DevOps的廣泛實踐和項目的實際狀況,咱們給整個自動化部署系統定下了下面的目標:運維
在肯定目標後,咱們進行了技術選型,但願可以找到既很好支持AWS相關自動化操做,又能集成DevOps優秀實踐的方案(注:那時AWS尚未推出OpsWorks服務)。但最後並無找到合適的方案,因而決定本身來實現整個自動化部署系統。通過幾輪的改進和實現,如今的自動化部署系統總體結構以下:工具
圖1:自動化部署系統總體架構
相似於傳統的自動化部署,咱們也一樣有開發分支和發佈分支,並與持續構建系統對接。當開發人員提交代碼後,相應的構建就會在代碼所在的分支自動觸發。在完成代碼編譯和集成的自動化測試(目前主要是單元測試)後,將產生相應部署組件並存放在構建系統中(目前,每一個構建會產生全部的系統組件並擁有一樣的版本號)。至此,整個構建過程完成。
爲了支持多環境部署和安全隔離,咱們使用兩個獨立的AWS帳號來運行不一樣的環境。其中開發環境在一個AWS帳戶內,只部署開發分支的構建。而生產系統則在另一個AWS帳戶中,其下運行Prod/Staging兩組環境。發佈分支永遠只會向Staging環境部署並在完成最後驗證測試後與當前Prod環境進行熱切換,從而達到無服務中斷的目的。
在完成自動化持續構建後,咱們就能夠部署其中的任意版本。當部署某一構建版本時(不管開發分支仍是發佈分支),整個流程以下:
圖2:一鍵式部署流程
圖3:運行時部署
看到上面部署流程,相信不少人會問一個問題:AWS不是能夠經過虛擬機鏡像(AMI)來啓動EC2實例,爲何不把上面的部署組件直接燒入AMI?這樣在EC2實例啓動後就直接使用而無需作運行時部署。其實,咱們的最初解決方案就是把部署組件直接燒入AMI,但很快就發現了這種方案的侷限:
部署組件的變化是很是頻繁的,尤爲是在發佈前,一天都可以產生上十次的變化。這就意味着自動部署系統可能須要頻繁產生AMI。而AMI的建立過程並不快(10分鐘~1小時),而且過多的AMI也會形成管理問題和額外的存儲成本。
做爲一個平臺項目,各個產品會在咱們的平臺上運行。咱們但願提供給各個產品部門的基本AMI是平臺版本無關的。這樣產品部門在基本AMI基礎上部署它們產品並從新生成的產品AMI也是平臺版本無關的。因而產品AMI能夠不作任何修改就可以快速採用最新的平臺版本。具體以下圖所示:
圖4:自動化部署中的AMIs
爲了保證圖4中的基本AMI和產品AMI是平臺版本無關,咱們就須要保證燒入AMI的全部部分都是可以獨立於平臺版本的。可是,啓動腳本須要作平臺組件的運行時部署,顯然這個運行時部署腳本也會隨着平臺更新不斷變化,因此咱們沒法直接把整個運行時部署腳本放到啓動腳本中。針對這個問題,咱們的解決方案就是把整個運行時部署腳本分紅兩部分。一部分作平臺組件的安裝、檢測工做,並隨安裝組件存到S3中,而另一部分只作基本不會改變的事情(下載平臺組件包並調用自動化部署腳本)並設置爲操做系統的啓動腳本。這也是圖3中啓動腳本和自動化部署分開兩部分的緣由。
正是由於採起了上面的AMI生成、管理策略,咱們的產品部門基本上不用太頻繁的更新它們產品的AMIs(除非產品自身有更新),真正作到平臺版本和產品版本的去耦合,極大的下降了運維成本。
因爲產品AMI是平臺版本獨立的,以它爲鏡像運行起來的EC2實例沒法知道應該去下載哪個版本的平臺組件。幸運的是AWS的EC2服務提供了「User Data」機制。簡單來講,就是在啓動EC2實例的時候能夠傳入一段用戶自定義數據給AWS。當這個實例運行起來後,實例內部程序能夠經過調用AWS EC2的元數據服務取得先前傳入的用戶自定義數據。因而,咱們能夠把當前須要運行的平臺版本號以「User Data」的方式傳給EC2實例,而後讓啓動腳本讀取相應版本號並下載相應版本組件來部署。
一樣,基於「User Data」機制和平臺版本無關的AMI,咱們很是容易得實現版本的回滾。只須要修改傳入給「User Data」中的版本號並保證要回滾到的平臺組件版本仍然存在於S3中便可。即便是從零開始回滾到之前版本也能夠在幾分鐘內完成(主要時間花費在啓動EC2實例上)。在實際運營中,由於已經有了Prod/Staging的熱切換,咱們通常會在切換上新的版本後保持原來的版本運行一段時間(這段時間通常是問題的高發期)以便作到秒級的回滾。
如前面所說,咱們須要格外關心在AWS上自動化部署的安全問題。在咱們的實踐中,時刻會遵循最小受權原則並利用AWS中的IAM服務實施,具體體如今下面的兩個原則上:
例如,咱們的構建系統須要訪問多項AWS服務資源(如S三、EC二、Cloud Formation等),而構建系統又在防火牆內部,因此咱們建立專用的 IAM User來作自動化部署並給予構建系統須要的資源訪問權限。另外,EC2實例須要訪問S3並下載部署組件,因此EC2應該以專用的IAM Role來運行並在IAM Role中給予相應的S3桶只讀屬性。
熟悉AWS服務的人可能都知道Amazon已經在2013年發佈了它的DevOps服務: OpsWorks。咱們的自動化部署系統爲何沒有選擇這個服務呢?最直接的緣由就是咱們開始構建自動化部署系統時候,AWS尚未發佈OpsWorks。在AWS發佈OpsWorks後,咱們對此作了仔細調研,並決定繼續使用目前的系統。要了解其背後緣由,就要完整理解AWS提供的一系列應用程序管理服務(Application Management Services)之間的關係。這裏,讓咱們首先看看AWS文檔中這張示意圖:
圖5:AWS中的應用程序管理服務
就如上圖所示,AWS爲各類應用場景提供了不一樣的解決方案。因爲針對的應用場景不一樣,這些服務的關注點也就不一樣。例如,AWS Elastic Beanstalk主要是爲Web應用程序提供快速部署服務(有點相似國內SAE、BAE等服務),它幫助開發和運維人員隱藏了大量的底層細節,很是方便上手部署應用。可是,該服務在管理底層基礎設施架構上就基本沒有多少靈活性,沒法適應項目的個性化需求。就咱們的服務而言,它開始於最右邊的徹底本身定製方案。在AWS推出Cloud Formation後,爲了提升系統的效率和自動化程度,咱們遷移到以Cloud Formation爲基礎的新方案。可是咱們沒有繼續向AWS OpsWorks遷移。究其原因,讓咱們先多方面比較一下AWS OpsWorks和AWS Cloud Formation:
特性 |
AWS Cloud Formation |
AWS OpsWorks |
基礎設施架構 |
以Stack的方式管理整個基礎設施,你能夠以任何你想要的架構組織你的基礎設施。 |
遵循常見的架構實踐,以Stack、Layer和App爲核心觀念來管理整個服務架構,並利用Chef 來把App自動化部署到各個Layer上。儘管它也有很大的靈活性,可是你須要把本身的基礎設施架構映射到上面的這些概念中以實施該服務。 |
AWS資源管理 |
支持幾乎全部的AWS資源。你能夠在Cloud Formation的JSON模板中方便地加入各類AWS資源。Cloud Formation會自動幫你管理各類資源之間的依賴關係。你也能夠自定義一些資源之間的邏輯依賴關係。 |
支持主要的AWS服務資源(如EC二、EBS、ElasticIP,ELB等),並利用這些資源構建常見的Layers。固然你也可本身加入一些非內建的資源(如RDS服務)到OpsWorks中來,可是它沒法達到Cloud Formation對於資源管理的廣度。 另外,目前的OpsWorks僅僅支持Amazon Linux 和Ubuntu LTS操做系統,你可使用這些系統的默認AMI或者在這些默認AMI基礎上建立的新AMI。 |
定製化 |
支持利用參數改變由資源模板定義的Stack默認行爲。 |
支持利用自定義JSON改變Stack的默認行爲。 |
自動部署 |
支持各類自動化部署工具(如Chef、Puppet等),可是你須要本身實現全部的自動化部署腳本。 |
支持基於Chef的自動化部署,而且提供了大量的內建自動化腳本。這些內建的自動化腳本會幫助開發和運維人員完成不少的常見工做(如自動部署Tomcat服務器等)並已經集成到整個服務中去。另外,它一樣支持自定義的Chef腳原本實現項目相關的部署。 |
彈性支撐 |
支持徹底自由控制的彈性策略。用戶可使用Auto-Scaling組加自定義的性能指標來肯定Scale-up/down的條件。 |
提供基於負載(Load-Based)和基於時間(Time-Based)的彈性策略。其中基於負載的彈性策略主要考慮CPU、內存等幾個主要因素。 |
系統監控 |
支持基於Cloud Watch的監控機制。用戶能夠監控大量的內建指標並添加自定義的監控指標到Cloud Watch中去。 |
提供以Stack爲單元的整合監控界面,一樣以Cloud Watch爲基礎提供監控服務。另外,它還提供了基於Ganglia的可選監控方案。 |
安全管理 |
支持IAM的完整功能。用戶能夠精細控制各個資源的訪問權限。 |
支持IAM的完整功能。並能方便的把相應的安全策略批量實施。 |
表1:Cloud Formation與OpsWorks的比較
參考上面的比較和咱們目前的自動化部署系統,OpsWorks對於咱們仍然有一些限制:
隨着OpsWorks的發展,這些限制將來均可能會被解決。可是,做爲一個已經運行的系統,咱們仍然須要仔細評估OpsWorks帶來的收益和成本以肯定是否遷移。若是須要在AWS上面部署一個新的應用,推薦的實踐就是如圖5從左向右依次選擇,而且在確認左面的方案有明確限制的狀況下再考慮下一個選擇。若是圖5中左邊服務已經可以解決問題,就不建議本身開發相應的系統。畢竟整個部署系統的開發和維護仍是須要一個不小的成本,而AWS提供的這些應用程序管理服務都免費的。另外,在絕大多數狀況下,Cloud Formation已經足夠靈活以知足你在AWS上部署服務。可是,在某些狀況下(例如,同時支持在多個雲服務提供商上部署服務),你可能還得選擇徹底本身開發或採用第三方供應商的方案。
在過去的一年裏,咱們利用上面的自動化部署系統讓整個部署過程的耗時從最初的幾天快速降低到幾分鐘以內,大大下降了的開發、運維人員的負擔。如此同時,自動化部署還把部署出錯的可能性降到了一個極低的水平,提升了系統的總體可用性。
在上面的文章中,我仔細介紹了整個自動化部署系統,並討論了怎樣充分利用AWS服務的特色來提升自動化部署的效率。該系統運行高效、穩定,並且極大程度的下降了平臺自身和運行於平臺上產品的運維成本。接下來,咱們仍然會持續改進整個系統,其中關注的重點有:
徐桂林現爲Autodesk中國研發中心的高級開發工程師。2007年加入Autodesk中國研發中心,前後在Autodesk Labs、CTO Office工做,如今Autodesk雲平臺事業部(Cloud Platform)工做。在2007年開始參與多個SaaS相關的開發,主要作前端開發。從2009年年末轉向作後端,開始使用AWS服務並領導中國團隊的開發工做。畢業於浙江大學計算機系CAD&CG國家重點實驗室,關注雲計算、前端開發等相關技術。
轉自:http://www.infoq.com/cn/articles/automated-deployment-practice-based-on-aws/