截至目前為止,在雲端開台小 VM 裝 Docker 跑 ASP.NET Core 網站對我已不是難事,甚至寫了懶人安裝腳本一氣喝成。不過我心裡明白,開 VM 跑 Linux 裝 Docker 屬於 IaaS,跟在公司內架主機概念差不多,技術門檻不高,但 OS 需要自己管理設定、定期更新,容量不足時需要自己新裝 VM 加入,並不算完整真正發揮雲端的優勢。

要升級到 PaaS 才能徹底避免底層作業系統管理成本,不用擔心主機或網路問題導致批次作業或服務掛點;而當系統負載過重過低時,可快速手動或自動調整服務主機等級(Scale Up 擴大)或數量(Scale Out 擴增),這才是自己養機器所無法達成的境界。(註:自己架 Kubernetes 也可實現主機數量彈性增減,但技術門檻較高且有 VM 及 OS 維運成本)

微軟有張決策圖列舉了可用的 Azure 雲端服務:


圖片來源:選擇 Azure 計算服務

Azure VM 前面已經介紹夠多了,這次的重點放在 PaaS 方面的服務:

  • Azure App Service
    裝載 Web 應用程式、行動裝置應用程式後端、RESTful API 或自動化商務程序的受控服務。
  • Azure 容器執行個體
    不需建 VM 裝 Docker,直接在 Azure 建 Docker Registry 及執行容器。
  • Azure Functions
    受控函式即服務 (FaaS) 服務。使用 C#、Java、JavaScript、PowerShell、Python 建立程式碼區塊,以無伺服器概念方式執行。
  • Azure Batch
    用於執行大規模的平行和高效能運算 (HPC) 應用程式,例如財務風險模型、3D 影像分析處理、基因序列分析、OCR... 等。
  • Azure Service Fabric
    將微服務與容器組成叢集(Cluster),提供負載平衡(對外單一 IP,後面有多個節點分擔處理需求)並簡化管理。
  • Azure Kubernetes Service (AKS)
    用於執行容器化應用程式的受控 Kubernetes 服務,Kubernetes 難裝難養,拿 Azure 裝好的來玩,花錢省事。
  • Azure Container Apps
    建置在 Kubernetes 上的受控服務,可簡化在無伺服器環境中部署容器化應用程式的作業。
  • Azure Red Hat OpenShift
    完全受控的 OpenShift 叢集,可用於使用 Kubernetes 在生產環境中執行容器。(OpenShift 是 RedHat 所開發支援 Kubernetes 的專屬平台)
  • Azure Spring Apps
    專為裝載 Spring Boot 應用程式而設計並優化的受控服務。(Spring Boot 是 Java 的框架)

東西太多了,這篇只先看 Azure App Service,練習建一個展示用的服務,設定當 CPU 忙不過來時自動增加網站數量。

微軟的Azure App Service 官方文件相當詳細完整,理論上不怎麼需要其他參考。管理與部署操作我優先考慮 CLI/PowerShell,這些操作都能用網頁介面完成,甚至 Visual Studio/VSCode 還支援直接從開發機部署到 Azure。但應用在生產環境,不太可能從開發機部署,而指令操作較易標準化及自動化,因此若作業會頻繁執行或需分工及批次處理(例如: 部署上線)我會以指令優先,較複雜且不會反覆執行的初始設定(例如:新建一個 App Service、設定規則)則使用網頁介面。

Azure App Service 支援 .NET、.NET Core、Java、Ruby、Node.js、PHP、Python,提供 Windows 及 Linux 兩種環境,並能整合 DevOps 與 Azure DevOps (前身為 TFS)、GitHub、Docker Hub 進行 CI/CD 整合(例如:改完程式推上 Git 伺服器後自動測試並部署)。先從簡單的開始,建一個 ASP.NET Core 專案,部署為 Azure App Service,設定 CPU 吃緊時自動擴充到最多五台。為了方便模擬,我寫了一個超吃 CPU 的 WebAPI (不停頓跑迴圈到指定秒數),實測呼叫它讓 Azure 自動擴充主機數量。

