建構可擴充的彈性應用程式

建立兼具彈性與擴充性的網頁應用程式,是任何應用程式架構的核心要素。設計完善的應用程式應能隨著需求的增減而順暢調整,並具備足以承受一或多個運算資源損失的彈性。

本說明文件適合熟悉 Compute Engine 的系統作業專家閱讀。在本文中,您將學習如何使用 Google Cloud Platform (GCP),應用可廣泛適用於任何應用程式的模式和做法,來建構可擴充的彈性應用程式架構。您還可透過建構於 Ruby on Rails 應用程式上的熱門開放原始碼專案管理工具 Redmine 部署範例,來瞭解這些原則如何應用於實際的使用情況。在本文後段的部署範例解決方案一節中,您還有機會親自部署應用程式,並下載所有原始碼做為參考。

GCP 能讓您構建並執行既可擴充又具彈性的網頁應用程式。您可依需要使用如 Compute Engine 和自動配置器等服務來調整應用程式的資源。Compute Engine 的以秒計費模式讓您用多少就付多少,還可透過續用折扣自動獲得最優惠價格,讓您不必面對複雜的容量或預留規劃工作。

如要概略瞭解 GCP 提供的網路託管服務選項,請參閱提供網站內容一文。

定義擴充性和彈性

在介紹範例應用程式架構之前,讓我們先來談談「擴充性」和「彈性」這兩個詞的涵義。

擴充性:因應需求調整容量的能力

一個可擴充的應用程式不論使用者多寡,即使是 1 或 1,000,000 個使用者都能應付自如,並能自動從容應對流量的高峰期和低谷期。透過適時增減虛擬機器,可擴充的應用程式只會耗用因應需求的必要資源。

下圖顯示可擴充的應用程式如何因應需求的增減變化。

顯示資源如何因應需求擴充的圖表。

請留意,應用程式會隨著需求的變動而調整容量。這種設計上的配置有時也稱為彈性,能確保您僅針對應用程式在特定時刻所需的運算資源付費。

彈性:承受非預期狀況的能力

一個高可用性或高彈性的應用程式,不論在預期或非預期的情況下遇到系統元件故障,都能繼續運作如常。如果單個執行個體故障或整個區域出現問題,具彈性的應用程式依然會保有容錯能力,且能持續運作,並在必要時自行修復。由於狀態資訊未儲存在任何一個執行個體上,因此損失單個執行個體 (或即使是整個區域) 並不會影響應用程式的效能。

要設計一個真正具有彈性的應用程式,必須從軟體開發及應用程式架構的層級進行規劃。本文主要從應用程式架構的層級進行探討。

彈性應用程式的架構設計通常涉及下列幾個面向:

  • 利用負載平衡器監控伺服器,並將流量分配到最適合處理要求的伺服器
  • 將虛擬機器放到不同的地區中託管
  • 設定強大的儲存空間解決方案

GCP:靈活又具成本效益

傳統上能夠支援擴充性及彈性的架構,通常必須在資源方面挹注大量的投資。對內部部署解決方案而言,擴充性通常意味著您必須在兩種情形之間做抉擇:為了處理高峰用量而在伺服器容量上花大錢;或是購買僅足以應付平均需求的容量,但承擔流量暴增時應用程式效能不彰或使用者體驗欠佳的風險。然而,彈性講求的不只是伺服器容量而已,地點也同樣重要。為減緩暴風或地震等實際事件的影響,您必須考慮將作業伺服器架設在不同的實體位置,但這會使成本大增。

GCP 為您提供替代方案:一套可讓您以靈活方式增添架構擴充性和彈性的雲端服務組合。而且,GCP 是透過您可控制的定價結構來提供這些服務。

使用 GCP 打造具彈性且可擴充的架構

下表顯示建置高擴充性與高彈性應用程式的關鍵必要需求,以及這些需求與不同 GCP 服務之間的對應關係。

