揭秘Amazon EC2容器服務背后的技術細節
本文就Amazon ECS服務的兩大核心:集群管理和容器調度,進行了簡單的闡述,并介紹了ECS是如何實現支持并發操作的鍵值對存儲的,為我們實現相關服務提供了一定參考。
在最近一篇關于Amazon EC2容器服務(Amazon ECS)的文章中。我討論了在一個集群中運行現代化分布式應用的兩個關鍵組件:可靠的狀態管理和靈活的調度。Amazon ECS簡化了構建和運行容器化應用的流程,但是如何實現才是Amazon ECS真正有意思的地方。今天,我想要探討Amazon ECS架構并闡述這個架構能夠做些什么。如下是Amazon ECS的基本組件圖:
我們如何協調(Coordination)集群
讓我們來談談Amazon ECS到底做了什么。Amazon ECS的核心是集群管理器,它是一個后臺服務,能夠處理集群協調和狀態管理的任務。在集群管理器之上是不同的調度器。集群管理和容器調度是互相解耦的,所 以Amazon支持客戶使用和創建他們自己的調度器。集群其實就是應用可以使用的計算資源池。而這里的資源池就是根據容器劃分的Amazon EC2實例的CPU、內存和網絡資源。Amazon ECS通過運行在集群中每個EC2實例上的 容器代理來協調集群。代理允許Amazon ECS與集群中的EC2實例進行通信,并根據用戶或調度器的請求來啟動、終止和監控容器。代理使用Go語言編寫,資源占用少,目前在GitHub上基于Apache協議開源。歡迎大家貢獻和反饋。我們如何管理狀態
為了協調集群,我們的集群上需要有一個SSOT[單一數據源]:集群中的EC2實例,運行在EC2實例上的任務,組成 任務的容器,可用/占用資源(例如,網絡端口、內存、CPU等)。在獲得精確的集群狀態信息之前,我們是不可能成功開啟和終止容器的。為了解決這個問題, 需要在某個地方存儲狀態,因此現代集群管理器的心臟是鍵值數據庫。
這個鍵值數據庫對任何集群輸入的和存儲于此的信息表現為SSOT。為了保證可靠性和可擴展性,這個鍵值數據庫需要采用分布式來確保持久性和可用 性,并規避網絡劃分和硬件故障帶來的影響。也正因為鍵值數據庫是分布式的,確保數據一致性以及正確的進行并發修改會變得更加困難,這種情況在狀態持續變化 的環境(比如,容器的停止和啟動)中尤甚。對此,為了保證多狀態修改不會出現沖突,某些形式的并發控制就需要落實到位了。打個比方,假設有2個開發者從某 個EC2實例請求剩余的內存以供他們的容器使用,這個時候,只有其中一個容器能夠真正得到這些資源,而另一個則會被告知請求未完成。
為了實現并發控制,我們采用了Amazon分布式系統的核心原語之一來實現Amazon ECS,這是一個基于Paxos的事務日志的數據存儲系統,它保存了每一項數據變更的記錄。在日志中,任何數據的寫入均以事務的形式提交,并對應一個特定 順序的ID。數據當前的值就是日志中記錄的那些事務的總和。對于任何數據的讀取,得到的都只是日志當前時間點的一個快照。如果寫操作是繼上次讀取操作完成 以來最新提交的事務,則判定寫操作成功。這種原語允許Amazon ECS以樂觀鎖的形式存儲集群的狀態信息,對于共享數據經常變動的場景(比如當需要表達諸如ECS之類的計算資源共享池的狀態時)而言,這是一種理想的方 式。這個架構使得Amazon ECS具有高可用性、低延遲和高吞吐量的特點,因為數據存儲并未使用悲觀鎖(譯者注:作者自己表述得很含糊,大家參見
多版本并發控制MVCC)。
通過API訪問
既然我們有了一個鍵值數據庫,那么我們便能夠成功協調集群,并確保所需數量的容器正在運行,因為我們有一種可靠的方法來 存取集群的狀態。之前提到過,我們解耦了集群管理和容器調度兩個模塊,因為我們希望客戶能夠充分利用Amazon ECS狀態管理的能力。我們已經通過一系列API開放了Amazon ECS集群管理器,它允許客戶以結構化的方式訪問存儲在鍵值數據庫中的集群狀態信息。
通過list命令,客戶可以讀取托管的集群,特定集群中運行的EC2實例,運行中的任務以及組成任務的容器配置(如任務定義)。通過describe命令,客戶可以獲取EC2實例的具體信息以及每個實例上的可用資源。最近,客戶亦可以啟動和停止任何集群中的任務了。近期,我們針對Amazon ECS進行了一系列的負載測試,我們希望分享一些性能要點,客戶在Amazon ECS上創建應用的時候應該會關注它們的。
上圖顯示了一個負載測試的結果,在這次測試中,我們在Amazon ECS集群中添加和刪除實例,并測量72小時的周期內,調用‘Describe Task’API時,百分比排列位于第50位和第99位的延遲。你可以看到,盡管集群數量有較大的波動,但是延遲相對而言并沒有什么抖動。Amazon ECS可以如你所需地進行擴展,不管你的集群規模有多大,且根本無需操作或擴展集群管理器。
這組API是客戶在Amazon ECS上搭建解決方案的基礎。調度器只是提供了關于何時、何地以及如何開啟和停止容器的邏輯。Amazon ECS的架構為分享集群狀態而設計,它允許客戶根據需要為應用運行各種調度器(如二進制打包、發布等)。這個架構允許調度器查詢集群的具體狀態,并從通用 池中分配資源。樂觀并發控制允許調度器無沖突地獲取它們所請求的資源。一些客戶已經在Amazon ECS上創建了各種有趣的解決方案,下面我們來分享一些具體的示例。
Hailo——彈性資源池上的定制調度
Hailo是一個免費的移動APP,它允許人們招呼一輛認證的出租車到其所在地。Hailo擁有 一個全球網絡,囊括了超過60000名司機以及一百萬以上的乘客。Hailo于2011年成立,從第一天開始就使用了AWS。在過去的幾年中,Hailo 從AWS單一區域上運行的應用集合演化為貫穿多個區域的微服務架構。之前,每個微服務都跑在靜態劃分的實例集群上。Hailo遇到的問題是跨分區的資源使 用率較低。這個架構并不具備很強的擴展性,并且Hailo也不希望它的工程師關心基礎設施的細節或者微服務的部署問題。
為此,Hailo決定基于服務優先級以及其它的運行時指標對容器進行調度。后來他們選擇了Amazon ECS來作為集群管理器,因為ECS可以輕松的管理任務狀態并訪問集群狀態的API。同樣,Hailo可以根據自己的需求來定制調度器。
Remind——平臺即服務
Remind是一個web端和移動端應用,使得老師能夠給學生發送信息并和家長取得聯系。Remind平臺 上擁有24M用戶和超過1.5M的老師。它每月傳遞150M條信息。Remind起初使用Heroku來運行整個應用設施,從消息推送引擎、前后端 API、Web客戶端到聊天后臺。這些設施中的大部分都以龐大的應用塊進行部署。
隨著用戶的增長,Remind希望擁有橫向擴展的能力。因此大約在2014年年底,它的工程師團隊開始摸索著向基于容器的微服務架構遷移。團隊希 望基于AWS搭建一個PaaS,確保它能夠兼容Heroku的API。一開始,團隊期望能有一個開源的解決方案(比如,CoreOS和 Kubernetes)來負責集群的管理以及容器的協作,但是由于團隊的規模較小,因此他們沒有時間來管理集群的基礎設施,同時保證高可用性。
在簡要評估了Amazon ECS之后,團隊決定在此服務的基礎上搭建PaaS。Amazon ECS是全托管式的,這使得工程資源能夠被集中于開發和部署應用;這里并沒有集群需要管理和擴展。在6月份,Remind開源了他們基于ECS的PaaS解決方案,名為“
Empire”。憑借Empire,Remind得到了可觀的性能提升(例如,延遲和穩定性)以及安全優勢。他們接下來幾個月的計劃是將90%以上的核心設施遷移到Empire。
Amazon ECS——一個全托管的平臺
上述只是我們從客戶處看到的其中兩個用例。Amazon ECS架構允許我們提供一個具有高可擴展、高可用、低延遲的容器管理服務。通過API樂觀并發(譯者注:樂觀鎖)地訪問共享集群狀態的能力,使得用戶得以 按需創建任何定制容器解決方案。我們一直致力于為客戶消除重復而繁重的任務。通過Amazone ECS,根本不需要安裝或操作集群管理程序,客戶理應僅僅專注于開發優秀的應用。原文鏈接:Under the Hood of Amazon EC2 Container Service(翻譯:孫科 校對:李穎杰)