在 Azure 上部署和測試任務關鍵性工作負載
任務關鍵環境的部署和測試是整體參考架構的重要部分。 個別的應用程式戳記是使用原始程式碼存放庫中的基礎結構即程式代碼來部署。 更新 至基礎結構,且應用程式位於頂端,應以零停機時間部署至應用程式。 建議使用 DevOps 持續整合管線,從存放庫擷取原始程式碼,並在 Azure 中部署個別戳記。
部署和更新是架構中的中央程式。 基礎結構和應用程式相關更新應部署至完全獨立的戳記。 只有架構中的全域基礎結構元件會跨戳記共用。 基礎結構中的現有戳記不會觸碰。 基礎結構更新只會部署到這些新的戳記。 同樣地,新的應用程式版本只會部署到這些新的戳記。
新的戳記會新增至 Azure Front Door。 流量逐漸轉移到新的戳記。 當它判斷流量是從新的戳記提供而不發出時,就會刪除先前的戳記。
針對已部署的環境,建議進行滲透、混亂和壓力測試。 基礎結構的主動式測試會發現弱點,以及部署的應用程式在發生失敗時的行為。
部署
參考架構中的基礎結構部署取決於下列程式和元件:
DevOps - 來自 GitHub 的原始程式碼和基礎結構的管線。
零停機更新 - 更新 和升級會部署到環境,而已部署的應用程式不會停機。
環境 - 用於架構的短期和永久環境。
共用和專用資源 - 專用和共用至戳記和整體基礎結構的 Azure 資源。
如需詳細資訊,請參閱 在 Azure 上部署和測試任務關鍵性工作負載:設計考慮
部署:DevOps
DevOps 元件提供原始程式碼存放庫和 CI/CD 管線,以部署基礎結構和更新。 GitHub 和 Azure Pipelines 已選擇為元件。
GitHub - 包含應用程式和基礎結構的原始程式碼存放庫。
Azure Pipelines - 架構用於所有建置、測試和發行工作的管線。
用於部署的設計中,額外的元件是組建代理程式。 Microsoft 裝載的組建代理程式會用來作為 Azure Pipelines 的一部分,以部署基礎結構和更新。 使用 Microsoft 裝載的組建代理程式可減輕開發人員維護及更新組建代理程式的管理負擔。
如需 Azure Pipelines 的詳細資訊,請參閱 什麼是 Azure DevOps Services?。
如需詳細資訊,請參閱 在 Azure 上部署和測試任務關鍵性工作負載:基礎結構即程式代碼部署
部署:零停機更新
參考架構中的零停機時間更新策略是整體任務關鍵性應用程式的核心。 取代的方法,而不是升級戳記可確保將應用程式全新安裝到基礎結構戳記中。 參考架構會使用藍色/綠色方法,並允許個別的測試與開發環境。
參考架構有兩個主要元件:
基礎結構 - Azure 服務和資源。 使用 Terraform 及其相關聯的組態進行部署。
應用程式 - 為使用者提供服務的託管服務或應用程式。 以適用於單頁應用程式 (SPA) UI 的 HTML 和 JavaScript 中的 Docker 容器和 npm 建置成品為基礎。
在許多系統中,假設應用程式更新會比基礎結構更新更頻繁。 因此,會針對每個程序開發不同的更新程式。 使用公用雲端基礎結構時,變更的速度可能會加快。 已選擇一個應用程式更新和基礎結構更新的部署程式。 其中一種方法可確保基礎結構和應用程式更新一律同步。此方法允許:
一個一致的程式 - 如果基礎結構和應用程式更新在發行中故意或不混合,則錯誤的機會較少。
啟用藍/綠部署 - 每個更新都是使用逐步移轉至新版本的流量來部署。
更容易部署和偵錯應用程式 - 整個戳記永遠不會並存裝載多個版本的應用程式。
簡單回復 - 如果發生錯誤或問題,流量可以切換回執行舊版的戳記。
消除手動變更和設定漂移 - 每個環境都是全新的部署。
如需詳細資訊,請參閱 在 Azure 上部署和測試任務關鍵性工作負載:暫時藍/綠部署
分支策略
更新策略的基礎是使用 Git 存放庫中的分支。 參考架構使用三種類型的分支:
分支 | 描述 |
---|---|
feature/* 和 fix/* |
任何變更的進入點。 這些分支是由開發人員所建立,應該提供描述性名稱,例如 feature/catalog-update 或 fix/worker-timeout-bug 。 當變更準備好合併時,會針對 main 分支建立提取要求 (PR)。 每個 PR 必須至少由一個檢閱者核准。 在有限的例外狀況下,PR 中建議的每個變更都必須透過端對端驗證管線執行。 開發人員應該使用 E2E 管線來測試和偵錯完整環境的變更。 |
main |
持續向前移動和穩定分支。 大部分用於整合測試。 main 的變更只會透過提取要求進行。 分支原則會禁止直接寫入。 系統會從 分支自動執行main 針對永久integration (int) 環境的夜間發行。 分支 main 視為穩定。 假設在任何指定時間,都可以從中建立發行,這應該很安全。 |
release/* |
發行分支只會從 main 分支建立。 分支會遵循 格式 release/2021.7.X 。 使用分支原則,只允許存放庫管理員建立 release/* 分支。 只有這些分支可用來部署至 prod 環境。 |
如需詳細資訊,請參閱 在 Azure 上部署和測試任務關鍵性工作負載:分支策略
Hotfix
當因為 Bug 或其他問題而需要 Hotfix,且無法進行一般發行程式時,可以使用 Hotfix 路徑。 在初始測試期間未探索到用戶體驗的重要安全性更新和修正,會被視為 Hotfix 的有效範例。
Hotfix 必須在新的 fix
分支中建立,然後使用一般 PR 合併至 main
。 Hotfix 不是建立新的發行分支,而是「挑選」到現有的發行分支。 此分支已部署至 prod
環境。 原本部署發行分支且所有測試的 CI/CD 管線會再次執行,現在會將 Hotfix 部署為管線的一部分。
若要避免重大問題,請務必讓 Hotfix 包含一些隔離的認可,以便輕鬆地挑選並整合至發行分支。 如果無法挑選隔離的認可來整合至發行分支,表示變更不符合 Hotfix 資格。 變更應部署為完整的新版本,並可能結合復原至先前穩定版本,直到可以部署新版本為止。
部署:環境
參考架構會針對基礎結構使用兩種類型的環境:
短期 - E2E 驗證管線可用來部署短期環境。 短期環境用於開發人員的純驗證或偵錯環境。 您可以從分支建立
feature/*
驗證環境,並接受測試,然後在所有測試都成功時終結。 偵錯環境會以與驗證相同的方式進行部署,但不會立即終結。 這些環境不應該存在幾天以上,而且應該在合併功能分支的對應PR時刪除。永久 - 在永久環境中,有
integration (int)
和production (prod)
版本。 這些環境會持續運作,且不會終結。 環境會使用固定功能變數名稱,例如int.mission-critical.app
。 在參考架構的實際實作中,staging
應該新增 (預先支援) 環境。 環境staging
是用來使用與 (Blue/Green 部署) 相同的更新程式prod
來部署和驗證release
分支。整合 (int) - 版本
int
會每晚從 分支部署,main
且程式與prod
相同。 流量的切換速度比上一個發行單位快。 如同 在prod
中,在幾分鐘或幾小時內完成的程式int
,而不是在幾天內逐漸切換流量。 這種更快速的切換可確保更新的環境已於第二天早上就緒。 如果管線中的所有測試都成功,就會自動刪除舊的戳記。生產環境 (prod) - 版本
prod
只會從release/*
分支部署。 流量切換會使用更細微的步驟。 手動核准網關在每個步驟之間。 每個版本都會建立新的區域戳記,並將新的應用程式版本部署到戳記。 程式中不會觸及現有的戳記。 最重要的考慮prod
是,它應該是 「永遠開啟」。 應該不會發生任何計劃性或非計劃性的停機時間。 唯一的例外狀況是資料庫層的基礎變更。 可能需要計劃性維護期間。
部署:共用和專用資源
參考架構內的永久環境 (int
和 prod
) 有不同類型的資源,取決於它們是否與整個基礎結構共用,或專用於個別戳記。 資源可以專用於特定版本,並只存在於下一個發行單位接管之前。
發行單位
發行單位是每個特定發行版本的數個區域戳記。 戳記包含未與其他戳記共用的所有資源。 這些資源包括虛擬網路、Azure Kubernetes Service 叢集、事件中樞和 Azure 金鑰保存庫。 Azure Cosmos DB 和 ACR 會使用 Terraform 數據源進行設定。
全域共享資源
發行單位之間共用的所有資源都會定義在獨立的 Terraform 範本中。 這些資源包括 Front Door、Azure Cosmos DB、Container Registry (ACR),以及 Log Analytics 工作區和其他監視相關資源。 部署發行單位的第一個區域戳記之前,會先部署這些資源。 這些資源會在戳記的 Terraform 範本中參考。
Front Door
雖然 Front Door 是跨戳記的全域共享資源,但其設定與其他全域資源稍有不同。 部署新的戳記之後,必須先重新設定 Front Door。 必須重新設定 Front Door,才能逐漸將流量切換至新的戳記。
Front Door 的後端設定無法在 Terraform 範本中直接定義。 組態會插入 Terraform 變數。 變數值會在 Terraform 部署啟動之前建構。
Front Door 部署的個別元件組態定義為:
前端 - 工作階段親和性已設定為確保使用者在單一會話期間不會在不同的 UI 版本之間切換。
Origins - Front Door 已設定兩種類型的原始群組:
提供UI之靜態記憶體的來源群組。 此群組包含來自所有目前使用中發行單位的網站記憶體帳戶。 不同的權數可以指派給不同發行單位的來源,以逐漸將流量移至較新的單位。 發行單位的每個來源都應該指派相同的權數。
API 的來源群組,裝載於 AKS 上。 如果有不同 API 版本的發行單位,則每個發行單位都有 API 來源群組。 如果所有發行單位都提供相同的相容 API,所有來源都會新增至相同的群組,並指派不同的權數。
路由規則 - 路由規則 有兩種類型:
連結至 UI 記憶體來源群組之 UI 的路由規則。
來源目前支援之每個 API 的路由規則。 例如:
/api/1.0/*
和/api/2.0/*
。
如果發行引進新版本的後端 API,變更將會反映在部署為發行一部分的 UI 中。 特定版本的UI一律會呼叫特定版本的 API URL。 由UI版本提供服務的使用者將會自動使用個別的後端 API。 API 版本的不同實例需要特定的路由規則。 這些規則會連結至對應的原始群組。 如果未引進新的 API,則所有 API 相關路由規則都會連結至單一原始群組。 在此情況下,使用者是否從與 API 不同的版本提供 UI 並不重要。
部署:部署程式
藍色/綠色部署是部署程序的目標。 分支 release/*
的新版本會 prod
部署到環境中。 使用者流量會逐漸轉移到新版本的戳記。
在新版本的部署程式中,會使用 Terraform 部署新版本的基礎結構。 基礎結構部署管線的執行會從選取的發行分支部署新的基礎結構。 與基礎結構布建平行,容器映射會建置或匯入並推送至全域共用容器登錄 (ACR)。 當先前的進程完成時,應用程式會部署至戳記。 從實作的觀點來看,它是一個具有多個相依階段的管線。 您可以針對 Hotfix 部署重新執行相同的管線。
部署並驗證新版本單元之後,它會新增至 Front Door 以接收使用者流量。
切換/參數,可區分執行和不引進新 API 版本的版本,應針對 此版本進行規劃。 根據發行是否引進新的 API 版本,必須建立具有 API 後端的新原始群組。 或者,新的 API 後端可以新增至現有的原始來源群組。 新的UI記憶體帳戶會新增至對應的現有原始來源群組。 應根據所需的流量分割來設定新來源的權數。 必須建立與適當原始群組對應的新路由規則,如上所述。
作為新增新發行單位的一部分,新來源的權數應設定為所需的最小使用者流量。 如果未偵測到任何問題,應該在一段時間內將使用者流量增加至新的原始群組。 若要調整權數參數,應該以所需的值再次執行相同的部署步驟。
釋放單位卸除
在發行單位的部署管線中,不再需要發行單位之後,就會移除所有戳記的終結階段。 所有流量都會移至新版本。 此階段包含從 Front Door 移除發行單位參考。 這項移除對於在稍後啟用新版本的發行至關重要。 Front Door 必須指向單一發行單位,才能在未來準備下一個版本。
檢查清單
作為發行頻率的一部分,應該使用發行前和發行后檢查清單。 下列範例是應至少在任何檢查清單中的專案。
發行前檢查清單 - 開始發行之前,請先檢查下列各項:
請確定已在環境中成功部署分支的最新
main
狀態並進行測試int
。透過針對 分支的PR
main
更新變更記錄檔。從
main
分支建立release/
分支。
發行后檢查清單 - 在舊戳記終結之前,以及從 Front Door 移除其參考之前,請檢查:
叢集不再接收連入流量。
事件中樞和其他消息佇列不包含任何未處理的訊息。
部署:更新策略的限制和風險
此參考架構中所述的更新策略有一些應該提及的限制和風險:
較高的成本 - 發行更新時,許多基礎結構元件會在發行期間使用中兩次。
Front Door 複雜度 - Front Door 中的更新程序很複雜,可實作和維護。 執行具有零停機時間的有效藍/綠部署的能力取決於其正常運作。
小型變更耗時 - 更新程式會產生較長的發行程式,以進行小型變更。 使用上一節所述的 Hotfix 程式,可以部分減輕這項限制。
部署:應用程式數據轉送相容性考慮
更新策略可以支援多個版本的 API 和同時執行的工作元件。 由於 Azure Cosmos DB 會在兩個或多個版本之間共用,因此一個版本所變更的數據元素可能不一定符合取用它的 API 版本或背景工作角色。 API 層和背景工作角色必須實作向前相容性設計。 舊版 API 或背景工作元件會處理由更新的 API 或背景工作元件版本所插入的數據。 它會忽略它不瞭解的部分。
測試
參考架構包含測試實作內不同階段所使用的不同測試。
這些測試包括:
單元測試 - 這些測試會驗證應用程式的商業規則是否如預期般運作。 參考架構包含 Azure Pipelines 在每個容器建置之前自動執行的單元測試範例套件。 如果有任何測試失敗,管線將會停止。 建置和部署不會繼續。
負載測試 - 這些測試有助於評估指定工作負載或堆疊的容量、延展性和潛在瓶頸。 參考實作包含用戶負載產生器,可建立可用來模擬實際流量的綜合負載模式。 負載產生器也可以獨立於參考實作使用。
煙霧測試 - 這些測試會識別基礎結構和工作負載是否可用,並如預期般運作。 抽煙測試會在每個部署中執行。
UI 測試 - 這些測試會驗證使用者介面是否已部署並如預期般運作。 目前的實作只會在部署后擷取數個頁面的螢幕快照,而不需要任何實際測試。
失敗插入測試 - 這些測試可以自動化或手動執行。 架構中的自動化測試會將 Azure Chaos Studio 整合為部署管線的一部分。
如需詳細資訊,請參閱 在 Azure 上部署和測試任務關鍵性工作負載:持續驗證和測試
測試:架構
盡可能使用在線參考實作現有的測試功能和架構。
架構 | Test | 描述 |
---|---|---|
NUnit | 單位 | 此架構用於單元測試實作的 .NET Core 部分。 在容器組建之前,Azure Pipelines 會自動執行單元測試。 |
使用 Azure 負載測試的 JMeter | Load | Azure 負載測試 是用來執行 Apache JMeter 負載測試定義的受控服務。 |
Locust | Load | Locust 是以 Python 撰寫的開放原始碼負載測試架構。 |
劇作家 | UI 和煙霧 | Playwright 是一個 開放原始碼 Node.js 連結庫,可透過單一 API 將 Chromium、Firefox 和 WebKit 自動化。 Playwright 測試定義也可以獨立於參考實作使用。 |
Azure Chaos Studio | 失敗插入 | 參考實作會使用 Azure Chaos Studio 作為 E2E 驗證管線中的選擇性步驟,以插入失敗以進行復原驗證。 |
測試:失敗插入測試和混亂工程
分散式應用程式應該能夠復原服務和元件中斷。 失敗插入測試(也稱為錯誤插入或混亂工程)是將應用程式和服務導向真實世界壓力和失敗的做法。
復原是整個系統的屬性,插入錯誤有助於找出應用程式中的問題。 解決這些問題有助於驗證應用程式復原能力,以符合不可靠的條件、遺漏相依性和其他錯誤。
您可以針對基礎結構執行手動和自動測試,以找出實作中的錯誤和問題。
自動
參考架構會 整合 Azure Chaos Studio 來部署並執行一組 Azure Chaos Studio 實驗,以在戳記層級插入各種錯誤。 混亂實驗可以當作 E2E 部署管線的選擇性部分執行。 執行測試時,選擇性負載測試一律會以平行方式執行。 負載測試是用來在叢集上建立負載,以驗證插入錯誤的效果。
手動
手動失敗插入測試應在 E2E 驗證環境中完成。 此環境可確保完整的代表性測試,而不會有來自其他環境干擾的風險。 大部分使用測試產生的失敗,都可以直接在 Application Insights 實時計量 檢視中觀察到。 其餘失敗可在 [失敗] 檢視和對應的記錄數據表中使用。 其他失敗需要更深入的偵錯,例如使用 kubectl
來觀察 AKS 內的行為。
針對參考架構執行的失敗插入測試範例有兩個:
DNS 型失敗插入 - 可模擬多個問題的測試案例。 DNS 解析失敗,因為 DNS 伺服器或 Azure DNS 失敗。 DNS 型測試可協助模擬用戶端與服務之間的一般連線問題,例如當 BackgroundProcessor 無法連線到事件中樞時。
在單一主機案例中,您可以修改本機
hosts
檔案以覆寫 DNS 解析。 在具有 AKS 等多個動態伺服器的大型環境中,檔案hosts
不可行。 Azure 私用 DNS 區域可用來作為測試失敗案例的替代方案。Azure 事件中樞 和 Azure Cosmos DB 是參考實作中使用的兩個 Azure 服務,可用來插入 DNS 型失敗。 事件中樞 DNS 解析可以使用系結至其中一個戳記虛擬網路的 Azure 私用 DNS 區域來操作。 Azure Cosmos DB 是具有特定區域端點的全域復寫服務。 這些端點的 DNS 記錄操作可以模擬特定區域的失敗,並測試用戶端的故障轉移。
防火牆封鎖 - 大部分的 Azure 服務都支援以虛擬網路和/或 IP 位址為基礎的防火牆存取限制。 在參考基礎結構中,這些限制可用來限制對 Azure Cosmos DB 或事件中樞的存取。 簡單的程式是移除現有的 [允許 規則] 或新增新的 [封鎖 規則]。 此程式可以模擬防火牆設定錯誤或服務中斷。
參考實作中的下列範例服務可以使用防火牆測試進行測試:
服務 結果 金鑰保存庫 封鎖存取 金鑰保存庫 時,最直接的影響是新 Pod 無法繁衍。 在 Pod 啟動時擷取秘密的 金鑰保存庫 CSI 驅動程式無法執行其工作,並防止 Pod 啟動。 您可以使用 來觀察 kubectl describe po CatalogService-deploy-my-new-pod -n workload
對應的錯誤訊息。 雖然觀察到相同的錯誤訊息,但現有的 Pod 將會繼續運作。 錯誤訊息是由定期更新檢查秘密的結果所產生。 雖然未經測試,但假設執行部署無法在無法存取 金鑰保存庫 時運作。 管線執行中的 Terraform 和 Azure CLI 工作會要求 金鑰保存庫。事件中樞 當事件中樞的存取遭到封鎖時,CatalogService 和 HealthService 所傳送的新訊息將會失敗。 BackgroundProcess 擷取訊息的速度將會緩慢失敗,且總失敗會在幾分鐘內完成。 Azure Cosmos DB 拿掉虛擬網路的現有防火牆原則會導致 健全狀況服務 開始失敗,且延遲最小。 此程式只會模擬特定案例,整個 Azure Cosmos DB 中斷。 大部分在區域層級發生的失敗案例,應該透過將用戶端透明故障轉移至不同的 Azure Cosmos DB 區域來自動減輕。 先前所述的 DNS 型失敗插入測試是 Azure Cosmos DB 更有意義的測試。 容器登入 (ACR) 當 ACR 的存取遭到封鎖時,建立先前在 AKS 節點上提取和快取的新 Pod 將會繼續運作。 建立仍會因為 k8s 部署旗標 pullPolicy=IfNotPresent
而運作。 尚未提取並快取映像的節點,在區塊無法繁衍新的Pod,且立即失敗併發生ErrImagePull
錯誤。kubectl describe pod
會顯示對應的403 Forbidden
訊息。AKS 輸入負載平衡器 AKS 受控網路安全組 (NSG) 中 HTTP(S)(埠 80 和 443) 的輸入規則變更為 拒絕 會導致使用者或健康情況探查流量無法到達叢集。 此失敗的測試很難找出根本原因,其模擬為 Front Door 網路路徑與區域戳記之間的封鎖。 Front Door 會立即偵測到此失敗,並將戳記從旋轉中取出。