在 Google Cloud 上部署.NET 應用程式

Last reviewed 2022-01-19 UTC

本頁面提供如何在Google Cloud 上部署 .NET 應用程式的總覽,並且指引您如何為應用程式選擇正確的部署方式。

簡介

Microsoft .NET Framework 為應用程式開發作業提供一套豐富的工具和資料庫。隨著 Docker 開始支援 Windows,並且能夠在 Linux 上執行 .NET 應用程式,.NET 應用程式現在也能支援各種部署目標。

為了提高開發與測試的效率,您可以使用自動化應用程式部署作業,並讓這項作業成為持續整合/持續推送軟體更新 (CI/CD) 管道的一部分。但是,為了選擇正確的工具及建構持續整合/持續推送軟體更新管道,您必須先決定如何在實際工作環境中執行應用程式,以及要採用的部署方式。

在 Google Cloud上部署 .NET 應用程式不只一種最佳方法。最佳部署選項需取決於您的應用程式和需求。舉例來說,如果您的應用程式需要完整的 .NET Framework,或者必須在 IIS 上執行,則您的部署作業會以 Windows 為基礎。但如果您的應用程式可利用 .NET 支援的功能執行,則您可以選擇在 Linux 的環境下進行部署。

本頁面介紹在 Google Cloud上執行及部署 .NET 應用程式的各種方法,包括各選項適用的條件。最後,本文會在決策樹狀圖中摘要列出部署選項,協助您決定哪些 Google Cloud 元件和方式最適合您的 .NET 應用程式。

部署模型

有兩個基本方法可以自動執行應用程式的部署作業。您可以選擇將部署套件「推送」至應用程式伺服器,或由應用程式伺服器從已知位置「提取」應用程式套件。下列各節將討論這兩種模型之間的差異。

推送式部署

在「推送式部署」中,部署成果 (ZIP 檔案、NuGet 套件或其他成果) 初期只適用於部署伺服器。部署伺服器可以是專屬機器或持續整合系統假設的角色。

如要執行部署,部署伺服器上的程序會連線至應用程式伺服器、複製部署成果並啟動安裝作業。如有多個應用程式伺服器,這項程序會以平行方式重複執行,或是採用更常見的做法,按照順序重複執行,以將成果部署至所有應用程式伺服器。

下圖說明了這個流程。

推送式部署

有各種設定管理工具能讓您以這個方式自動部署。其中有些工具遵循命令式方法,部署步驟的順序會以類似指令碼的方式定義。 雖然這個做法很直覺化,但很容易出現「設定偏移」的情形,也就是說,在經過一段時間後,多台機器的狀態可能會不一致,且可能無法完全反映您預期的狀態。因此,有許多工具可讓您定義所需狀態,由工具決定達到此狀態的所需步驟。

在 Windows 上,此部署模型的常用工具包括:

熱門的開放原始碼工具包括 AnsibleChef InfraPuppet。雖然這些工具主要用於 Linux,但也能用於部署 Windows 目標。

安全性

如要使用部署伺服器將部署作業推送至應用程式伺服器,則必須使用反向通道。舉例來說,Web Deploy 和 Octopus Deploy 使用自訂通訊協定和通訊埠執行這項工作,Ansible 則是使用 SSH。

無論工具使用哪一種通訊協定,請務必確保通訊安全,以防止攻擊者利用反向通道來部署惡意應用程式。更重要的是,部署伺服器必須能透過應用程式伺服器進行驗證以保護通訊安全。

SSH 可以使用公開金鑰驗證。如果您使用適當的 IAM 設定,則可以讓 Google Cloud 自動將 SSH 使用的公開金鑰發布至應用程式伺服器。不過,如果您未使用 IAM, Google Cloud 就無法為您管理金鑰,您必須自行管理這項工作。

其中一個選項是 Active Directory。如果部署伺服器和應用程式伺服器均執行 Windows,並且都是 Active Directory 網域的成員時,系統會使用 Kerberos 進行驗證。不過,執行容錯 Active Directory 環境時,至少需要兩個額外的 VM 執行個體才能執行網域控制器。如果您的設定使用自動調度資源,則所有伺服器也必須動態加入網域,這會降低伺服器啟動程序的速度。此外,自動調度資源還可能會讓過時的電腦物件累積在目錄中,因此需要使用額外的清理邏輯。如果您要在雲端式環境中使用 Active Directory,請務必考量這些額外要素。

在不使用 Active Directory 的情況下,您必須使用 NTLM 或 HTTP 基本驗證等其他方式進行驗證。這兩種方式的憑證必須在部署伺服器和應用程式伺服器之間保持同步並安全儲存,但這兩項工作都具有挑戰性。

