Flynn初探:基于Docker的PaaS平臺
Flynn是一個開源的PaaS平臺,可自動構(gòu)建部署任何應用到Docker容器集群上運行,其功能特性與組件設計大量參考了傳統(tǒng)的PaaS平臺Heroku。本文旨在從使用動機、基本對象、層次架構(gòu)、功能組件、基本工作流這幾個方面對Flynn做總體的介紹。
為什么需要Flynn
為了便于理解Flynn的作用與功能,讓我們先來看看應用程序從開發(fā)到構(gòu)建再到部署再到運行分別需要經(jīng)歷的幾個實體狀態(tài):
更具體一點,以一個Java程序為例來描述:
- 源代碼:包括*.java、log4j.properties、pom.xml等文件。
- 發(fā)布包:源代碼被編譯打包后生成一個JAR包,這個就是發(fā)布包。
- 部署配置:比如每個進程的啟動命令、環(huán)境變量、系統(tǒng)屬性等。通常,這些配置會寫在一個啟動腳本里面。
- 進程:運行Java程序的實體。一個Java程序可以起多個進程,每個進程啟動不同的主類(實現(xiàn)了main()方法的類,一個JAR包可以包含多個主類)。
引入Docker后,發(fā)布包變成封裝了JAR包與JDK環(huán)境的鏡像,進程變成在相互隔 離的容器里運行。但是,從源代碼到鏡像、從鏡像到運行容器這兩步轉(zhuǎn)換過程需要用戶人工的操作。尤其是后者的轉(zhuǎn)換,涉及到集群資源調(diào)度、自動部署、配置管 理、容器管控等一系列的復雜流程。更進一步,在運行階段還涉及擴縮容、日志查看、錯誤處理、運行監(jiān)控等運維需求,如果全部人工操作將耗費巨大的工作量。
這時候類似Flynn這樣的PaaS出場了,基于Docker之上進一步封裝了整個構(gòu)建、部署、運行工作流,使得用戶只需簡單地提交代碼即可完成開發(fā)到運行的快速轉(zhuǎn)換:
- 開發(fā)到構(gòu)建:用戶通過git提交源代碼,由Flynn自動構(gòu)建鏡像,并提供版本的管理——用戶可以創(chuàng)建新版本(提交新代碼或修改部署配置)、回滾老版本等。
- 部署到運行:Flynn自動選擇運行機器,為每個進程副本部署啟動單獨的容器,并提供進程的管理——用戶可以做擴縮容、查看日志、監(jiān)控狀態(tài)等。
Flynn的基本對象
下面我們來看看發(fā)布包、部署配置、進程這三個實體在Flynn中是如何抽象的。如下圖所示是其基本對象的關(guān)系描述:
- App:表示一個應用,所有其他對象都是圍繞App而展開。
- Artifact:表示應用的發(fā)布包,實際上對應一個Docker鏡像。
- Process:表示應用的進程。通過一個鏡像可以啟動多個不同的進程,每個進程運行在自己單獨的容器里。
- Release:是應用發(fā)布態(tài)的 抽象表示。它在Artifact的基礎上增加了一些不可變(immutable)的靜態(tài)配置,比如每個進程的啟動命令行、環(huán)境變量、綁定端口、等。要修改 這些配置,需要生成一個新Release。Release這種不可變性是為了方便做Rollback,即應用隨時可以回退到之前的Release。
- Formation: 是應用運行態(tài)的抽象表示。它在Release的基礎上增加了可變(mutable)的動態(tài)配置,即每個進程的副本(replica)個數(shù)。
- Job: 是進程副本的抽象表示,每個Job對應一個運行容器。因此,在后文中可以看到,Job是資源調(diào)度的基本單元。
Flynn的層次架構(gòu)
如下圖所示,F(xiàn)lynn的架構(gòu)自下而上分為兩個層級——Layer 0和Layer 1。簡單地理解,可以認為Layer 1負責接受用戶請求,封裝成應用的運行指令,再由Layer 0解決在哪里運行、以什么方式運行的問題。具體一點講,Layer 0面向的對象是Formation,負責將底層的集群資源封裝成可執(zhí)行Formation的一臺主機;Layer 1面向的對象是App,負責將App從源代碼構(gòu)建成Artifact,進而封裝成Formation提交給Layer 0去執(zhí)行。
這種分工明確的層次劃分,使整個系統(tǒng)非常靈活,相互松耦合,便于任意組件的替換(比如,甚至可以把Layer 0替換成不用容器去執(zhí)行Formation)。
Flynn的功能組件
下面總結(jié)一下組成兩個層級的各個組件及其功能(所有組件自身都可以運行在容器里):
Layer 0
- Scheduler: 資源調(diào)度器,定期從Layer 1獲取Formation的更新,再根據(jù)每個Formation的部署配置生成一個個的Job,***從集群中選擇合適的機器去運行這些Job。
- Host Service: 運行在集群每臺機器上的agent,負責管控運行在本機的容器,并收集運行狀態(tài)信息。
- Host Leader:一個特殊的Host Service,做為"cluster leader",負責維護整個集群的狀態(tài)信息(比如有哪些機器、每臺機器上運行的Job等),并提供給Scheduler用于資源調(diào)度。
- Discoverd:基于etcd的服務發(fā)現(xiàn)模塊,提供容器間的發(fā)現(xiàn)機制。實際上,F(xiàn)lynn自身的組件間通訊也是通過Discoverd來相互發(fā)現(xiàn)的。
Layer 1
- CLI:提供給用戶使用的命令行工具。
- Controller:為Flynn系統(tǒng)的入口, 封裝了核心對象(比如app/artifact/release/job)的增刪改查操作,以RESTFul接口方式提供給外部客戶和內(nèi)部組件調(diào)用。它維 護的REST對象將持久化到postgre數(shù)據(jù)庫。Layer 0的Scheduler就是通過Controller的接口來獲取Formation更新的。
- GitReceiver:接受用戶git push源代碼的SSH服務器。接受到git push后將觸發(fā)Receiver。
- Receiver:基于buildpack機制, 利用SlugBuilder從源代碼包構(gòu)建slug包。buildpack和slug都是從Heroku借鑒過來的概念。簡單地理解,buildpack 是一組用于構(gòu)建源代碼的腳本,buildpack可以多種多樣,每個buildpack可構(gòu)建某種類型的源代碼,這種類型可以是不同的語言(比如 Java、PHP)、不同的構(gòu)建方式(比如maven、gradle);而slug則是buildpack構(gòu)建生成的部署包,包含了編譯輸出文件、依賴庫 文件等運行環(huán)境。
- BlobStore: HTTP文件服務器,用于上傳/下載slug包。
- SlugBuilder:接受源代碼包,基于某種buildpack構(gòu)建生成slug包。選擇哪一種buildpack可以顯式地指定,也可以由SlugBuilder根據(jù)源文件自動匹配。
- SlugRunner:運行slug包,會從BlobStore下載應用的slug包。
Flynn的工作流
下面通過一個例子來展示Flynn各個組件的工作流。使用Flynn來構(gòu)建部署應用最基本的流程是以下三步:
用戶創(chuàng)建app:
- flynn create myapp
用戶提交app代碼:
- git push flynn master
用戶擴容app的進程:
- flynn scale web=2
對比Kubernetes
Kubernetes是Google開源的Docker容器集群管理系統(tǒng),為容器化的應用提供資源調(diào)度、部署運行、服務發(fā)現(xiàn)、擴容縮容等整一套功能,更詳細地介紹請參考作者的另一篇文章《Kubernetes初探:原理及實踐應用》。
在應用的抽象上,F(xiàn)lynn與Kubernetes有本質(zhì)的區(qū)別:Flynn的應用管 理單元是App,只對應一個Docker鏡像,但可以由這個鏡像來啟動多個進程,并且每個進程可以單獨擴縮容;而Kubernetes的應用管理單元是 Pod,可對應多個不同的Docker鏡像,并且Pod內(nèi)的各個容器保證會運行在相同的機器上,整個Pod作為擴縮容的基本單位。
另外一個根本的區(qū)別是Kubernetes不提供鏡像構(gòu)建與版本管理的功能。因此,Kubernetes只能看成是面向容器而不是面向應用的系統(tǒng)。當然,我們可以在Kubernetes之上擴充這些功能。
對比Deis
與Flynn類似,Deis也是受到Heroku的啟發(fā),基于Docker之上構(gòu)建的PaaS平臺。因此,從功能特性到應用抽象,兩者是大同小異。
至于兩者的差異,了解不是很多,這里提三點:***,Deis是用Python開發(fā)的, 而Flynn是Go;第二,Deis依賴于CoreOS,而Flynn因為所有組件都可運行在容器里,沒有OS的依賴;第三,Deis在構(gòu)建階段,除了 buildpack方式構(gòu)建外,還支持Dockerfile與鏡像直接上傳兩種方式,相對Flynn更為靈活。
原文出自:http://blog.csdn.net/zhangjun2915/article/details/41266133