首先,在 Azure Portal 管理介面新建一個 App Service (跑網站用的 App Service 中文資源名稱為「Web 應用程式」),選擇執行個體的名稱、發佈形式(代碼、Docker 容器或靜態 Web 應用程式)、執行階段堆疊(Runtime Stack,.NET/Go/Java/Node/PHP/Python/Ruby)、 OS (Linux/Windows)、地區。「定價方案」決定 App Service 要在什麼等級的虛擬機器運行,跟選擇 VM 大小一樣,可依 Web 應用程式所需的 CPU、RAM、Disk 資源及口袋深度挑選,免費方案一天可用 60 CPU 分鐘、1GB RAM + 1GB 儲存空間,可用於驗證測試;再上來最小的 B1 有 1 核 CPU + 1.75GB RAM + 10 GB 儲存空間,一個月費用約新台幣 381 元,跑中小型網站足矣;再上一級 B2 為 2 核/3.5GB RAM/10GB 儲存,每月 762 元。每個 App Service 對外會有一個虛擬 IP,背後是一個到多個執行個體(每個執行個體相當於一台虛擬主機)平均消化流入的 HTTP 請求,當預期或發現大量請求湧入網站扛不住時,可透過管理介面或 CLI/PowerShell 指令瞬間增加執行個體數量(等同多加幾台機器分擔流量),充分展現身為雲端服務的威力。(延伸閱讀:David 老師這篇 Azure Web App的Scale Up、Scale Oute功能有詳細介紹及操作影片) 如果覺得靠「工人智慧」隨時盯著流量及 CPU 調主機數量太辛苦,Azure App Service 也能依流量需求自動增加或減少虛擬機器執行個體數目,但這要標準型 S 系列以上的主機才支援,最小的 S1 1 核/1.75GB RAM/50GB 儲存空間每月 2131 元。(詳細定價表可以參考官方網頁 (有分 Linux/Windows 價格不同))

App Service 可以整合 GitHub,實現推送後自動建置、測試並部署,走向更專業的 DevOps,這塊將來再玩。

App Service 開好了,再來要寫個程式放上去跑。我建了一個 Minimal API 專案,裡面有個 POST /chase-tail API 負責空跑迴圈指定秒數吃光 CPU:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => Results.Content(
@"<html>
<head><meta charset=""utf-8""></head>
<body>
    <select id=secs>
        <option value=3>3 秒</option>
        <option value=5>5 秒</option>
        <option value=10>10 秒</option>
        <option value=60>1 分鐘</option>        
    </select>
    <button onclick='run()'>瞎忙</button>
    <ul id=msgs>
    </ul>
    <script>
    function addMsg(msg) {
        var li = document.createElement('li');
        li.innerText = msg;
        document.getElementById('msgs').appendChild(li);
    }
    let i = 0;
    function run() {
        let j = i++;
        addMsg(`[${j}]開始瞎忙...`);
        fetch('/chase-tail/' + document.getElementById('secs').value, { method: 'POST' })
            .then(r => r.text())
            .then(t => addMsg(`[${j}]` + t));
    }
    </script>
</body>
</html>", 
"text/html"));

app.MapPost("/chase-tail/{secs}", (int secs) => {
    var endTime = DateTime.Now.AddSeconds(secs);
    while (DateTime.Now < endTime) { }
    return $"瞎忙 {secs} 秒完成";
});

app.Run();

在本機實測確認有衝高 CPU 的效果:

接著,參考文件,用 PowerShell 指令將檔案送上 Azure: (補充:安裝 Az PowerShell)

這樣網站就部署完成了!

接下來,我設定了 CPU 超過 70% 維持五分鐘執行個體加一,低於 30% 維持十分鐘減一的自動擴增及縮減規則:

調整規模規可指定要觀察的計量統計資料(CPU、記憶體、Disk IO、網路傳輸量),設定觸發條件、持續時間(至少五分鐘),以及冷靜期(增減後等待一段時間暫不調整,等待計量穩定):

設好規則,連上網站搞一波瞎忙,把 CPU 衝上 100%,持續一段時間:

成功將 App Service 方案的執行個體數目增加到 5 個的上限:

由 App Service 方案活動記錄可觀察到執行個體數量增加與減少的過程,我的規則是大於 70% 維持五分鐘加一,冷靜期兩分鐘。實際觀察當 CPU 一直 100%,大約三分鐘會增加一台,直到上限五台。負載消失後十分鐘,每三分鐘減少一台,最後降回一台。

【結論】

在本次演練中,我們將一個 ASP.NET Core 測試網站部署成 Azure App Service,並設定自動擴增及縮減規則,遇到 CPU 負載過重時自動增加執行個體數量(可想像成網站主機數量)分擔消化需求,負載降低時自動減少以節省費用,體驗了真正的雲端威力,經驗值加五點。

Practice to deploy ASP.NET Core to Azure App Service and test the auto scale-out feature.


Comments

Be the first to post a comment

Post a comment