共用方式為


利用容器和協調器

提示

此內容摘錄自《建構適用於 Azure 的雲端原生 .NET 應用程式》電子書,您可以在 .NET Docs 找到此電子書,或免費下載可離線閱讀的 PDF。

Cloud Native .NET apps for Azure eBook cover thumbnail.

容器和協調器旨在解決整合型部署方法的常見問題。

整合型部署的挑戰

依傳統方法,大部分的應用程式皆部署為單一單位。 這類應用程式稱為整合型。 這種即使應用程式是由多個模組或組件所組成,也普遍將其部署為單一單位的方法,稱為整合型架構,如圖 3-1 所示。

Monolithic architecture.

圖 3-1 整合型架構。

雖然整合型架構具有簡單性的優點,但仍面臨許多挑戰:

部署

此外,它們需要重新啟動應用程式,如果部署時未套用零停機技術,可能會暫時影響可用性。

調整大小

整合型應用程式完全裝載在單一機器執行個體上,通常需要有高功能的硬體。 如果整合型應用程式的任一部分需要擴縮,您即必須將完整應用程式的新複本也部署到另一部電腦。 使用整合型應用程式時,您無法個別擴縮應用程式元件,只能全部更新或什麼都不做。 擴縮不需要擴縮的元件會導致資源使用量效率不佳且成本高昂。

Environment

整合型應用程式通常會隨著預先安裝的作業系統、執行階段和程式庫相依性,一起部署到裝載環境。 此環境可能與開發或測試應用程式時所用的環境不完全相符。 應用程式環境之間的不一致是整合型部署常見的問題來源。

結合程度

整合型應用程式可能會發生功能元件高度結合的問題。 如果沒有強制界限,系統變更通常會導致非預期且成本高昂的副作用。 新功能/修正的實作會變得很麻煩、耗時且昂貴。 更新需要大量測試。 結合程度也使得重構元件或切換替代實作變得困難。 即使建構時考慮了嚴格區隔,但深植於整合型程式碼基底的架構磨損也會隨永無止境的「特殊案例」惡化。

平台鎖定

整合型應用程式是以單一技術堆疊所建構。 雖然提供統一性,但此承諾會成為創新障礙。 即使另有更多更好的新式技術可供選擇,新功能和元件仍會使用應用程式目前的堆疊建置。 長期的風險是所用技術堆疊會逐漸過期過時。 將整個應用程式重新架構到全新的新式平台,不僅昂貴且有風險。

容器和協調器有哪些優點?

第 1 章介紹了容器。 我們強調了 Cloud Native Computing Foundation (CNCF) 如何在其雲端原生路線圖 (英文) 中將容器化排為第一個步驟,這是開始雲端原生旅程的企業指導。 本節會討論容器的優點。

Docker 是最熱門的容器管理平台。 適用於 Linux 或 Windows 的容器。 容器可在任何系統上提供以相同方式執行,彼此分隔卻可重現的應用程式環境。 這使其非常適合用於開發與裝載雲端原生服務。 容器彼此分隔。 位在相同主機硬體上的兩個容器,可有不同的軟體版本,卻不會造成衝突。

容器是由簡單的文字型檔案所定義,這些檔案會變成專案成品,並會簽入原始檔控制中。 雖然完整伺服器和虛擬機器需要手動更新,但容器很容易以版本控制。 您可在建置管線中,使用自動化工具開發、測試及部署要在容器中執行的應用程式。

容器是不可變動的。 定義容器之後,您可以使用完全相同的方式重新建立並執行容器。 這種不變性使其本身適合元件型的設計。 如果應用程式某部分的發展與其他部分不同,若是可以只部署變更最頻繁的部分,為何要重新部署整個應用程式? 應用程式的不同功能和跨領域考量可以拆分成不同的單元。 圖 3-2 顯示整合型應用程式如何藉由委派特定特性或功能,利用容器和微服務。 應用程式本身的其餘功能也已容器化。

Breaking up a monolithic app to use microservices in the back end.

圖 3-2: 將整合型應用程式分解為可使用的微服務。

每項雲端原生服務都是建置並部署在不同的容器中。 每個都可以視需要更新。 個別服務可以裝載於有各項服務適用資源的節點上。 每項服務執行所在的環境都是固定的,可跨開發、測試和實際執行環境共用,且容易控制版本。 應用程式不同區域之間會明確結合為服務之間的呼叫或訊息,而不是整合型內的編譯時期相依性。 您也可以選擇最適合指定功能的技術,無須變更應用程式的其餘部分。

容器化服務需要自動化管理。 手動管理一組大型獨立部署的容器並不可行。 以下列工作為例:

  • 如何在有多部機器的叢集中佈建容器執行個體?
  • 部署之後,容器會如何探索彼此並互相通訊?
  • 容器如何視需要縮減或擴增?
  • 如何監視每個容器的健康狀態?
  • 如何保護容器不受硬體和軟體故障影響?
  • 如何利用零停機時間升級即時應用程式的容器?

容器協調器會處理並自動化這些問題和其他疑慮。