架構需求 GCP 服務
負載平衡 HTTP 負載平衡
伺服器託管 Compute Engine地區與區域
伺服器管理 執行個體範本代管執行個體群組自動配置器
資料儲存 Cloud SQLCloud Storage

下圖顯示這些 GCP 元件如何協同運作,共同建置一個兼具擴充性和彈性的應用程式。我們將在下節詳細說明各個元件所扮演的角色。

顯示可擴充且具彈性的應用程式的圖表。

元件總覽

範例應用程式架構中的每個元件在確保應用程式的擴充性及彈性方面都發揮了各自的作用。本節將概略介紹各個元件服務,並在後續章節中說明這些元件如何互相搭配運作。

HTTP 負載平衡器

HTTP 負載平衡器提供一個讓客戶用於存取應用程式的公開 IP 位址。此 IP 位址可與 DNS A 記錄 (如 example.com) 或 CNAME (如 www.example.com) 建立關聯。傳入的要求會根據每個群組的容量,分配至各區域的每個執行個體群組。在該區域中,要求會平均分配給群組中的執行個體。雖然 HTTP 負載平衡器能平衡不同地區之間的流量,但本範例解決方案僅在具有多個區域的單一地區使用這項元件。

區域

區域是某個地區內的獨立位置。同一地區中的各個區域會以高頻寬且低延遲的網路相互連線。Google 建議將應用程式部署在同個地區內的不同區域。

執行個體

執行個體是指 Google 基礎架構所託管的虛擬機器。您可以如同實體伺服器一般地安裝及設定這些執行個體。在範例部署中,您會使用開機指令碼和 Chef 來設定具有應用程式伺服器及應用程式程式碼的執行個體。

執行個體範本

執行個體範本定義了機器類型、映像檔、區域、標籤及其他執行個體屬性,您可以使用執行個體範本來建立代管執行個體群組

代管執行個體群組

代管執行個體群組是以執行個體範本為基礎的一組性質相同的執行個體。HTTP 負載平衡器會以代管執行個體群組為目標,將工作負載分配給群組中的執行個體。代管執行個體群組有對應的執行個體群組管理員資源,負責為群組新增及移除執行個體。

自動配置器

Compute Engine 自動配置器會透過群組管理員,將 Compute Engine 執行個體新增至代管執行個體群組或加以移除,以回應流量、CPU 使用率或其他信號。在範例解決方案中,自動配置器回應了 HTTP 負載平衡器的每秒要求數 (RPS) 指標。自動配置器是為代管執行個體群組自動調整資源配置的必要工具。

Cloud SQL

Cloud SQL 是一項支援 MySQL 和 PostgreSQL 的全代管資料庫服務。包括複製、加密、修補程式和備份等作業全都交由 Google 代管。Cloud SQL 執行個體會部署在單一區域,而其資料會自動複製到其他區域。此範例中使用的 Redmine 應用程式與 MySQL 相容,並且能與 Cloud SQL 完美搭配運作。

Cloud Storage

Cloud Storage 使物件 (通常是檔案) 能夠透過簡單且可擴充的介面進行儲存及擷取。此解決方案使用 Cloud Storage 值區,將私人 SSL 金鑰發布到可擴充的 Compute Engine 執行個體,並且用來儲存所有上傳至 Redmine 應用程式的檔案。也就是說,執行個體的磁碟中不會存放任何狀態資訊。

彈性

對於本範例架構而言,若要具備彈性,此架構就必須自動替換已經故障或變得無法使用的執行個體。當任何新執行個體上線時,此架構應能夠:

  • 瞭解其在系統中的角色。
  • 自動完成設定。
  • 探索其依附元件。
  • 自動開始處理要求。

如要自動替換故障的執行個體,您可以同時搭配多個 Compute Engine 元件:

開機指令碼會在執行個體啟動或重新啟動時執行。您可以使用這些指令碼來安裝軟體並更新,以確保服務在虛擬機器中運作,甚至可安裝設定管理工具,像是 Chef、Puppet、Ansible 或 Salt。