無論您使用 Linux 或 Windows,保護部署作業與應用程式伺服器之間的通訊安全,都需要與 IAM 不同的機制。不過,使用多種機制控管系統存取權會增加整體複雜度,進而提高意外設定錯誤的風險。

作業系統更新

能夠在應用程式伺服器上有效部署應用程式套件的新版本非常重要,但能在這些伺服器上提供基礎作業系統也同樣至關緊要。這代表您必須安裝安全性修補程式。如果是較大型的伺服器組,您應該自動執行這項程序,以盡可能降低風險及大幅減少更新時無法使用的伺服器數量。

您也可以使用推送方式執行作業系統更新,其中部署伺服器會觸發應用程式伺服器上的 OS 更新。在 Linux 上,通常會使用 SSH 遠端執行這項作業的更新指令。在 Windows 上,PowerShell 遠端連線 (通常仰賴 WinRM) 是最常用的選項。對於這兩種機制,您必須能夠安全地進行驗證及儲存憑證。

自動調度資源

在應用程式伺服器數量不變的靜態環境中,部署伺服器會預先知道所有部署目標。在雲端環境中,可自動調整應用程式伺服器的數量是較好的做法。如果您使用的是推送式部署,這會帶來兩個挑戰:

  • 加入新的應用程式伺服器時,請將其註冊至部署伺服器,以確保新的伺服器會包含在日後的部署作業中。
  • 新伺服器必須接收其初始部署項目。

自動調度資源事件不會由部署伺服器啟動,而是由運作層級低於部署伺服器的基礎代管執行個體群組啟動。

新的應用程式伺服器執行個體本身必須註冊至部署伺服器,並在新的應用程式伺服器可傳送要求之前先觸發部署作業。下圖說明了這個程序。

使用推送式部署進行自動調度資源

為使這個方法發揮作用,只讓部署伺服器可以與應用程式伺服器連線並進行驗證是不夠的。應用程式伺服器也需要與部署伺服器連線並進行驗證。

最後,新啟動的伺服器也必須擁有最新的 OS 安全性修補程式。在自動調度資源程序的執行期間啟動更新作業,會導致該程序的執行速度大幅延遲。因此,您必須先為已建立的應用程式伺服器 VM 安裝映像檔更新。您可以透過下列兩種方式進行管理:

  • 使用 Google Cloud提供的公開映像檔,這些映像檔會由 Google 持續更新。由於這些映像檔只包含 OS,您必須使用開機指令碼或在應用程式部署過程中處理任何自訂項目 (應用程式的程式碼、公用程式和 OS 設定)。
  • 維護自訂的 OS 映像檔並持續更新。這可讓您將自訂項目套用到映像檔,但會提高管理部署作業的整體複雜度。

雖然執行推送式部署屬於直覺式操作,但在考量到安全性、OS 更新和自動調度資源時,可能會變得相當複雜。下一節會說明提取式部署,這是更偏向雲端原生的部署方式。

提取式部署

在提取式部署中,部署作業採用間接的執行方式。 持續整合系統在產生新的部署成果版本之後,便會將成果發布至存放區。下圖說明了這個流程。

提取式部署

執行部署時 (可能是在發佈成果之後,或是在稍後的階段),部署伺服器會觸發實際部署作業。同樣地,部署伺服器可以是單獨的系統或持續整合系統假設的角色。觸發部署會連線至應用程式伺服器,使其透過中央存放區提取並安裝部署成果。

雖然推送式模型和提取式模型在初期的時候可能差異不大,但執行提取式部署有一些重要注意事項:

  • 不必在應用程式或 OS 層級上觸發應用程式伺服器以提取部署成果。相反地,部署伺服器可藉由讓 Compute Engine 重新啟動或取代 VM 的方式觸發提取作業。這樣做可以避免與推送式部署相關的安全性挑戰。
  • 除了只能包含應用程式檔案以外,部署成果也可以是 Docker 映像檔或 VM 映像檔,可統一套用應用程式和 OS 更新的程序。

安全性

在某些類型的部署作業中,部署伺服器完全不需要與應用程式伺服器互動。舉例來說,假如部署成果屬於下列任何一種,則不需要進行任何互動:

  • VM 映像檔。
  • 要部署至 Google Kubernetes Engine 的 Docker 映像檔。
  • 要部署至 App Engine 的套件。

此外,部署伺服器只需要與Google Cloud API 互動即可啟動部署。換言之,這代表部署程序可依賴 IAM 提供的驗證機制,無須管理金鑰或憑證。

