2023年2月2日 星期四

建立與使用Azure Storage Account(儲存體帳戶)

Azure Storage 是 Azure中主要的儲存體,擔任一切儲存的任務。Azure Storage本身具有四種不同的存儲形式,分別是:

  • Files
    可模擬SMB檔愛存取機制,類似雲端硬碟。
  • Blobs
    適合存取各種檔案,類如影片、圖檔、文件、logs…etc.
  • Tables
    NoSQL形式的資料儲存體。
  • Queue
    FIFO(先進先出的佇列儲存體)

典型的Storage durability形式有底下幾種:

  • LRS(本地備援儲存體) - 單一資料中心內備援三份
    圖片

  • ZRS(區域備援儲存體) - 將資料同步複寫至三個不同的區域。每個區域具備獨立的電源、冷卻和網路的不同實體位置
    圖片

  • GRS(異地備援儲存體 - 基於LRS,再將資料以非同步方式複製到位於數百英哩外的另一個位置,實現真正的異地備援。
    圖片

  • RA-GRS - 基於GRS加上可從異地支援讀取功能。

底下影片示範如何建立azure storage,並且建立一個 container,以及上傳檔案(blob)到container中。觀察影片中的操作,你會發現,當我們把 container的存取權限調整之後,blob檔案的URL就可以存取了,否則會變成找不到上傳的檔案:

Container 的 匿名存取層級有三種:

  • 無公用讀取權限︰只能讓有授權的用戶存取容器及其 Blob檔案。(此選項是預設值)
  • 僅對 Blob 有公用讀取權限:您可以透過匿名要求讀取容器內的 Blob,但您無法匿名使用容器資料。 匿名用戶無法得知容器中有哪些blob檔案。
  • 容器及其 Blob 的公用讀取存取權限:匿名要求可以讀取該容器中所有 Blob 檔案,也可以列出容器中有哪些blob檔案。

Shared Access Signature (SAS)

針對特定的 blob 檔案,可以產生具有SAS(簽章)的連結,可讓特定IP在特定時間內,存取該blob檔案。

產生SAS簽章的方式如下:

透過具有簽章的連結,可以在特定時間區間內,從特定的IP位置存取該blob檔案,是控制權限很好的方式。

參考資料:
https://learn.microsoft.com/zh-tw/azure/storage/common/storage-redundancy

2023年1月31日 星期二

使用Visual Studio開發支援容器化的 .net 網站

在 .net 開發技術中,若要產生支援 Linux Container 的 Image 非常容易,你只需要底下幾個步驟即可:

圖片

上圖中的 Image Registry,可以是私有的,也可以是公用的。目前坊間公用的 Registry 典型像是 Docker Hub,若你把Image上傳到Docker Hub,人人都可以下載使用。許多軟體和框架的開發商,都已經把自己所建立的SDK, Runtime上傳至Docker Hub:
圖片

私有的Registry則適合企業存放僅供內部使用的Image。開發人員可以透過軟體自建Private Image Registry,或是採用雲端現成的服務,像是Azure 上的ACR(Azure Container Registry)。

使用Docker File建立image

docker file是一份文件,透過docker file我們可以建置出docker image,你可以透過手動方式,以docker CLI來建立,若採用開發工具,在 Visual Studio 中,只需要將專案加入docker支援,即可自動建立 docker file:

圖片

Visual Studio自動建立出來的 docker file,會依照 .net 版本有所不同。例如,底下是 .net 5 的 docker file:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

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

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

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

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

建立的過程中,如果出現OS選擇,請選擇 linux:
圖片

上面的 docker file 被稱為 multi-stage build, 主要分成四個段落。有了docker file之後,我們就可以將我們開發出來的網站,建立出Image了。

使用Visual Studio建立並發佈Image

你可以在 Visual Studio中,直接透過方案總管來建置 Image 影像檔,完成後,該應用程式的image檔案會出現在 local 的 docker desktop工具中:

完成後,即可建立出image

注意,你的Visual Studio環境必須安裝有 docker desktop才行。

前面提到過,建立出來的Image,可以先發佈到 Image Registry,以便於未來將應用程式佈署到正式環境執行。

你可以透過 docker push 指令,把Image推送到Registry,不過我們有Visual Studio,可以更方便的完成這個動作。

你可以先在Azure Portal建立好私有(Privately)的Registry,建立方式如下:

接著,我們可以透過Visual Studio直接把Image建置好並發佈到Azure ACR,過程如下:

從ACR佈署到ACI

將建立好的Image放上 ACR,同時也有另一個好處,就是我們保留了每一個不同時期產出的網站,就好比把一個個的不同版本的artifacts封存,我們可以藉由ACR,進行每一個可運行的網站的版本控管。

除了隨時將最新版的部屬到正式機環境執行,我們也隨時可以進行roll-back退回上一版,甚至隨時找到任何一個需要的版本。

若您想將發佈到ACR上的image,實際上佈署到容器中運行,可以參可底下做法,下面展示將ACR發佈到ACI,成為一個實際可執行的網站:

2023年1月30日 星期一

使用VMSS實踐負載平衡

我們知道,可以透過串聯多台虛擬機,加上traffic routing,實踐負載平衡,讓你的應用程式的可用性得以提升。

不過,在Azure當中有比手動實踐更方面的選擇,那就是
VMSS( Virtual Machine Scale Set)。Azure VMSS可幫助我們建立一套內建負載平衡的 VM組。執行個體的數目可以視需要自動或手動增加、減少,可輕易地實現 Auto Scale或Fail-over。

建立VMSS

建立一組VMSS的方式很簡單,請參考底下影片:

建立過程中,我們分別透過底下PS指令,在兩台伺服器上建立IIS服務,並建立預設網頁:

Add-WindowsFeature Web-Server
Set-Content -Path "C:\inetpub\wwwroot\Default.htm" -Value "Hello world from host $($env:computername) !"

網頁會分別顯示機器名稱,從上面的有片中,你會看到,我們試著停掉其中一台機器,另一台VM會即時接手執行,自動實現 fail-over 之效果。

建立與使用 Azure VM

Azure 中的VM(虛擬機器),是雲端提供的典型IaaS(Infrastructure as a Service)服務模型之一。

你可以直接在Azure雲端建立一台Windows或Linux VM,並且透過portal管理該VM。使用RDP或SSH連上該VM。

建立虛擬機

建立VM所需要考量的因素大抵包含:

  • 等級(CPU, RAM, 運算能力…etc.)
  • 應碟大小與數量
  • 網路與對外IP
  • 可用性(是否支援負載平衡或容錯處理)

底下示範建立一台windows的VM:

從上面的影片你會發現,建立一台VM時,大多會同時建立多個資源,像是網路IP、虛擬硬碟…等,因此建議將其放在獨立的資源群組,以便於管理。

一般來說,建立windows VM時,我們會開啟3389 port,以便於透過RDP連入操作,但這是有潛在的資安風險的,如果你的VM有對外(網際網路)的公開IP,建議在設定完成之後,移除3389 port,以降低被網路上駭客攻擊的機會。(有需要連入再設定開啟即可)

底下展示如何透過RDP連入VM:

透過portal運行PowerShell指令

如果你需要設定VM或是安裝功能,其實也不一定需要直接透過RDP連入,針對windows VM,你可以從portal直接執行powerShell指令,例如,底下這樣的powerShell指令可以建立VM成為網站伺服器:

Add-WindowsFeature Web-Server
Set-Content -Path "C:\inetpub\wwwroot\Default.htm" -Value "Hello world from host $($env:computername) !"

你可以透過azure portal進行這個操作,完全不用連入VM:

設定防火牆

你可以透過Portal來管理防火牆,例如底下示範為VM的網站伺服器開放對外的80:

如此一來,VM就輕鬆成為Web伺服器了。

2023年1月28日 星期六

在VS Code開發環境建立Azure Function

在本地端開發環境建立 Azreu Function 相較在雲端直接建立並撰寫Azure Function,更便於測試(單步執行)和維護,也可以得到預先編譯的效果。

你可以使用VS Code來建立Azure Function。但須要在開發環境上安裝好底下套件,分別是:

圖片

如果你使用 .net 5以前的版本,建議搭配 3.0版的 core tools,如果你使用 .net 6以後的版本,建議搭配 4.0版以後的core tools,相關資訊如下:
https://learn.microsoft.com/zh-tw/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash

你可以從命令列,看到你的版本:
圖片

當你的VS Code安裝好Azure Functions套件,可以透過VS Code直接開發,完成後直接佈署到雲端運行。

底下展示如何在VS Code中完成這個動作。

2023年1月27日 星期五

建立與使用Azure Functions

Azure Functions 是微軟所提供的雲端 Server-less 服務,可讓開發人員在 Azure 上撰寫簡短的程式碼(functions)。以便於來執行例行性的工作,例如:

  • 固定時間執行特定動作。
  • 每當OOO發生的時候,執行XXX動作。

Azure Functions 之所以稱為 server-less functions,意思是,可讓您在不需要額外建置、管理伺服器或底層架構的情況下,直接執行程式碼(functions)。您只需要專注於寫出正確的程式碼,Azure 會負責在背景中執行,同時讓您透過 azure portal 來管理和備份程式碼。

舉例來說

舉例來說,過去我曾幫用戶建立一個解決方案,每當用戶把圖檔或影片上傳到 azure blob(儲存體)之後,就自動呼叫Azure cognitive services,辨識影像圖片中的人臉,並且將結果紀錄在資料庫中,以便於後續可以關鍵字搜尋。

這整個機制,我們就可以透過 Azure Functions 來完成。

底下這個MS官方的影片,很清楚地介紹使用Azure function的好處:

你可以把 Azure Functions 想像成,有人幫你建立好了伺服器、網站、準備好了SDK、runtime,然後你只需要把執行特定功能的 WebAPI/Web Services程式碼寫好放上去,就可以開始運行了。

撰寫方式

具體 Azure Functions 支援的語言包含:

  • C#
  • Java/JavaScript
  • Python
  • TypeScript
  • PowerShell Script
  • …越來越多…

開發人員可以透過 Azure Portal來撰寫,或是透過開發工具(像是Visual Studio, VS Code)撰寫完之後,佈署上雲端來執行。

在雲端建立第一個Function

要使用 Azure Function,得先建立 Function App服務,中文版稱為"函數應用程式"。

您可參考底下影片建立一個 Function App:

接著,透過 azure portal ,你可以直接建立一個 Function 並且在其中撰寫程式碼。底下這段影片,展示如何建立一個Function App,並且監聽 azure storage中的 blob container,若其中有檔案上傳,則取得檔案名稱,填入queue:

影片13秒的地方,你會看到連結 blob trigger,意味著,可以透過blob檔案上傳,觸發這個function,這是input binding。

影片42秒,你看到的是我們透過binding,連結一個已經建立好的名為container1的容器,當用戶把檔案上傳到這個容器中,就會觸發funcion。

59秒處,是建立這個容器的storage account連結。
1’42秒開始,是建立輸出的queue,當用戶有檔案上傳,該function就會寫入一則記錄到queue當中。

1:35秒處,請注意建立的queue名稱,該名稱必須和待會綁定於azure function中的名稱相同。

最後, 2:14秒開始,則是撰寫該function的程式碼,請看程式碼本身,你會發現blob和queue相關資訊,都會從function 參數傳入,然後我們可以透過程式碼來控制其中的互動(底下的例子是把上傳的檔案名稱寫入queue):

public static void Run(Stream myBlob, string name, ICollector<string> outputQueueItem, ILogger log)
{
  log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
  outputQueueItem.Add("Name passed to the function: " + name);
}

實務上當然不是那麼簡單,這只是一個範例,看起來無用,但這個範例,展示了 Azure Function 可以連結到外部的 blob, queue…等儲存體,而不需要額外撰寫程式碼去維護連線。

本質上這是一個binding(繫結、綁定)機制,透過input binding與output binding就可以讓azure function以設定的方式,來連結外部資源,或是被特定事件(例如檔案上傳到blob)來觸發。

影片的3:11秒開始,則是展示上傳檔案後,會成功的有log,並且在queue當中留下一筆紀錄。

總的來說,使用azure function 帶來很多好處:

  1. 無須額外撰寫程式碼管理外部資源的連線,便於維護或管理。
  2. 透過binding設定即可將外部資訊以參入方式注入函式中,便於程式碼撰寫。
  3. 無須管理伺服器本身的架構或是runtime、SDK,這些都由雲端服務廠商來負責維護,開發人員可以專注在function 的開發上。

2023年1月25日 星期三

Azure Web App的應用程式環境變數與組態

寫程式很少沒有環境變數的,不知道你把環境變數儲存在哪裡?
怎樣的保存和使用,才是安全有效率的呢?

過去 .net 開發人員,大多把環境變屬保存在 web.config 中,以XML的形式存在:

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
  <add key="MyCustomSetting" value="MyCustomSettingValue" />
</appSettings>

而 .net core之後的時代,則大多保存在 appSettings.json檔案中,以JSON形式存在:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "myConfig": {
    "para1": "value3",
    "para2": "value2"
  }
}

