Amazon EC2,將節點加入現有集群的最快方式
我是亞馬遜 AWS 的新手。很多時候,我聽到人們產生實例並幾乎立即將它們放在負載均衡器後面並放入現有集群中。
在傳統的託管機器世界中,這將包括配置硬體、安裝作業系統、在機器上配置網路,一旦網路可用,使用您選擇的工具(例如 CFengine、Puppet 或 Chef)來引導機器它的類。
似乎有一些“捷徑”可以讓特定類別的伺服器在 Amazon EC2 中啟動並執行。如果我的伺服器上執行了一個特定的堆棧,例如 erlang、tomcat6 等。讓這些堆棧啟動並執行並連接到 Amazon 的負載均衡器的最快方法是什麼?從網路到軟體堆棧再到核心調整?它是創建 AMI 然後針對新實例執行 Puppet 等工具的組合嗎?
任何的想法
簡短的回答:
這取決於您的應用程序 - AMI 始終是起點,您需要在啟動實例時自定義多少,這將決定除了簡單的“負載均衡器後面的自動縮放實例”範例之外您還需要什麼。
不是那麼簡短的答案:
EC2 上的實例與 VPS 非常相似——事實上,它們是虛擬機(亞馬遜使用 Xen 虛擬化)。我看到 VPS 和“雲”伺服器之間的主要區別在於易於部署——在“雲”中配置和添加十幾個實例或幾百 GB 的儲存應該是一項微不足道的任務。
由於亞馬遜使用虛擬機,他們擁有這些機器的“圖像”。這些映像引用儲存並包含對預設核心(您可以更改)的引用。此映像的內容通常用於創建附加到實例的根卷。
您在很大程度上被亞馬遜提供的(相當多的)核心所困擾——編譯你自己的核心通常不是一種選擇——但你可以設置大多數參數並利用可用的核心模組來實現你想要的。一旦您創建了自己的 AMI,您從它啟動的所有實例都將是相同的(除了您讓 AMI 執行以自定義自身的任何腳本)。這使其成為幾乎所有案例的起點。
事物的“虛擬”性質有一些明確的好處。例如,您可以通過簡單地停止實例、分離根卷、附加新卷並重新啟動實例來切換根卷。同樣,您可以通過停止實例、修改實例屬性並重新啟動實例來更改實例類型。
當您啟動一個實例時,您指定(除其他外)實例類型(例如 m1.large)和 AMI。這意味著您的實例將使用該 AMI 上保存的所有內容啟動 - 預配置的作業系統,您安裝的任何軟體等。此外,AMI(或 ec2-run-instances 命令)可以引用額外的儲存 - 臨時或EBS 支持。對於額外的 EBS 儲存卷,可以從現有快照創建這些卷,並在實例啟動時附加到您的實例。(有趣的是,這些快照的內容是“延遲”載入的——這意味著您可以在快照完全載入之前訪問其中的數據,如果您正在載入大量數據,這將是有利的)。
考慮最簡單的場景——一個所有機器都是等效的集群——首先,假設我們正在為一個靜態站點提供服務。EC2 將允許您垂直擴展(更強大的實例)和水平擴展(更多實例)。所以,我們從最小的實例開始——一個 t1.micro,我們最終發現它無法處理負載。我們現在可以在彈性負載均衡器 (ELB) 後面添加第二個實例。因此,傳入的請求將發送到 ELB(它的設計應該考慮到冗餘和可擴展性 - 它應該自動添加更多資源以滿足對其提出的需求) - 並將其路由到其中一個實例,該實例將處理請求並通過負載均衡器返回。
為了進一步自動化該過程,我們可以使用 Amazon 的自動縮放 - 本質上,使用觸發器(Cloudwatch 指標的值),您可以動態添加和刪除實例(就像手動啟動實例一樣,您可以指定實例類型和 AMI的新實例)。此外,這些實例可以(它們不一定)與 ELB 相關聯,該 ELB 根據某些指標的變化(例如 CPU 負載、RAM 使用或其他一些自定義變數)自動增長或縮小您的集群。
現在 - 關於上述場景的幾乎所有內容都是“不好的做法” - 你可能不應該從 t1.micro 水平擴展,因為它們是功率不足的實例 - 所以你應該首先增加實例大小;ELB 的成本遠高於(保留的)t1.micro 的成本,使其在這種情況下(經濟上)不切實際;如果您在 AWS 上為靜態站點提供服務,您只需使用 S3 並完全放棄實例的費用和麻煩,但重點是一個例子。
讓我們舉一個更複雜的例子——一個 PHP/MySQL 站點(例如 Wordpress)。首先,我們將數據庫與 Web 伺服器分開 - 所以讓我們從每個實例開始 - 我們現在可以獨立擴展每個實例。可以說,我們可以使用 Amazon 的 RDS(儘管我個人更喜歡維護自己的 MySQL 設置),而不是自己託管 MySQL,這將簡化額外 MySQL 實例的部署(……當然是有代價的)。我們的網路伺服器都提供相同的內容,但現在內容可能會發生變化。儲存在數據庫中的更改(例如,新文章、評論等)不是問題——所有伺服器都從同一個數據庫實例中讀取。理想情況下,您會將程式碼儲存在某個中心位置(例如 S3),每個實例在啟動時都會拉取它。靜態資產可以從 CDN 提供,這樣您就可以避免在本地處理分佈式文件系統。(ELB 可以處理粘性會話,但最好將會話簡單地集中儲存(例如 Memcached),以便所有實例都可以訪問它們 - 請記住,請求可以在任何實例上結束)。
(AWS 確實有 Elastic Beanstalk - 它應該處理某些應用程序類別(例如 PHP/MySQL)所需的資源的配置 - 但我沒有個人經驗)。
對於更複雜的設置,您可以將使用者數據傳遞給實例,並且有一些方法可以獲取您正在執行的所有實例的列表(並且您可以標記您的實例以根據需要對它們進行分組)。您可以在消息隊列中處理任務(Amazon 版本是 Simple Queue Service…,或者如果需要,可以使用開源版本),以確保您的集群只處理每個請求一次。當然,您也可以使用典型的高可用性工具(例如 Heartbeat/Corosync、Pacemaker 等)來控制您的集群——這將使所有節點都“了解”彼此,並讓您控制在其上執行的資源每個節點。添加一個分佈式文件系統(例如 Gluster),您可以處理大多數情況。
除此之外,您仍然可以使用您提到的相同工具。上面的大多數想法都是基於多次部署相同的 AMI(您自定義 AMI,並啟動它的多個副本 - 每個副本都應該配備處理自己的基本配置(例如提取最新程式碼等)) . 如果您的實例要經常更改,或者您有一個更大的集群(例如,將更改部署到所有節點會有問題),或者如果您的節點不相似 - 那麼您可以根據自己的選擇部署節點配置管理軟體(例如 Puppet、Chef 等)。
您還可以採取另一個步驟 - 即提供您自己的“虛擬專用網路” - 本質上,允許您使用 NAT 創建一些面向私有和一些面向公眾的實例,並控制私有 IP 地址和網路介面(例如,您可以在單個實例上擁有多個介面)。
最後,如何部署應用程序在很大程度上取決於應用程序的需求——每個節點需要共享哪些資訊,集群中有多少個節點,以及哪些節點相互依賴。最簡單的場景將始終是每個節點可以相互獨立執行的場景,並且發送到任何節點的請求都會產生相同的結果……啟動一個實例,自定義它,創建您的 AMI,並在 ELB 後面自動擴展它. 所有其他場景都需要一些計劃來設計可以有效擴展的東西。
鑑於上述情況,我覺得指出另一面很重要——AWS 是一項很棒的服務——因為進入門檻很低——你基本上可以免費學習它(他們確實有免費套餐)——你就可以可以根據您的需要進行擴展。但是,AWS 上的每一件事都需要收費——執行實例的小時數、儲存的 GB 數、磁碟上的 I/O 量、向 S3 發出的請求數、(傳出)您使用的頻寬 - 一切。不可預見的事情很容易在相當短的時間內積累相當多的賬單。AWS 絕對不是所有問題的解決方案,也不是沒有限制(例如,在他們的網路上沒有廣播/多播數據包)。
(嗯,這最終比我打算寫的幾行多一點……)