在雲端原生的生態系統中,Kubernetes 已成為事實的容器協調器。 它是由 Cloud Native Computing Foundation (CNCF) 管理的開放原始碼平台。 Kubernetes 會將整個機器叢集中的容器化工作負載部署、擴縮和作業考量事項自動化。 不過,安裝與管理 Kubernetes 是眾所周知地複雜。

更好的方法是利用 Kubernetes 作為雲端廠商的受控服務。 Azure 雲端提供完全受控的 Kubernetes 平台,名為 Azure Kubernetes Service (AKS)。 AKS 提取管理 Kubernetes 的複雜度和操作負荷。 您可將 Kubernetes 當成雲端服務使用,Microsoft 負責其管理和支援。 AKS 也與其他 Azure 服務和開發工具緊密整合。

AKS 是以叢集為基礎的技術。 同盟虛擬機器或節點的集區會部署至 Azure 雲端。 共同形成具有高可用性的環境或叢集。 叢集會顯示為雲端原生應用程式的隨選即用單一實體。 在幕後,AKS 會遵循預先定義的平均分散負載策略,跨這些節點部署容器化服務。

擴縮的優點為何?

建置在容器上的服務可以利用 Kubernetes 等協調流程工具所提供的擴縮優點。 自設計伊始,容器就只知道自己。 一旦需要多個容器聯手合作,就需要在較高層級組織它們。 當要組織大量容器及其共用相依性時,例如網路組態,就是需要使用協調流程工具以節省精力的時候! Kubernetes 會在容器群組上建立抽象層,並將其組織成 Pod。 Pod 會在稱為節點的背景工作電腦上執行。 這個組織結構稱為叢集。 圖 3-3 顯示 Kubernetes 叢集的不同元件。

Kubernetes cluster components.圖 3-3。 Kubernetes 叢集元件。

擴縮容器化工作負載是容器協調器的重要功能。 AKS 支援跨兩個維度的自動擴縮:容器執行個體和計算節點。 它們共同讓 AKS 能夠快速有效地回應需求尖峰,並新增其他資源。 本章稍後會討論 AKS 的擴縮功能。

宣告式與命令式

Kubernetes 支援宣告式組態和命令式組態。 命令式方法涉及執行各種命令,通知 Kubernetes 在每個步驟中該執行的工作。 執行這個映像。 刪除這個 Pod。 公開這個連接埠。 使用宣告式方法則要建立稱為資訊清單的組態檔,說明您的目的,而不是要執行的工作。 Kubernetes 會讀取資訊清單,將您想要的結果轉換成實際的結果。

命令式命令非常適合學習和互動式實驗。 不過,建議您以宣告方式建立 Kubernetes 資訊清單檔案,採用基礎結構即程式碼方法,提供可靠且可重複的部署。 資訊清單檔會變成專案成品,用於 CI/CD 管線中以自動化 Kubernetes 部署。

如果您已經使用命令式命令設定叢集,您可以使用 kubectl get svc SERVICENAME -o yaml > service.yaml 匯出宣告式資訊清單。 此命令會產生類似如下的資訊清單:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-09-13T13:58:47Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
  resourceVersion: "153"
  selfLink: /api/v1/namespaces/default/services/kubernetes
  uid: 9b1fac62-d62e-11e9-8968-00155d38010d
spec:
  clusterIP: 10.96.0.1
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

使用宣告式組態時,您可以對組態檔所在的資料夾使用 kubectl diff -f FOLDERNAME,在認可前預覽所要執行的變更。 確定要套用變更之後,請執行 kubectl apply -f FOLDERNAME。 新增 -R 以遞迴方式處理資料夾階層。

您也可以使用宣告式組態搭配其他 Kubernetes 功能,其中一個是部署。 宣告式部署有助於管理版本、更新和擴縮。 它們會指示 Kubernetes 部署控制器如何部署新的變更、擴增負載或復原回先前的修訂。 如果叢集不穩定,宣告式部署就會自動將叢集傳回所需的狀態。 例如,如果節點即將損毀,部署機制即會重新部署一個替代品,以達到您想要的狀態

使用宣告式組態可讓基礎結構以程式碼表示,這些程式碼可與應用程式程式碼一起簽入及設定版本。 其可使用建置和部署管線為持續部署提供改良的變更控制和更好的支援。

哪些案例適合使用容器和協調器?

下列案例適合使用容器和協調器。

需要高執行時間和可擴縮性的應用程式

具有高執行時間和可擴縮性需求的個別應用程式最適合使用微服務、容器和協調器的雲端原生架構。 它們可以在容器中發展、跨版本設定環境進行測試,以及部署至不會停機的實際執行環境。 使用 Kubernetes 叢集可確保這類應用程式也可以視需要擴縮,並從節點失敗中自動復原。

大量的應用程式

部署與維護大量應用程式的組織可自容器和協調器得益。 設定容器化環境和 Kubernetes 叢集的前置工作主要是固定的成本。 部署、維護及更新個別應用程式的成本,會隨著應用程式數目而有所不同。 除了少數幾個應用程式之外,手動維護自訂應用程式的複雜度超過使用容器和協調器實作解決方案的成本。