在開發階段,我們的應用程式,可以直接consume(使用)位於local的XML/Json設定檔,也就是上述的web.config和appSettings.json,但這樣有一個小缺點,每次將應用程式佈署到不同環境後(QA/Staging/Production),都要手動修改設定檔。

如今,將應用程式佈署到雲端上的Azure App Services之後,有一個更方便的配置管理後台,就是下圖中的『組態』:

圖片

你可以透過組態來新增一組環境變數,替代(overwrite)原先在程式碼檔案中的設定:
圖片

我們看底下這個範例,如果你有興趣,可以透過底下CLI指令從筆者的github網站下載此範例做練習,並透過VS Code開啟該資料夾:

git clone https://github.com/isdaviddong/AZ204-DemoAppSettings.git
cd .\AZ204-DemoAppSettings\
code .

程式碼中,有一個設定檔,其中有一組MyCondig設定:
圖片

你會發現分別有 para1, para2 兩個參數。

如果你運行這個程式,會發現 privacy 頁面中,使用到了MyConfig.para1這個參數:

圖片

檢視這個頁面的程式碼,會發現:
圖片
後端程式碼.cshtml.cs中,21行取得了appSettings.json中環境變數,並保留在para1變數中,接著透過.cshtml頁面上的razor指令將其顯示出來:
圖片

如此一來,呈現出的上面的結果了:
圖片

順帶一提,取得環境變數的部分程式碼採用了 .net core 框架中的DI(dependency injection)技術,這邊暫且表過不提。

重點在於,我們接下來要將此應用程式佈署到雲端,然後佈署上雲之後,程式會改採用雲端後台所設定的環境變數值,取代剛才地端的環境變數 “value 3”。

我們來看具體作法。

你從底下影片可以看到,我們在雲端新增了 MyConfig:para1 環境變數,並指定值為 helloworld。接著將應用程式從地端佈署到雲端,你會發現上了雲端之後,應用程式自動改抓雲端的設定值:

透過這樣的方式,管理環境變數變得既安全又便利。

熱門文章