如果您使用的部署成果只包含應用程式檔案和二進位檔 (例如 ZIP 或 NuGet 套件),則可使用下列方式觸發部署作業:

  • 如果伺服器設定為在作業系統啟動時,提取並安裝最新的部署構件,您可以 Google Cloud 重新啟動 VM 來觸發更新。雖然重新啟動可能看似浪費時間,但這樣一來,部署伺服器就不必向應用程式伺服器進行驗證。
  • 與推送式部署相同,部署伺服器可透過反向通道遠端觸發更新。但這個做法會與推送式部署面臨同樣的憑證管理安全疑慮和挑戰。
  • 部署伺服器可執行代理程式以觀察存放區中是否有新的部署成果。偵測到新成果時,伺服器可以自動套用。不過,這個做法可能會出現多個應用程式伺服器同時安裝更新,進而導致無法使用的問題。為避免這種情況,代理程式可以追蹤存放區中的伺服器狀態,並根據這個伺服器狀態資訊以可控制的方式提供更新。

在每個情況下,請確保您妥善控管存放區的寫入權限,以防止伺服器提取及安裝惡意套件。

作業系統更新

使用 Docker 或 VM 映像檔做為部署成果時,這些成果會結合應用程式檔案和相依項目。這可讓您使用相同的部署機制來更新作業系統和應用程式。在這種情況下,您必須確保可以為下列兩個不同情況建構及發布新的部署成果:第一個是在推出新的應用程式版本時,第二個是在為作業系統或其他相依項目發布新的安全性更新時。

在其他情況下,當部署成果只包含應用程式檔案時,讓作業系統保持在最新狀態是一項獨立工作。因此,適用於在推送式部署一節中說明的內容。

自動調度資源

由應用程式伺服器提取部署成果的概念與自動調度資源相符,且大幅降低了結合自動調度資源和推送式部署所導致的複雜程度。每當新的應用程式伺服器因自動調度資源事件而啟動時,伺服器都會連線至存放區,並提取及安裝最新的部署套件。

如果您使用的是 VM 或 Docker 映像檔,則 Google Cloud會提供提取映像檔的機制。如果您使用的是其他套件 (例如 ZIP 或 NuGet 封存檔),則必須設定應用程式伺服器才能在啟動後開始進行部署作業。您可以自訂 VM 映像檔或使用開機指令碼進行這項操作。

部署目標

過去 .NET 應用程式只能在 Windows 上執行,而且 Windows 並不支援容器。這限制了您可以執行應用程式的環境選項。

隨著 .NET 的問世,您可以決定要在 Windows 或 Linux 上執行應用程式。由於兩個作業系統都支援容器,現在您擁有更多環境選項可供指定。

作業系統

雖然 Mono 多年前便提供了在非 Windows 平台上部署 .NET 應用程式的方式,但直到 .NET 發布之後,Linux 平台才真正獲得 Microsoft 開發堆疊的完整支援。

.NET 只提供一部分的 .NET Framework 功能,因此,指定 .NET 會對應用程式施加多項限制。更重要的是,將現有應用程式從 .NET Framework 移植到 .NET 可能有難度且不符合成本效益;在某些情況下,可能根本無法移植。

因此,選擇部署模型和目標的基本問題在於,您是要選擇使用 Linux (需使用 .NET),或是使用 Windows (支援 .NET 或 .NET Framework)。

在 Linux 上執行 .NET 應用程式的潛在優點包括:

  • 可使用全代管環境的 App Engine 彈性環境
  • 可使用支援容器自動化調度管理的代管環境 GKE
  • 不需要為與 Windows 授權相關的 付費 Compute Engine 映像檔支付額外費用。

您必須衡量上述優點與下列在 Linux 上使用 .NET 的潛在缺點:

  • 將現有 .NET Framework 應用程式移植到 .NET 的所需作業可能會抵消節省的費用。或是如上所述,可能無法將現有的 .NET Framework 應用程式移植到 .NET。
  • Linux 不支援 IIS。 雖然 .NET 網路伺服器 Kestrel 具備良好效能,但其提供的功能組與 IIS 不同。因此您可能必須將 Kestrel 搭配 Nginx 這類網路伺服器一起使用。
  • 目前在 Linux 上沒有與 Windows 服務直接對應的項目。雖然您通常可以將 Windows 服務轉換為可做為 Daemon 執行的 Linux 主控台應用程式,但這項轉換作業並不容易。
  • 在 Linux 上對 .NET 應用程式進行疑難排解和偵錯時,所需的工具和技能和在 Windows 上使用 .NET 不同。如果您的團隊對於 Linux 的經驗有限,這可能會頗具挑戰性。