此解決方案使用開機指令碼安裝 Chef Solo,並且進而用來設定與應用程式搭配的執行個體。要瞭解如何使用開機指令碼和 Chef Solo 來自動設定執行個體,請參閱本主題結尾處的附錄:新增執行個體

除了開機指令碼之外,您還需要定義一些項目才能啟動 Compute Engine 執行個體。例如,您需要指定其機器類型、要使用的作業系統映像檔及要掛載的磁碟。您可以使用執行個體範本來定義這些選項。

執行個體範本和開機指令碼可一起用來定義要如何啟動 Compute Engine 執行個體,以及要如何在該執行個體上設定軟體,使其能夠在您的應用程式架構中發揮特定的作用。

顯示開機指令碼、執行個體範本和執行個體如何協同運作的圖表。

無庸置疑地,執行個體範本就只是範本而已。為讓這個範本發揮作用,您需要用一種方法將範本套用至新上線的 Compute Engine 執行個體。為此,您需要建立一個代管執行個體群組。您可以決定要在任何特定時間執行的執行個體數量,以及要將哪個執行個體範本套用至這些執行個體。接著,執行個體群組管理員會負責視需要啟動及設定這些執行個體。

下圖顯示這些元件如何協同運作:

  • 開機指令碼
  • 執行個體範本
  • 執行個體群組管理員
  • 代管執行個體群組
顯示開機指令碼、執行個體範本、執行個體群組管理員和代管執行個體群組如何協同運作的圖表。

代管執行個體群組及其對應的執行個體群組管理員可以是「特定區域」或「地區性」的資源。執行個體範本是專案層級的資源,可在任何區域及地區中的多個代管執行個體群組中重複使用;不過,您可以在執行個體範本中指定一些區域資源,藉此將範本的使用範圍限制在這些區域資源所在的區域。

透過使用開機指令碼、執行個體範本和代管執行個體群組,您目前所建構的系統可將健康狀態不良的執行個體替換為新的執行個體。在下一節中,您將看到一種可用來定義及偵測健康狀態不良的執行個體的方法。

健康狀態檢查

此時,範例應用程式差不多已具備打造彈性所需的一切工具。但還缺少了某個要素,那就是可用來識別運作狀態不良的執行個體的方法,如此一來才能知道哪些執行個體應該進行替換。

這個應用程式的設計旨在透過 HTTP 負載平衡器,將使用者連線到運作良好的適當執行個體。此架構可讓您使用兩種服務來識別能夠為要求提供服務的執行個體:

  • 健康狀態檢查。HTTP 健康狀態檢查可指定要在每個執行個體上執行健康狀態檢查的通訊埠和路徑。健康狀態檢查預期收到的回應是 200 OK (代表執行個體的狀態是運作良好)。
  • 後端服務。後端服務可定義會從負載平衡器接收流量的一或多個執行個體群組。後端服務指定由執行個體公開的通訊埠和通訊協定,例如 HTTP 通訊埠 80,以及要對執行個體群組中的執行個體使用的 HTTP 健康狀態檢查。

下圖顯示這種應用程式架構,以及後端服務和 HTTP 健康狀態檢查與負載平衡器和執行個體群組之間的關係。

顯示健康狀態檢查和後端服務的圖表。

利用 Cloud SQL 實現資料彈性

網路、運算及儲存是應用程式架構的三大核心要素。這裡描述的應用程式架構已涵蓋網路及運算這兩大要素,但還缺少一個要素,那就是儲存。

此範例解決方案使用 Cloud SQL 第一代執行個體來提供全代管的 MySQL 資料庫。在 Cloud SQL 的輔助下,Google 可自動進行複製、加密、修補程式管理及備份等作業。

Cloud SQL 資料庫是一種地區級的資料庫,其資料會被複製到地區內的所有區域。這等同於當資料有任何更新時,就會立刻為其備份。因此,即使發生罕見的區域大當機狀況,資料仍會保存下來。