何時應該避免使用容器和協調器?

如果無法依十二要素應用原則建置應用程式,建議您考慮避免容器和協調器。 在這些情況下,請考慮 VM 型的裝載平台,或者一些混合式系統。 使用此工具,即可將某些功能片拆分成不同的容器,或甚至是無伺服器函式。

開發資源

本節顯示一份簡短的開發資源清單,可協助您開始為下一個應用程式使用容器和協調器。 如需如何設計雲端原生微服務架構應用程式的指導,請參閱本書的參考指南:.NET 微服務:容器化 .NET 應用程式的架構

本機 Kubernetes 開發

Kubernetes 部署在實際執行環境中提供極大的價值,但也可以在開發電腦上本機執行。 雖然您可以獨立使用個別微服務,但有時可能需要在本機執行整個系統,就像部署至實際執行環境時一樣。 有數個工具可提供協助:Minikube 和 Docker Desktop。 Visual Studio 也為 Docker 開發提供工具。

Minikube

什麼是 Minikube? Minikube 專案表示「Minikube 會在 macOS、Linux 和 Windows 上實作本機 Kubernetes 叢集」。其主要目標是「成為本機 Kubernetes 應用程式開發的最佳工具,並支援所有合適的 Kubernetes 功能」。安裝 Minikube 與 Docker 不同,但 Minikube 支援與 Docker Desktop 支援的不同 Hypervisor。 Minikube 目前支援下列 Kubernetes 功能:

  • DNS
  • NodePorts
  • ConfigMap 和祕密
  • 儀表板​​
  • 容器執行階段:Docker、rkt、CRI-O 和容器化
  • 啟用容器網路介面 (CNI)
  • 輸入

安裝 Minikube 之後,您可以執行 minikube start 命令快速啟動,以下載映像並啟動本機 Kubernetes 叢集。 啟動叢集之後,您可以使用標準 Kubernetes kubectl 命令與其互動。

Docker Desktop

您也可以直接從 Windows 上的 Docker Desktop 使用 Kubernetes。 如果使用 Windows 容器,這會是您唯一的選擇,也是非 Windows 容器的絕佳選擇。 圖 3-4 顯示如何在執行 Docker Desktop 時啟用本機 Kubernetes 支援。

Configuring Kubernetes in Docker Desktop

圖 3-4: 在 Docker Desktop 中設定 Kubernetes。

Docker Desktop 是在本機設定與執行容器化應用程式的最熱門工具。 當您使用 Docker Desktop 時,可以針對將部署至實際執行環境的相同 Docker 容器映像集在本機開發。 Docker Desktop 旨在於本機「建置、測試及寄送」容器化應用程式。 其可支援 Linux 和 Windows 容器。 一旦您將映像推送至映像登錄,例如 Azure Container Registry 或 Docker Hub,AKS 就可以提取映像並將其部署至實際執行環境。

Visual Studio Docker 工具

Visual Studio 支援 Web 型應用程式的 Docker 開發。 建立新的 ASP.NET Core 應用程式時,您可選擇與 Docker 支援一起進行設定,如圖 3-5 所示。

Visual Studio Enable Docker Support

圖 3-5: Visual Studio 啟用 Docker 支援

選取此選項後,專案會使用其根目錄中的 Dockerfile 建立,以在 Docker 容器中建置及裝載應用程式。 圖 3-6 顯示 Dockerfile 範例。

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["eShopWeb/eShopWeb.csproj", "eShopWeb/"]
RUN dotnet restore "eShopWeb/eShopWeb.csproj"
COPY . .
WORKDIR "/src/eShopWeb"
RUN dotnet build "eShopWeb.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "eShopWeb.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "eShopWeb.dll"]

圖 3-6: Visual Studio 產生的 Dockerfile

新增支援之後,您可以在 Visual Studio 的 Docker 容器中執行您的應用程式。 圖 3-7 顯示以新增的 Docker 支援所建立之新 ASP.NET Core 專案中可用的不同執行選項。

Visual Studio Docker Run Options

圖 3-7: Visual Studio Docker 執行選項

此外,您隨時可將 Docker 支援新增至現有的 ASP.NET Core 應用程式。 在 Visual Studio 方案總管中,以滑鼠右鍵按一下專案,然後選取 [新增]>[Docker 支援],如圖 3-8 所示。

Visual Studio Add Docker Support

圖 3-8: 將 Docker 支援新增至 Visual Studio

Visual Studio Code Docker 工具

Visual Studio Code 有許多延伸模組可支援 Docker 開發。

Microsoft 提供 Docker for Visual Studio Code 延伸模組。 此延伸模組可簡化將容器支援新增至應用程式的流程。 其可產生必要的檔案、建置 Docker 映像,並讓您偵錯容器內的應用程式。 延伸模組是視覺化總管,讓您輕鬆對容器和映像採取動作,例如啟動、停止、檢查、移除等等。 此延伸模組也支援 Docker Compose,讓您將多個執行中的容器當成單一單位管理。