容器

容器非常適合在單一程序中執行的應用程式。其應用範例如下:

  • Windows 服務
  • 做為 Daemon 使用的 Linux 主控台應用程式
  • 自行託管式 WCF 服務
  • Kestrel 託管的 ASP.NET MVC 或 Web API 應用程式

許多 .NET 應用程式都會指定 IIS。這通常用於管理多個應用程式 (在單獨的虛擬目錄和應用程式集區中),因此可能與單一程序的模式不相符。

如要將以 IIS 為基礎的設定移至容器,您可採取下列做法:

  • 使用與基本映像檔相同的 microsoft/iis 映像檔,將 IIS 連同所有虛擬目錄和集區放入單一 Windows Docker 映像檔中。除非應用程式的結構很緊密,否則通常不建議您採取這個做法,因為這樣會無法單獨更新和部署應用程式。
  • 為每個執行 IIS 的應用程式使用獨立的 Windows Docker 映像檔。確保您可以獨立管理應用程式。但是,如果您需要大量操作這些容器,IIS 可能會產生不可忽略的費用負擔,進而造成重大影響。
  • 將部分或所有應用程式從 IIS 移轉到 Kestrel。 由於 Kestrel 可以部署在 Windows 容器或 Linux 的 Docker 容器中,這個做法可讓您單獨管理容器。

IIS 允許多個網路應用程式在單一網站下執行,共用一個網域名稱。將應用程式封裝至獨立的容器時,您可以使用以內容為基礎的負載平衡取得相同的功能。 同樣地,使用 Google HTTP 負載平衡器也不需要在 Kestrel 伺服器前端部署自訂的反向 Proxy。

多數應用程式都可以容器化;無法容器化的應用程式非常少見。但有些容器化情境具有挑戰性:

  • 以 IIS 代管的應用程式來說,應用程式部署作業通常已經自動化。但是,您必須手動執行 IIS 的設定步驟 (建立應用程式集區、繫結等)。移至容器時,您也必須自動化執行所有的初始步驟。
  • 如果應用程式依賴設定檔或磁碟上的資料,則可能需要變更。舉例來說,您可以變更為從環境變數取得設定資訊,並將相關檔案和資料夾掛接為磁碟區。這可讓映像檔保持為無狀態,且不受特定環境的設定限制。

最後,如果您使用的是 Windows 的 Docker 容器,請注意Google Cloud 不支援 Hyper-V,而且也不允許您執行 Hyper-V 容器。因此,您只能在Google Cloud中部署 Windows Server 容器。相較於 Hyper-V 容器,Windows Server 容器更為輕量,且提供的隔離層級不同。

部署限制

在建構應用程式的過程中,某些因素會對您採用的部署方式施加限制,詳細內容如本節所述。

應用程式架構

選擇部署目標和模型時,您要考量的主要因素是應用程式的架構。首先是應用程式可能遵循單體式架構模式,其中所有應用程式邏輯均在單一程式碼基底中實作,並在單一程序或 IIS 應用程式集區中執行。另一方面,應用程式可能遵循微服務模式。在此方法中,應用程式包含許多服務;這些服務在獨立的程序或獨立的 IIS 應用程式集區中執行,或做為獨立的 Windows 服務執行。

最後,您可能會有多個採用統一部署策略進行部署的獨立應用程式,而每個應用程式本身都是單體式應用程式。為符合本文的目的,這個方法可視為等同於微服務情境。

在微服務架構中,如果您希望應用程式以符合成本效益的方式執行,同時保持服務獨立且可單獨管理,您可以為每個服務分配專用 VM,以確保能單獨管理及部署服務。但這種做法可能會讓許多 VM 的使用量過低,產生不必要的費用。對於這類應用程式而言,使用允許緊密「封裝」的部署模型 (尤其是容器式模型) 可能更具成本效益。

狀態與無狀態

當您為雲端環境設計應用程式時,請嘗試讓應用程式保持為無狀態,並使用以 Google Cloud 為基礎的儲存空間服務在外部管理狀態。無狀態應用程式提供許多優勢,包括:

  • 可備援部署,提高可用性和容量。
  • 可將要求自由分散在執行個體之間。
  • 非常適合用於自動調度資源。
  • 如果作業失敗,您可以重新建立環境 (無論是容器或 VM),而不必擔心有資料遺失的風險。

將應用程式設計為無狀態並不容易,許多舊版應用程式都未遵循這個做法。不過,您可以花點時間分析您是否能讓應用程式處於無狀態,這會非常值得。

工作階段狀態