Cloud SQL 有兩種複製模式供您選擇:

  • 同步複製。選用同步複製模式時,更新會先複製到多個區域,然後再傳回用戶端。在發生重大事件時,這可以確保資料的可靠性及可用性,只是寫入速度會比較慢。
  • 非同步複製。選用非同步複製模式時,為了提高寫入總處理量,在資料快取到本機後就會確認寫入作業,然後再將資料複製到其他位置。由於非同步複製不需要等到複製作業完成後才確認寫入,因此可提高資料寫入資料庫的速度。但是,如果在資料庫更新後的幾秒鐘內,資料中心突然發生罕見的系統故障事件,您就可能會失去最新的更新資料。

這項解決方案中的 Redmine 應用程式採取同步複製模式,因為工作負載的寫入作業不是很密集。您可依據應用程式的寫入效能及資料耐用性需求,來選擇使用同步複製模式或非同步複製模式。

擴充性

上文說明範例應用程式如何使用 GCP 建立具彈性的應用程式。但光有彈性還不夠,擴充性也同樣重要。不論使用者數是 1 還是 1,000,000,應用程式都應穩定有效地運作,並隨著使用者數量的多寡而增減資源,以達到成本效益。

如要增減應用程式的資源,則必須具備以下工具:

  • 一個可讓您為服務增加或移除執行個體的工具。您還需要一個用來決定何時需要增加及何時應該移除執行個體的方法。GCP 的自動配置器就是用來解決這項問題的工具。
  • 一個儲存狀態資料的工具。由於執行個體會來來去去,因此不建議將狀態資料儲存在這些執行個體上。應用程式架構透過將關聯性資料儲存在單獨的 Cloud SQL 執行個體來解決此問題,只是這還需要容納使用者上傳的檔案。而 Cloud Storage 可滿足此要求。

以下各節介紹如何使用自動配置器來擴充執行 Redmine 應用程式的基礎架構,以及如何利用 Cloud Storage 來處理上傳的檔案。

使用自動配置器調度資源

由於應用程式的使用量時有消長,因此應用程式會需要針對所需資源進行動態調整。您可以使用 Compute Engine 自動配置器來因應這項挑戰。

當流量或負載升高時,自動配置器會增加資源來處理額外的活動,並且會在流量或負載降低時,將資源移除以節省成本。自動配置器會根據您定義的資源調度規則來自動執行這些動作,完全無需後續的人為介入。

自動配置器可帶來雙重效益:

  1. 使用者可獲得更優異的應用程式使用體驗,因為隨時都有足夠的資源可以應付需求。
  2. 您可以更有效地控管成本,因為自動配置器會在需求降到特定門檻以下時移除執行個體。

自動配置器可依據 CPU 使用率、服務規模或 Stackdriver Monitoring 指標來調整虛擬機器的數量。此解決方案使用服務規模指標,根據執行個體從負載平衡器收到的每秒要求數 (RPS) 來新增或移除 Compute Engine 執行個體。詳情請參閱使用 Compute Engine 自動配置器進行批次處理的說明。

每秒要求數 (RPS)

前述各節所介紹的單一後端服務,可用來辨識應自負載平衡器接收流量的執行個體群組。此範例解決方案還針對與後端服務關聯的每個執行個體群組,做了 balancingMode=RATE 的設定。這個屬性會指示負載平衡器根據在 maxRatePerInstance 屬性中所定義的 RPS (本例設為 100) 來調度資源。此設定意味著負載平衡器會嘗試將每個執行個體保持在 100 RPS 或低於100 RPS。如要進一步瞭解有關後端服務的設定屬性,
請參閱後端服務的說明文件

如要調整 RPS 的數值,您需要替每個自動調度資源的執行個體群組都建立一個自動配置器。在此範例中,執行個體群組被規劃為區域級的資源,因此您必須在每個區域中都建立一個自動配置器。

顯示自動配置器如何融入應用程式架構的圖表。

