Empire:一個基于Docker和亞馬遜ECS的開源PaaS平臺
Heroku已經能很好的滿足很多人的需求,但當我們不斷壯大,問題和瓶頸頻現,為此我們開始尋求解決之道,首先關注的是開源社區中支持Docker的平 臺,如Flynn、Deis、CoreOS、Kubernetes等,但都不理想,后通過使用亞馬遜ECS,最后確定了Empire,用Empire完成 從Heroku到亞馬遜ECS的無痛遷移,過程與挑戰都在文中做了說明。
Remind是一個適用于師生及家長的通訊應用。老師可以通過它給學生和家長群發信息,高效傳達信息的同時,讓家長更多地參與教學。目 前,Remind已經有約100萬名教師用戶和1700萬家長及學生用戶,建立起了強大的通訊網絡。在8月份返校季期間,每天有20萬-30萬名學生下載 這款應用,在蘋果應用商店中排名第三,領先于WhatsApp 和推ter,排在第三位。
今天,Remind開源了我們自托管的PaaS系統: Empire。 Empire能為你提供一個基于Docker容器的集群,符合 12因子應用規范,基于強大的亞馬遜EC2 Container Service(ECS,EC2 容器服務)構造而來,具有功能完善的的命令行界面。
已經有了Heroku,且Heroku已經能很好的滿足很多人的需求,為什么我們還需要自己造一套Empire這樣的東西?這篇文章講述了為什么 我們決定從Heroku遷移出來,我們遇到了哪些挑戰,以及我們怎么用Empire完成從Heroku到亞馬遜ECS的無痛遷移。
講講一點歷史
在2011年的時候,Remind還是一個托管在Heroku的一個整體單一的Rails應用。那個時候一切都很簡單:一個應用使用幾個 dynos已經足以應付當時不大的流量。當時我們選擇Heroku因為它讓我們能專注于開發產品而無需關心基礎設施(infrastructure),對于一個當時不到十個人的團隊來說,這很重要。回想過去,這無疑是我們做的最好決策之一。但我們開始壯大
而在今天,事情變得有點不同了。我們有超過50個員工,2500萬客戶,50多個后端服務支撐著產品 - 其中有些是產品的核心部分,其它則是不同團隊開發出來用來滿足各種需求的。為了滿足這種規模,我們用了超過250個Dyno。我們慢慢發現,我們的發展模式在很多方面看來是獨一無二的。我們打造的是一個給老師使用的產品,在學生的返校季業務會迅速增長 - 每天有多達35萬的新用戶,超過500萬條的消息,每30分鐘系統就會出現一次峰值(heavy spike)。
我們開始意識到,如果想有一個能夠滿足我們業務增長的基礎設施,Heroku可能無法完成這一目標。我們遇到的主要問題有:
- 缺乏對安全的控制。我們十分推崇微服務/SOA的架構,然后我們有一大堆內部的服務。在Heroku中,每一個服務都暴露在外網,這些服 務本身難免有自己的弱點(nasties),因而需要身份認證,DoS防御(DoS mitigation),不斷的打安全補丁等。這跟我們想象的有很大不同。
- 缺乏可見性(visibility):我們需要對我們的應用的性能有更加透的認識。盡管Heroku提供了這種可能,卻跟我們想象中的仍有距離,我們需要知道在操作系統和主機的層面都發生了什么。
- 缺乏靈活性:我們需要構建性能更加強大,不僅僅只是受HTTP管控的服務。我們無法控制路由層(routing layer),因而實現一些中間件如限制速率,添加常見的認證和將路由某路徑的請求到不同的上游服務器等超過了其本應有的難度。 </ol>
- AWS:我們當時已經使用了很多亞馬遜的服務,如Redshift和DynamoDB,因而能直接運行在EC2上是必須的要求。這也能讓我們把這些數據存儲鎖定到特定的安全組(security groups)。
- 簡易化運維(Operational Simplicity):Heroku在讓運維的過程(如部署、擴展、配置更新)簡易化方面做的十分出色。我們也希望遷移后仍然能夠保持這個水準。我們不愿意看到部署新應用的時運維人員必須到場,并且我們希望部署能遵循共同的模式。
- Docker:這不是一個硬性的要求,但是我們還是想繼續使用容器來作為部署的單元,因為:
- 容器能隔離依賴,封裝的包移植性高,易于發布,很類似Go的包。
- 容器提供了更好的開發環境,因為開發和生產環境的相似度(dev/prod parity)更高。
- 容器能限制我們部署的時候那些不確定的部分。基礎設施(Imutability in infrastructure)中的不可變性有很大的好處。
- 容器能更有效地利用資源,降低成本。 </ul> </li>
- 容錯性(Resilience):我們對宕機這一問題的態度十分嚴肅。 并且我們知道運行著我們應用和服務的平臺本身應該健壯且容錯性高。同時,無宕機部署也是要求的一部分。 </ul>
- 這是一個第三方管理(managed service)的服務,因而我們不需要自己運行和維護自己的集群服務。
- 他集成了AWS的ELB(Elastic Load Balancing),這能解決零宕機,connection draining和通過基于DNS的服務發現。
- 失效模式(failure mode)的表現的跟我們預期的效果一樣。我們可以將機器池的所有主機(entire pool of machines)停止,并且當新的機器啟動的時候整個服務又能恢復正常。
- 我們對AWS的服務更加放心。AWS的服務,發展快而且步履穩定,基于它構建生產級別的PaaS十分完美。 </ol>
方案一:使用時下時髦的技術(all the Alphas)
我們開始調查開源社區中支持Docker的平臺,我們不想去創造 事物。當時,兩個看起來最有希望的系統是Flynn和Deis。因為一些原因,我們團隊不是很放心將這些項目投入生產環境使用。Flynn當時還尚未發布 穩定版本,且正在進行不小的架構調整。并且他們的負載使用的均為完全自有的方案,而一些成熟的方案如HAProxy、Nginx或者ELB都沒有用到。我 們簡單地試用了一下Deis,最終覺得其過于復雜。同時我們也了解到,尚未有一個規模與我們相當且在生產環境使用這兩種技術的公司。
基于我們的需求,Remind的一個小隊開始研發Empire項目,我們借鑒了Deis和Flynn的項目的一些理念,也借鑒了其它項目的好的地方,如Netflix的 Asgard和SoundCloud的 Bazooka。起初我們決定以 CoreOS為基礎,使用 fleet作 為后端來調度機器集群。但是按照我們最初的設計決定,調度的后端應該是插件式(pluggable)的。我們有一個自定義的路由和服務發現的層,使用的是 由confd和registrator進行配置的Nginx,這都運行的很好,直到我們開始進行錯誤測試,我們才開始遇到了很多etcd脆弱的問題(當時 etcd的版本還是0.4),也遇到了fleet當中的 bug ,并且我們尚未解決不宕機部署的問題。
我們清醒的認識到我們需要一個比fleet更好的調度后端。在研究Kubernetes的時候我們發現其需要運行 網絡覆蓋層(network overlay)于是我們把它給否決了,因為我們實在不想自己運行并管理集群。
方案二:使用亞馬遜ECS
我們嘗試將這些新的或者看著不錯的項目拼湊成一個生產級別的PaaS平臺,結果證明這只會給人帶來失望。很顯然,我們應該退一步以求海闊天空,盡量簡化并剔除不穩定的組件。
恰巧這個時候亞馬遜的ECS發布了,我們立即發現到它幾乎能解決我們遇到的所有問題:
經過一些簡單的調查和原型,我們把調度后端換回到亞馬遜ECS。每一個定義在Procfile里面的進程都會被直接映射成一個亞馬遜ECS中的一 個服務。因為亞馬遜ECS集成了ELB,我們也決定棄用自己的路由層(routing layer)并使用將ELB依附到一個app的web進程。這個帶來一個問題,我們該如何解決系統中的服務發現問題?我們決定選用使用一個私有的 Route53然后創建CNAME記錄指向每一個應用的web進程。我們使用DHCP的選項集(option sets
)來設置搜索路徑為.empire
來達到服務只需要知道他們想交流的服務的名稱即可(如:http://acme-incc
)。我們去除了系統中不穩定的地方,如etcd;我們的主機集群現在只是簡單的安裝有Docker和亞馬遜ECS的代理的Ubuntu主機。
對于我們的架構,這個系統運行十分良好。我們有一個router的應用依附在對公網可見的ELB(在Empire里,這個應用默認是只內部可見,但是可以通過給其添加一個域名讓其公共可見)。
這個應用跑著一個Nginx,負責到相應的私有應用的路由,不管這是我們的API,Web的控制臺(dashboard)或者其它服務。它也會負 責請求的ID生成所以我們可以方便的追蹤請求在服務間的移動。這里最大的好處是現在router可以以Empire中其他應用一樣的方式來管理;一樣的部 署方式;一樣的配置方式;并且可以輕易的開發環境用運行起來,只需要一個簡單的docker run remind101/router
命令。在以后,它甚至可以換成如 Kong這樣的東西。
Empire能給我帶來什么?
如今Empire是一個 運行簡單,自托管的PaaS,其通過在亞馬遜ECS上一個輕量的層的方式實現。它實現了Heroku的一部分Platform API,這意味著你可以使用hk或者heroku CLI客戶端,或者我們的 empCLI。這里是一些Empire易用的例子:
部署一個Docker注冊表中新的應用就如敲一個emp deploy <image>:<tag>一樣簡單:
$ emp deploy remind101/acme-inc:latest
應用部署后我們可以列出這些應用:
$ emp apps acme-inc Jun 4 14:27
或者你可以列出那些正在運行的應用:
$ emp ps -a acme-inc v2.web.217e2ddd-c80c-41ed-af16-663717b08a3f 128:20.00mb RUNNING 1m "acme-inc server”
我們可以擴展一個在Procfile中單獨的一個進程:
$ emp scale worker=2 -a acme-inc $ emp ps -a acme-inc v2.web.217e2ddd-c80c-41ed-af16-663717b08a3f 256:1.00gb RUNNING 1m "acme-inc server" v2.worker.6905acda-3af8-42da-932d-6978abfba85d 256:1.00gb RUNNING 1m "acme-inc worker" v2.worker.6905acda-3af8-42da-932d-6978abfba85d 256:1.00gb RUNNING 1m "acme-inc worker”
甚至可以明確的指定CPU和內存的限制:
$ emp scale worker=1:256:128mb -a acme-inc # 1/4 CPU Share and 128mb of Ram
我們可以列出以前的發布版本:
$ emp releases -a acme-inc v1 Jun 4 14:27 Deploy remind101/acme-inc:latest v2 Jun 11 15:43 Deploy remind101/acme-inc:latest
我們也可以在幾秒鐘內回滾到以前的版本:
$ emp rollback v1 -a acme-inc Rolled back acme-inc to v1 as v3.
這些背后都發生在我們控制的硬件上面。
現在可以上生產環境嗎?
Empire現在還沒有到1.0(寫這篇博文的時候版本為0.9.0),但是在過去幾周,我們亞馬遜上的ECS 大部分的應用和服務都依靠Empire來管理,它們都十分穩定。這些應用在從Heroku遷移到Empire后的性能顯著提升了。基本上我們能觀察到 99%的請求的響應時間有兩倍的減少,變化和峰值也更少了。這里是一些例子:
這個圖顯示了在我們從Heroku遷移到亞馬遜ECS后,從API(RTT)上可以看到,文件服務的響應時間:
這個圖顯示了我們服務中特定端點(endpoint)的響應時間,其作用是用來管理一個用戶的未讀消息數。
這是我們的API中看到的響應時間的改變情況(這個應用仍運行在Heroku上面;我們期待在轉到Empier后可以減到更少,然后更加平穩)。
我應該使用它嗎?
這看情況。如果你只是一個小的創業公司,說實在的,使用Heroku就夠了。因為這是部署應用最簡單的方式。 Empire并不是沒有成本,你還需要創建你自己的日志和數據量化方面的基礎服務(logging and metrics infrastructure)(這一部分我會在未來的博客里面講),并且Empire仍處于頻繁的開發階段。我們仍是Heroku的忠實用戶,我們會繼 續在上面運行一些非核心的應用。但是如果你碰到了一些和我們一樣的瓶頸,我們希望Empire能一樣讓你的基礎設施更上一層樓。
你們為什么不使用XXX?
我們的終極目的是為我們在Remind碰到的問題,尋求一個簡單而健壯的方案。盡管我們不畏懼使用一些熱門的 新技術,但是我們更看重穩定且能達到目的(just work)的技術的價值,它們不會半夜將你吵醒。我們平臺的絕大部分都是基于這些穩定的技術創建的,如Nginx、Postgres、RabbitMQ和 ELB,并且Amazon ECS也非常穩定。
如果有一件事情是確定的,那就是我們的基于容器的基礎設施在快速的改變。我們現在創造的東西,在幾年前根本不可能實現。所以要感謝Docker和Amazon ECS這樣的項目,讓一切成為可能。
未來
我們仍然對Empire有 宏大的計劃, 如將負載均衡器應用到任何進程上,而不僅限于web進程;擴展Profile以在版本控制中支持健康檢查,暴露配置;支持sidekiq容器所你可以在 linked容器里面運行如statd或者nginx等服務。我們也同時希望,最終也支持使用Kubernetes來作為調度后端。
總之我們整個團隊滿意現在遷移到亞馬遜ECS和Empire之上的成果,我們將其開源希望它也可以幫助到你。
原文鏈接:Introducing Empire: A self-hosted PaaS built on Docker & Amazon ECS(翻譯:鐘最龍 校對:魏小紅)
來自:http://dockone.io/article/462本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!