ASP.NET 和 ASP.NET MVC 應用程式通常使用工作階段來追蹤使用者狀態,讓應用程式有狀態。然而,您有多種選項可以限制工作階段的影響範圍:

  • 如果工作階段的資料量很小,您可以改將狀態儲存在已加密或已簽署的 Cookie 中。
  • 除了使用預設的 InProc 工作階段狀態提供者以外,您也可以使用 SQLServer 提供者。但是,這需要使用 SQL Server 執行個體,除了會產生額外費用,也會影響應用程式的延遲時間和可用性。
  • 您可以善用 Cloud Load Balancing 中的工作階段相依性。這項功能可確保單一用戶端的所有要求都會轉送至相同的應用程式執行個體。但是,使用工作階段相依性會對負載平衡的公平性造成負面影響;也就是說,某些應用程式執行個體最終收到的要求,可能會比其他應用程式執行個體來得多。此外,如果某個應用程式執行個體因任何原因而遭到終止,則該執行個體處理的任何工作階段便會遺失,進而可能影響到使用者。因此,依賴工作階段相依性並非最佳解決方案,但這通常是兼顧可靠性和成本的可行選項。

記憶體內建的快取

應用程式通常會使用記憶體內建的快取,避免多餘的計算或資料庫搜尋作業。如果應用程式有多個執行個體同時執行,快取可能會變得不一致,進而造成問題。

為避免發生不一致的問題,請直接或透過 IDistributedCache 介面使用分散式快取。快取伺服器 (例如 Redis 或 Memcached) 的資源要求通常相對較低,但會提高整體設定的複雜度。

儲存空間

系統通常會將圖片、附件或媒體檔案形式的資料儲存在磁碟中。通常不建議您為此目的使用 VM 上的永久磁碟,因為這樣資料將無法在多個機器之間共用,且如果重新建立 VM 執行個體,還可能會遺失資料。不過,您可以採用下列其中一項做法:

  • 將資料移至檔案共用伺服器。這會大幅降低對應用程式的影響。但是,執行高可用性 SMB 或 NFS 伺服器代表需要額外的費用和維護作業。
  • 將資料移至 Cloud Storage。 雖然這需要變更應用程式,但 Cloud Storage 具有高可用性、比執行檔案伺服器更具成本效益,而且也不需要處理額外的維護工作。
  • 將資料移至 Filestore 檔案伺服器。 這個方法可能需要對應用程式進行一些變更,但完成佈建後,您就能根據需求擴充執行個體的容量,而且不會有任何停機時間。Filestore 也支援多個並行應用程式執行個體同時存取相同檔案系統。
  • 將資料移至 Cloud Volumes Service。Cloud Volumes 服務支援 NFS 和 SMB 磁碟區,可讓您將以檔案為基礎的應用程式遷移至 Google Cloud。您不必重新建構應用程式,還能輕鬆為應用程式取得永久儲存空間。

部署策略

部署新版應用程式時,您必須盡可能降低風險和對使用者的影響。有三種最常見的策略可達到這個目標,分別是「重新建立」、「藍綠」和「滾動式部署」

重新建立策略

「重新建立」策略的概念是停止所有伺服器上的執行中應用程式、部署新版本,並啟動應用程式。這個策略的明顯缺點是會導致服務中斷,但可避免兩個不同版本的應用程式在暫時共存期間,存取通用資料時所引致的潛在問題。

藍綠策略

「藍綠」(又稱為「紅黑」) 策略的概念是在一組新的伺服器上部署新的應用程式版本。部署完成後,您可以將所有流量從舊伺服器切換到新的伺服器組。這個方式暫時需要的伺服器數量最多達實際工作環境所需的兩倍,但可以避免服務中斷。

此策略的必要條件是應用程式的兩個版本可以暫時共存,且不會互相干擾。如果應用程式需要存取資料庫,這個策略要求資料庫結構的每個變更疊代都必須至少回溯相容上一個版本。

滾動式部署策略

「滾動式部署」的概念是一個接一個地更新伺服器。與藍綠策略的相同之處在於,這代表兩個不同版本的應用程式會在一段時間內共存。但與藍綠部署作業的不同之處在於,流量會逐漸從舊版本轉送至新版本。越多伺服器完成更新,轉送至新版本的使用者就越多,直到最終,當最後一個伺服器完成更新時,所有使用者都會使用新版本。這個方式的主要優點是能在所有使用者受到影響前及早偵測出潛在問題,有助於降低整體風險。

由於滾動式部署需要兩個版本的應用程式共存,因此也需要設定負載平衡器,以避免使用者在版本之間彈跳。

部署選項