每個自動配置器都包含 utilizationTarget 屬性;該屬性定義了自動配置器要將負載平衡器的最大服務規模維持在多少百分比。此範例將每個自動配置器的 utilizationTarget 設為 80%,即後端服務的每個執行個體最高速率 100 RPS 的八成。這表示自動配置器會在 RPS 超過每個執行個體最高速率的 80% (即 80 RPS) 時進行擴增,並於 RPS 降至該門檻值以下時進行縮減。

顯示自動配置器如何確定是否新增或移除執行個體的流程圖。

此外,每個自動配置器也會定義各自不可逾越的執行個體數量上下限。

請注意,只有代管執行個體群組能提供這種自動調度資源功能。詳情請參閱執行個體群組自動調度執行個體群組資源等文。

處理檔案上傳

Redmine 應用程式的其中一項功能是可讓使用者在登入後進行檔案上傳及儲存。Redmine 和許多其他類似的應用程式預設都會將這些檔案直接儲存在本機磁碟上。如果您只有一部備份機制完善的伺服器,這確實是不錯的方法。但是,當負載平衡器背後有多個可自動擴充的 Compute Engine 執行個體時,這就不是理想的做法。因為在使用者上傳檔案後,系統並無法保證下一個要求也會送到儲存檔案的機器上。而且此做法也無法保證自動配置器不會終止已不需要但仍存有檔案的執行個體。

較佳的做法是使用 Cloud Storage,因為這項服務提供了一個集中的位置,非常適合用於儲存及存取從眾多自動擴充網路伺服器上傳的檔案。Cloud Storage 還提供一個可與 Amazon S3 用戶端互通的 API,因此無需進行任何修改即可與現有的 Amazon S3 應用程式外掛程式相容,包括 Redmine S3 外掛程式。許多第三方和開放原始碼應用程式都有外掛程式可支援類似 Cloud Storage 的物件儲存空間。若是想要建置自己的應用程式,您可以直接使用 Cloud Storage API 來支援儲存檔案。

下圖顯示了使用 Redmine 和 Cloud Storage 上傳 (藍色箭頭) 及擷取 (綠色箭頭) 檔案的流程圖:

顯示要求如何在 Redmine 應用程式中傳遞的流程圖。

圖中顯示的程序如下:

  1. 使用者從網路瀏覽器「張貼」檔案。
  2. 負載平衡器選擇用於處理要求的執行個體。
  3. 執行個體將檔案儲存於 Cloud Storage。
  4. 執行個體將檔案的中繼資料 (如名稱、擁有者及其在 Cloud Storage 中的位置) 儲存於 Cloud SQL 資料庫。
  5. 當使用者要求檔案時,檔案會從 Cloud Storage 串流至執行個體。
  6. 執行個體透過負載平衡器傳遞串流。
  7. 檔案送達使用者。

儲存空間容量

除了能從 Compute Engine 執行個體移除狀態檔案上傳並使其動態調度資源之外,Cloud Storage 還提供一個可長期儲存無限量上傳檔案的備援空間。這可說是一項兼具彈性、擴充性與成本效益的儲存解決方案。您只需針對使用的儲存空間付費而不必費心規劃容量,而且資料會自動分散儲存於多個區域,以達到備援的目的。

費用

到目前為止,我們已利用本文的應用程式架構,介紹了如何使用 GCP 建置兼具彈性與擴充性的應用程式。但光是懂得如何建構應用程式還不夠,您還需要能以最具成本效益的方法來完成這項工作。

本節將為您說明此應用程式架構除了兼具彈性與擴充性的優點之外,成本效益也非常高。首先,我們要對應用程式的負載程度及使用頻率做出一些基本假設,然後再將這些假設換算為基本的預估費用。請記住,這些純粹只是假設而已。您可以依需要自由調整這些數據,以建立更符合您自己的應用程式用途的費用預估。

計算

在考量應用程式架構時,保持伺服器運作順暢需要花多少費用是基本的思考重點。此處的費用分析使用以下假設:

指標
每月平均網頁瀏覽量 20,000,000
每月平均 HTTP 要求數量 120,000,000
用量高峰時段 (90% 或以上) 週一至週五上午 7 點至下午 6 點
每個網頁瀏覽的資料傳輸量 100KB
每月高峰時數 220
高峰時段的要求頻率 每秒 127 個要求 (RPS)
離峰時段的要求頻率 每秒 6 個要求 (RPS)

根據這些假設,您將可算出每個月應用程式在高峰時段 (週一至週五上午 7 點至下午 6 點) 所收到的網頁瀏覽量:

20,000,000 (瀏覽量/月) * 6 (要求數/瀏覽) * 90% (發生於高峰時段) = 108,000,000

每個月平均有 22 個工作日。如果每個工作日有 11 個高峰小時,那麼您需要提供足以應付每月 242 個高峰小時的運算資源。

接下來,您需要確定哪種類型的 Compute Engine 執行個體能夠處理此類流量。此應用程式架構使用 gatling.io 進行基本負載測試,而測試結果顯示 4 個 n1-standard-1 類型的 Compute Engine 執行個體就足夠應付流量。

在非高峰時段,此解決方案會至少保持兩個 n1-standard-1 執行個體運作。

如要瞭解運作這些執行個體需要多少費用,請使用 GCP Pricing Calculator 查詢最新的估算價格。在實際查詢後,您會發現兩種案例的執行個體都自動符合續用折扣資格。

負載平衡與資料傳輸

此應用程式佈建了一個設有單一轉送規則的負載平衡器;該規則是提供給使用者連線的公開 IP 位址,並且按照小時計費。

在進行資料傳輸預估時,請先考慮最壞的情況。負載平衡器會按照處理的輸入資料量收費,從負載平衡器傳出的流量則按照一般輸出費率計費。假設 120,000,000 個 HTTP 要求中,有 99.5% 都是使用者載入 Redmine 專案頁面的要求。載入頁面算 1 個 HTTP GET 要求,而它又會連帶產生 5 個載入其他資產 (CSS、映像檔和 jQuery) 的 HTTP GET 要求。因此,載入整個頁面總共需要 6 個 HTTP 要求。這可得出以下的結果:

  • 每月約載入 20,000,000 個完整頁面
  • 每頁約需處理 10 KB 的輸入資料及產生 450 KB 的資料傳輸量
  • 負載平衡器每月約需處理總共 214 GB 的資料量,並產生 9,091 GB 的輸出流量

20,000,000 個 HTTP 要求中的另外 0.5% 是 HTTP POST 要求,用於上傳平均大小約為 0.5 MB 的檔案,每個月處理 500 GB 的額外資料量。

根據 GCP Pricing Calculator 的估算,此案例應支付的費用包括負載平衡器的 714 GB 資料傳輸處理費,加上 9,091 GB 的輸出流量計費。

資料傳輸量是按照最壞的情況估算,因為它算入了應要求由 Compute Engine 執行個體透過負載平衡器提供的所有內容 (包括靜態資產) 的費用,並未計入快取技術或內容傳遞聯播網 (CDN) 可節省的流量。在每個頁面載入所產生的大約 450 KB 酬載中 (試想此解決方案每月的頁面載入量超過 20 M),有 333 KB 必須載入 jQuery。只要更新一行應用程式,從 Google 託管程式庫載入 jQuery,您就能節省 73% 的資料傳輸費用。

使用新方法估價後,您就可以知道轉換到 Google 託管程式庫能幫您節省多少資料傳輸費用。

儲存

此解決方案使用 Cloud Storage 儲存所有透過 Redmine 應用程式上傳的檔案。如上一節所述,約有 0.5% 的資料傳輸量是上傳檔案所產生的,且檔案的平均大小為 0.5 MB。這表示您每個月預期可看見 1,000,000 個新上傳的檔案,也等於您每個月需要 500 GB 的新儲存空間。此解決方案還假設每月需要用 1,000,000 個 HTTP PUT 作業來儲存新檔案,這些將按照 A 級作業費率收費。