到目前為止,本頁面已經討論了部署模型、目標和策略。以下各節將介紹在Google Cloud上部署 .NET 應用程式的特定選項。

GKE (Windows 或 Linux)

GKE 提供全代管的 Kubernetes 環境。Kubernetes 的自動化調度管理功能,讓 GKE 非常適合執行由許多容器組成的複雜微服務應用程式。不過,即使是未遵循微服務模式的應用程式,GKE 也允許您以共用基礎架構的方式執行多個容器,既節省資源又易於維護。

GKE 需要將應用程式的所有部分都封裝為 Docker 容器。以 Linux 為基礎的容器需要使用 .NET 和 Linux 環境。如果您的 CI 系統以 Windows 為基礎,在 Linux 中建構容器可能頗具挑戰性。不過 Azure Pipelines、Team Foundation Server 和 Cloud Build 提供內建支援,可用於建構 .NET 應用程式,以及建構和發布 Linux 容器映像檔。

GKE 為無狀態應用程式提供最大的彈性。透過使用有狀態集合和永久磁碟區,您也可以在 GKE 上執行某些類型的有狀態應用程式。

GKE 叢集包含許多稱為「節點」 VM 執行個體;容器會在這些節點上安排排程。在多區域或地區叢集中,GKE 可以在多區域之間分配節點和工作負載,以確保高可用性。

費用是依據執行中的節點數量計算。因此,當節點的使用率適當時,GKE 最具成本效益。您可以在相同叢集上執行較大的工作負載,也可以視需要自動調整節點數量

使用 kubectl 指令進行提取式部署

將應用程式部署到 GKE 有兩個步驟:

  1. 使用 docker push 或其他方式將 Docker 映像檔發布到 Artifact Registry 或外部 Docker Registry。這個步驟通常由持續整合系統負責處理。
  2. 使用 kubectl 觸發部署作業。這個步驟可以由持續整合系統負責處理,也可以單獨處理。由於部署作業是從遠端啟動,因此 kubectl 可以在 Linux 或 Windows 上執行。

GKE 提供適用於重新建立和滾動式部署策略的內建支援。雖然控管部署的基本功能非常具有彈性,也適用於其他部署策略,但採用其他策略需要使用額外的工具或指令碼。

使用 Spinnaker 進行提取式部署

如果用於調度部署作業的 GKE 內建功能無法滿足您的需求,您可以將 GKE 與 Spinnaker 搭配使用。Spinnaker 提供適用於 GKE 的內建支援,可讓您實作更進階的部署策略,包含藍綠部署。

由於 Spinnaker 不是代管服務,因此必須單獨部署及維護。您可以將 Spinnaker 部署在獨立的 Linux VM 執行個體上或 GKE 叢集中。

Knative 和 Cloud Run

對於無狀態 .NET 容器,Knative 和其代管版本 Cloud Run 提供無伺服器容器環境。無伺服器容器提供佈建、自動調度資源和負載平衡等優點,無須費心管理基礎架構。

如要在 Kubernetes 叢集中部署容器,Knative 提供比 Kubernetes 更高層級且更小的 API 介面。因此,Knative 可協助您避開 Kubernetes 的複雜作業,讓容器部署作業更加輕鬆。

Cloud Run 遵循 Knative API,但會在 Google 基礎架構上執行,因此不需要 Kubernetes 叢集。Cloud Run 提供無伺服器容器選項。根據預設,Cloud Run 中的容器會自動調度資源,並在要求期間收費。部署時間以秒為單位。Cloud Run 也提供實用功能,例如修訂版本和流量分配。

Knative serving 是 Cloud Run 的彈性版本,兼具 Knative 和 Cloud Run 的簡便性,以及 Kubernetes 的運作彈性。舉例來說,您可以在 GKE Enterprise 上使用 Cloud Run,為執行容器的基礎執行個體新增 GPU,或將應用程式擴充至多個容器。

Cloud Run 可與其他服務整合,例如 Pub/Sub、Cloud Scheduler、Cloud Tasks,以及 Cloud SQL 等後端服務。無論是自動調度資源的網路前端,或是由事件觸發的內部微服務,都可使用這項功能。

Compute Engine (Windows 或 Linux)

Compute Engine 可讓您建立及管理 VM 執行個體,並支援一系列的 Windows Server 版本和 Linux 發行版,以及規模調整功能和設定選項。由於具備這樣的彈性,您可以使用 Compute Engine VM 執行個體來處理各種工作負載。

為確保能夠單獨部署及維護應用程式,請為每個 VM 執行個體僅部署單一應用程式或服務。為確保高可用性,請為每個應用程式執行至少兩個 VM 執行個體,每個執行個體必須位於不同區域。如此一來,無論預期負載為何,您都可以假設您所需的 VM 執行個體數量是待部署應用程式或服務的兩倍。

Compute Engine 提供了一種透過代管執行個體群組實作自動調度資源的簡單方式。此外,代管執行個體群組也提供一種實作滾動式部署的方式,詳情請見後文。

由於 Compute Engine 是依據 VM 執行個體計費,當應用程式收到大量負載時,會轉化成 VM 執行個體的高使用率,因此您可以假設在 Compute Engine 上執行應用程式是最具成本效益的做法。相反地,如果服務和應用程式的數量很多,但平均使用率偏低,則使用 GKE 等其他部署作業會較為經濟實惠。這是因為其他部署作業選項允許多個應用程式使用共用基礎架構,而不會犧牲工作負載區隔。

執行 Windows VM 執行個體必須使用付費映像檔。這些映像檔包含 Windows 的授權複本,因此必須支付額外費用。由於使用 CentOS 或 Debian 等 Linux 發行版的 VM 不會產生任何授權費用,因此相較之下,Windows VM 的成本效益通常較低。

您可以使用 SSH 或 RDP 手動設定 VM 執行個體,手動部署應用程式或處理任何必要初始設定,以準備第一次部署使用的機器。但是,這可能會導致具有專屬設定的機器與其他 VM 執行個體不同。長期來看,手動設定 VM 執行個體可能會變得既複雜又耗費人力。因此,建議您自動化執行該程序,讓程序能重複執行。

在 Compute Engine 上自動執行應用程式部署作業包括下列工作:

  1. 為第一次應用程式部署作業佈建及準備 VM 執行個體。
  2. 執行應用程式部署作業。
  3. 提供 OS 服務 (安裝安全性更新)。

以下兩節說明如何使用提取式部署方法統一處理所有三個步驟。雖然這些小節中說明的做法使用了不同機制和工具,但整體概念與使用 GKE 部署容器式應用程式的做法類似。

使用代管執行個體群組進行提取式部署

代管執行個體群組最常用於實作自動調度資源,但也提供處理滾動式部署的方法。建立參照新版應用程式的執行個體範本後,您可以使用滾動式更新功能,將使用舊範本的 VM 執行個體取代為使用新範本的執行個體。

這個方式的前提是,新版應用程式可做為執行個體範本使用。您可以透過下列方式達成此目的:

  • 定義使用其中一個公開 OS 映像檔的執行個體範本。 使用開機指令碼設定系統,並安裝 Cloud Storage 值區、NuGet 存放區、Docker Registry 或其他來源中的應用程式。下圖說明了這項做法。

    使用代管執行個體群組和公開映像檔進行提取式部署

  • 在持續整合/持續推送軟體更新程序中建立自訂 VM 映像檔,這個程序通常稱為「製作映像檔」。在此方式中,您會使用其中一個公開 OS 映像檔產生新的 VM 執行個體、在其中安裝最新版應用程式、從執行個體建立 VM 映像檔,並讓映像檔可供 Google Cloud 專案使用。您可以使用 Packer 這類工具自動執行整個程序。接著,您可以在執行個體範本中參照產生的映像檔。下圖說明了這項做法。

    使用代管執行個體群組和自訂映像檔進行提取式部署

建立自訂映像檔 (第二個選項) 的缺點在於製作映像檔的程序相對緩慢,通常需要幾分鐘的時間。因此,這個做法對持續整合/持續推送軟體更新程序來說,不僅增加了複雜度,還減緩了速度。從優點方面來說,使用自訂映像檔啟動新 VM 的程序簡單又快速,這在使用自動調度資源功能時非常實用。

使用開機指令碼來部署應用程式 (第一個選項) 具有相對的優缺點。在持續整合/持續推送軟體更新程序中,這不會產生製作映像檔的費用負擔,但會減緩建立 VM 執行個體程序的速度。此外,如果開機指令碼不完全穩定,或者下載應用程式二進位檔的來源系統不具備高可用性,則此方法可能會導致可用性降低。

最適合您的應用程式的方法,需取決於應用程式本身和設定的複雜度。在某些情況下,建議您結合下列兩種方法:

  • 自訂映像檔包含所有設定和相依項目,但不包含實際的應用程式二進位檔。當設定或任一相依項目變更時,便會建立新的映像檔,但不會針對每個應用程式版本建立。這樣可避免應用程式持續整合/持續推送軟體更新管道的速度延緩問題。
  • 使用開機指令碼安裝應用程式。為了大幅降低風險和速度延遲的情況,這個程序應該要盡可能簡單。