使用 GCP Pricing Calculator 進行價格估算,將可得出 Cloud Storage 的預估使用成本。

此處的架構使用 Cloud SQL 來儲存應用程式的所有關聯性資料。根據前文提及的範例指標,容量為 1024 MB RAM 的 D2 資料庫應該就具有足夠的容量可應付應用程式的工作負載,並讓應用程式維持每週 7 天、每天 24 小時的運作。由於此資料庫的使用率應該相當頻繁,因此請在計算器中為 I/O 作業勾選 [Heavy] 選項。我們對範例架構進行了插入 100,000 份文件的測試,結果顯示 50 GB 的磁碟可支援儲存超過 100,000,000 份文件,也就是說資料庫可透過上述費率使用長達 8 年以上。

使用 GCP Pricing Calculator 估算可得出此部分架構的預估費用。

部署範例解決方案

如要部署此解決方案中描述的範例應用程式,請前往 GitHub 存放區,查看在 GCP 上建構可擴充且具彈性的應用程式相關說明。

附錄:新增執行個體

為了打造有彈性且可擴充的應用程式架構,您需要考量許多因素,其中包括決定如何新增執行個體。具體而言,您需要決定如何自動設定新上線的執行個體。

本節將為您介紹一些可用的選項。

安裝開機載入軟體

為了服務使用者的網路要求,除了基本的作業系統之外,每個執行個體還需要安裝一些額外的軟體,並且載入設定資料。設定資料包括了資料庫連線資訊,以及儲存檔案的 Cloud Storage 值區名稱等。如果將這些元件想像成一層層的結構,就能把每個執行個體上的整個堆疊組合轉化為如下的視覺圖像:

顯示軟體如何在執行個體上堆疊的圖表。

此解決方案使用執行個體範本;該範本指定了執行個體在啟動時使用的 Compute Engine 映像檔。具體來說,此解決方案使用的是由 Canonical 開發及支援的 Ubuntu 14.10 映像檔。由於這是基本作業系統映像檔,所以並未包含任何應用程式所需的特定軟體或設定。

若要在新執行個體上線時自動安裝堆疊的其餘部分,您可以使用 Compute Engine 開機指令碼搭配 Chef Solo 來執行開機載入作業。您可透過將 startup-script 中繼資料屬性項目新增至執行個體範本的方式,來指定開機指令碼。開機指令碼會在執行個體開機時執行。

此開機指令碼將會:

  1. 安裝 Chef 用戶端。
  2. 下載一個名為 node.json 的特殊 Chef 檔案。此檔案可告知 Chef 要為此執行個體執行何種設定。
  3. 執行 Chef 並任其處理詳細的設定作業。

以下為完整的開機指令碼:

#! /bin/bash

# Install Chef
curl -L https://www.opscode.com/chef/install.sh | bash

# Download node.json (runlist)
curl -L https://github.com/googlecloudplatform/... > /tmp/node.json

# Run Chef
chef-solo -j /tmp/node.json -r https://github.com/googlecloudplatform/...

提供應用程式設定

在新執行個體使用開機指令碼和 Chef 啟動並自行完成設定後,都需要先知道一些資訊才能開始為要求提供服務。在此範例中,每個執行個體都需要知道資料庫連線資訊 (如主機名稱、使用者名稱和密碼)、要使用的 Cloud Storage 值區名稱,以及連線用的憑證。

每個 Compute Engine 執行個體都有關聯的中繼資料屬性,而您可以定義這些屬性。您已從之前的內容中瞭解到如何新增 startup-script 這個特殊的中繼資料屬性,而您還可以新增任意的鍵/值組合。您可以在此指定執行個體範本中的屬性,以包含執行個體連線至資料庫及 Cloud Storage 值區所需的設定資料。

以下是 GCP 主控台的執行個體範本中繼資料:

Google Cloud Platform 主控台的螢幕擷圖,顯示執行個體範本的自訂中繼資料資訊。

Chef 使用一個叫 Ohai 的工具來剖析來自執行個體中繼資料的設定資訊,並將其填入範本,以建立應用程式所需的設定檔案。以下的範本可建立一個含有資料庫連線資訊的 database.yaml 檔案,並用該檔案來自動存取適當的中繼資料項目:

production:
    adapter: mysql2
    database: <%= node['gce']['instance']['attributes']['dbname'] %>
    host:     <%= node['gce']['instance']['attributes']['dbhost'] %>
    username: <%= node['gce']['instance']['attributes']['dbuser'] %>
    password: <%= node['gce']['instance']['attributes']['dbpassword'] %>

您也可以使用本機中繼資料服務,從執行個體內部手動存取中繼資料值。在此,您可使用 curl 來擷取資料庫密碼:

curl "http:/metadata.google.internal/computeMetadata/v1/instance/attributes/dbpassword" -H "Metadata-Flavor: Google"

效能與相依性考量

此解決方案採用的開機載入方法需用預設的作業系統映像檔啟動,需在啟動時使用 Chef 安裝所有軟體,並且需要使用執行個體中繼資料來提供應用程式設定資料。

顯示軟體如何在執行個體上堆疊的圖表。此堆疊顯示一些軟體如何與映像檔搭配組合,有些在啟動時安裝,有些則是在啟動後提供。

此方法的優點是系統的設定是在 Chef 教戰手冊中指定。教戰手冊較有利於版本的控管及共用,並可用於佈建測試用的本機虛擬機器 (使用 Vagrant 或 Docker),或是用於設定您資料中心或不同雲端服務供應商的伺服器。映像檔管理工作也會變得更加簡單:以此範例應用程式的情況來說,您只需要追蹤應用程式所使用的基本作業系統映像檔。

需列入考量的一些缺點包括:啟動時間可能較慢,這是因為需要下載及安裝所有軟體,有時甚至需要進行程式碼編譯。此外,您還應考慮此方法帶來的相依性問題:在此範例中,Chef 會從 apt、Rubygems 和 GitHub 安裝一些套件。如果其中有任何存放區在啟動新執行個體時無法使用,將會導致設定失敗。

自訂映像檔和開機載入

由於您可以使用 Compute Engine 建立自訂映像檔,因此在啟動時安裝所有軟體並不是唯一的開機載入方法。比如說,您可以:

  1. 啟動基本 Ubuntu 14.10 映像檔。
  2. 安裝 Redmine 應用程式「以外」的所有軟體 (Ruby、nginx 等等)。
  3. 從結果建立映像檔。
  4. 在執行個體範本中使用該映像檔。

現在,當新的執行個體啟動時,只需安裝 Redmine 即可。如此一來,不僅啟動時間將會縮短,外部相依套件數量也會減少。

顯示執行個體堆疊的圖表,其中安裝 Redmine 除外的所有軟體。

您還可進一步利用自訂映像檔的方法,將所有內容都製備到映像檔中,包括所有依附項目、應用程式原始碼和設定。此做法的優點是啟動時間最快,外部相依性為零,但如果應用程式有任何一點變更時,您就必須建立新的映像檔並更新執行個體範本。

顯示執行個體堆疊的圖表,其中所有軟體皆與映像檔搭配組合。

請考慮用連續模式的方法來進行執行個體的開機載入作業。啟動時的設定作業越多,啟動速度就越慢,但要管理的映像檔也越少。在自訂映像檔中製備越多設定,啟動速度就越快且相依性就越低,但要管理的映像檔卻可能越多。對大多數客戶而言,採取折衷的做法才是明智之舉。換句話說,您應該選擇對自己和應用程式而言最合理的做法。

顯示如何在執行個體上以連續模式安裝軟體的圖表。範圍從在啟動後安裝所有內容,到將所有內容與映像檔搭配組合。

相關資源

  • 如要概略瞭解 GCP 提供的網路託管服務選項,請參閱提供網站內容一文。
  • 歡迎試用其他 Google Cloud Platform 功能,請參考我們的教學課程
本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
解決方案