假如您要部署多個不同的應用程式或服務具有通用基礎設定,此混合式做法可讓您免於建構及維護數十個、甚至數百個幾乎相同的映像檔。

您可以使用代管執行個體群組自動化調度管理 Linux 和 Windows 工作負載的部署作業。以 Linux 來說,使用代管執行個體群組在 VM 執行個體上部署 Docker 容器是可行的做法,並且受到平台支援。 但建議您只用於高使用率的應用程式。在其他情況下,為每個 VM 部署單一 Docker 容器的好處,並不會優於使用 GKE 或 App Engine 彈性環境。

如要使用 Windows Server 容器,請遵循下列準則,以使用 Compute Engine 和代管執行個體群組執行容器:

  • 使用已預先安裝 Docker 的自訂映像檔,或下列其中一個公開映像檔:
    • Windows Server 2019 Datacenter Core for Containers
    • Windows Server 2019 Datacenter for Containers
  • 在 VM 啟動期間,使用開機指令碼提取 Docker 映像檔,然後將其做為 Windows Server 容器啟用。您可以使用適當的通訊埠對應來公開發佈容器中執行的服務。

請注意,開機指令碼只有在啟動 Docker 服務的情況下才保證能順利執行。如要在啟動 Docker 之前妥善處理指令碼的運作情形,請在指令碼中加入適當的重試邏輯。

在非雲端環境中建立 Windows 映像檔時,您可能會依賴 Microsoft 部署工具包 (MDT)Windows 部署服務 (WDS)。不過,由於管理映像檔和根據自訂映像檔建立 VM 執行個體是 Compute Engine 的核心功能,您不需要使用這些額外的工具。Compute Engine 不僅支援開機指令碼,而且也支援 Windows VM 執行個體的專屬指令碼。因此,通常不需要使用自訂的 unattend.xml 檔案。然而,在建立映像檔之前,使用 GCESysprep 讓 Windows 安裝作業「通用化」還是非常重要。

使用 Spinnaker 進行提取式部署

代管執行個體群組提供一種輕量化且可靠的方式來實作滾動式部署,但對一些應用程式來說,代管執行個體群組的功能可能並不完善。如要實作更複雜的部署策略和管道,可使用 Spinnaker。

Spinnaker 在 Compute Engine 上自動化調度管理部署作業時,所採取的基本做法與上一節的說明內容相似,也同樣依賴映像檔製作。因此,請留意相同的注意事項。

由於 Spinnaker 不是代管服務,您必須透過應用程式單獨進行部署及維護。您可以將 Spinnaker 部署在獨立的 Linux VM 執行個體上或 GKE 叢集中。

推送式遠端部署

前幾節討論的提取式部署選項提供了許多優勢,但是並不適用於各種類型的應用程式。要特別注意的是,有狀態應用程式通常不適合使用這個方法,而且可能更適合使用推送式方法。

在推送式方法中,您需要分別處理三項部署工作 (佈建 VM 執行個體、執行應用程式部署作業、提供 OS 服務)。您可以使用相同的工具處理這三項工作,不過每項工作都使用不同的工具處理也很常見。

您可以使用 Terraform 等自動化工具,以與其他基礎架構相同的方式佈建應用程式伺服器 VM 執行個體。您可以使用開機指令碼或專屬指令碼,安裝自動執行應用程式部署作業的所需工具。舉例來說,如果您使用 Puppet、Chef 或 Octopus Deploy,您必須確認已安裝這些工具的代理程式軟體。

從安全性的角度來看,為了減少攻擊面,請確保在部署伺服器與應用程式伺服器 VM 執行個體上執行的任何代理程式之間,進行的所有通訊都使用內部網路。此外,也請確保正在使用的通訊埠不會暴露在公開網際網路下。

在不使用自動調度資源的環境中,您可以將 Windows 應用程式伺服器加入 Active Directory 網域,這是集中管理設定的可行方法。使用 Active Directory 也讓您可以控管 OS 服務等管理工作。

選擇部署選項

如本頁面開頭所述,在 Google Cloud上部署 .NET 應用程式不只一種最佳方法。最佳部署選項需取決於您的應用程式和需求。如要選擇正確的模型,首要問題在於您是要使用 .NET 或 .NET Framework,並視情況決定要部署在 Linux 或 Windows 上。確定目標作業系統後,請使用下列決策樹狀圖協助您決定合適的部署模型。

在 Linux 上部署 .NET 應用程式:

使用 .NET 和 Linux 進行部署的決策樹狀圖

在 Windows 上部署 .NET 或 .NET Framework 應用程式:

使用 Windows 進行部署的決策樹狀圖

後續步驟