只有累積,沒有奇蹟

2021年7月1日 星期四

[Azure] 打包 ASP.NET Core 應用程式到 Docker Hub 並發佈到 Azure

前言
這幾年隨著容器化技術逐漸成熟,在技術研討會與社群上可以聽到越來越多公司架構朝容器與微服務邁進,微軟也很佛心的提供 .NET 微服務 : 容器化應用程式架構指南 電子書,作為有興趣往微服務的.NET 開發人員參考。除了提供電子書之外在 Azure 提供 Web App for Container 服務,可以輕鬆的將封裝好的 Docker image 檔案部署到 Azure 上,這篇文章是參考 Microsoft Azure 官網影片的筆記,介紹如何透過 Visual Studio 2019 將 ASP.NET Core 應用程式封裝成 Linux image 檔案 push 到 Docker Hub,再透過 Web App for Container 服務部署至 Azure 雲端上使用若有問題或是錯誤的地方歡迎各方高手大大一起討論或給予指導

前置作業
一開始有提到要將 ASP.NET Core 應用程式包成 Docker Image 檔案並部署到 Azure,在這之中分別會用到 Docker for Windows 工具與 Visual Studio Azure development,因此在開始之前必須先確認這兩項是否有安裝成功,才可以順利進行後續的步驟

安裝 Docker For Windows
公司筆電使用的是 Windows 作業系統,在 Windows 上要使用 Docker 必須安裝 Docker Desktop for Windows 應用程式,安裝完畢之後還需要開啟 Windows 中的 Container & Hyper-V,安裝方式與細節可以參考小弟之前寫的 Docker for windows 初體驗 文章介紹,安裝傳送門 : Docker Desktop for Windows

安裝 Visual Studio Component - Azure development 
我們會將應用程式封裝成 Docker Image,接著將打包好的 image 檔案 publish 到 Azure 雲端上,這些流程都需要工具進行輔助才可以達到,在 Visual Studio 中有提供開發雲端應用程式的  Azure SDK ,與建立 Docker 容器化的工具,但這些選項在安裝 Visual Studio 時預設是不會安裝的,因此我們需要透過  Visual Studio Installer  進行安裝所需工具,安裝步驟如下
Step 1 : 開始 > 輸入Visual Studio Installer > 選擇 "修改
Step 2 : Workload 工作負載 > Azure 開發 選項打勾 > 確定後按右下角修改按鈕
接著就會進行 Azure SDK 安裝,如果不確定之前是否有安裝過 Azure SDK,可以輸入下列指令確認
  1. Get-Module -ListAvailable | Where-Object -Property Name -Like "*Azure*"
備註 : Azure Development 正確安裝元件清單可以參考 MSDN 介紹 : Visual Studio Community component directory - Azure Development

建立應用程式 
第一個步驟是建立需要上傳的範例應用程式,開啟 Visual Studio 2019 新增 DockerTest 專案,並選擇 ASP.NET Core MVC 模板應用程式
為了方便驗證應用程式,我在 ASP.NET Core 應用程式開啟首頁 index.cshtml 中 Welcome 改為 Welcome Marcus
  1. <div class="text-center">
  2. <h1 class="display-4">Welcome Marcus</h1>
  3. <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
  4. </div>
接著要新增  dockerfile  檔案,Dockerfile 是一個文字檔案,開發者可以將要 build image 所有的命令指令放在 dockerfile 檔案中,最後在透過 Docker Build 指令來建立 image 檔案,在 Visual Studio 中可以透過下列步驟新增專案所屬的 Docker File
Add Dockerfile : 專案點選右鍵 > Add > Docker Support  
在建立 Docker Image 前必須先定義應用程式要在哪個環境下執行,有分為 Linux 以及 Windows 兩種也就是要執行環境的OS,建立前會跳出視窗詢問要建立哪一種 image,這裡我希望在 Linux 上執行 
建立完畢後會在專案底下建立檔名為 dockerfile 檔案,可以打開建立好的 dockerfile 如果有要添加可以在其中做調整,預設的 dockerfile 內容如下 (如果上一步 Target OS 選擇 Windows 的話,OS就會看到 nanoserver-1903 )是 windows
  1. FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
  2. WORKDIR /app
  3. EXPOSE 80
  4. EXPOSE 443
  5.  
  6. FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
  7. WORKDIR /src
  8. COPY ["DockerTest/DockerTest.csproj", "DockerTest/"]
  9. RUN dotnet restore "DockerTest/DockerTest.csproj"
  10. COPY . .
  11. WORKDIR "/src/DockerTest"
  12. RUN dotnet build "DockerTest.csproj" -c Release -o /app
  13.  
  14. FROM build AS publish
  15. RUN dotnet publish "DockerTest.csproj" -c Release -o /app
  16.  
  17. FROM base AS final
  18. WORKDIR /app
  19. COPY --from=publish /app .
  20. ENTRYPOINT ["dotnet", "DockerTest.dll"]

Docker Hub
新增完要 Demo 的 ASP.NET Core 應用程式與建立好打包 image 的指令 (Dockerfile),下一步就是要透過 Visual Studio 提供的 Publish 功能將應用程式包成 image 並發佈到指定的 Docker Hub 上,步驟如下
Step 1 : 專案按右鍵 > 選擇 Publish  
Step 2 : 選擇 Container Registry > Docker Hub 打勾 
Step 3 : 會發佈到個人的 Docker repositoty,因此會要求你輸入 Docker 使用者名稱,密碼可選擇不要輸入
Step 4 : 按下存檔之後會在專案 Properties 底下新增   PublishProifles  資料夾與設定檔,將剛剛畫面所設定的資訊都透過 XML 方式存放在該資料夾中
Step 5 : 發布設定檔所對應到的資訊會顯示在發布畫面上,發佈到 Docker Hub 預設會加上  tag : latest ,如果公司或團隊有不同一樣的 tag 規範時在此步驟可以修改,沒問題就可以按下 Publish 按鈕
Step 6 : 進行 Publish 時候會在 Visual Studio Output 視窗顯示發布時的資訊與內容,內容描述整個 publish 到 Docker Hub 的過程,包含專案的建置、Docker Build 執行 Dockerfile 中的指令以及建置 Docker Image 成功之後放到 Docker Hub,其中比較值得介紹的是建置 Docker Build 的過程,Docker Image 是由很多不同的 Layer 所組成,執行 Docker Build 建置的過程中會依據所定義的內容 (指令) 建立所需要的 layer,每一層 Layer 都有屬於自己的 id,整個建置完成才算是完整的 Docker Image,示意圖如下
圖片來源 : Docker Images and How to work with them 

如果是第一次執行 Docker Build 會執行較久的時間,是因為之前沒有下載過相關的映像檔,舉例來說如果建立 Dockerfile 時指定 Windows 時,會需要下載 windows 的 nanoserver 1809 映像檔到本機環境中,如果下一次在重新建立時會發現建置 Docker Image 過程會抓取 cache 內容,透過此機制不用每次都重新下載會加速建置 Docker Image 的速度。透過以上說明,我們再回到主題來觀察 DockerTest 範例專案中在 publish 中 output 的內容就清楚許多
  1. Step 1/19 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
  2. ---> 3ee0429b27ad
  3. Step 2/19 : WORKDIR /app
  4. ---> Using cache
  5. ---> 129068167155
  6. Step 3/19 : EXPOSE 80
  7. ---> Using cache
  8. ---> 00e73d24a9b3
  9. ...省略
  10. Step 19/19 : LABEL com.microsoft.visual-studio.project-name=DockerTest
  11. ---> Using cache
  12. ---> ab2fcad3d592
  13. ---> 6a61a9666c82
  14. Successfully built 6a61a9666c82
  15. Successfully tagged dockertest:latest
Publish 完成之後開啟所設定的 Docker Hub 網址,即可以看到剛剛發布的 DockerTest 已成功

Web App for Container
接下來是透過 Azure 的 Web App for Container 服務,將稍早上傳到 Docker hub 的 image 印象檔部署到 Azure 中的應用程式,首先在上方的 Search 區塊輸入  Web App for Container  關鍵字,點選該服務
新增一個新的 Web App for Container 時需要輸入以下資訊
  • 應用程式名稱 : 這裡輸入範例的專案名稱 dockerlabtest
  • Container 需要執行的 OS : 建立 Docker Image 所選擇的執行環境
  • 設定容器 : 稍早使用 Visual Studio 上傳到 docker hub,因此在右邊區塊選擇 Docker Hub 頁籤,下方黃色圈起的區塊輸入 Docker Image 的位置,如果忘記位置可以參考 Docker Hub Repo 頁面右下方  docker pull username/dockertest ,輸入完畢之後按下套用。
  • 以上資料都輸入完畢後按下建立按鈕,Azure 就會開始進行建立應用程的動作,並在畫面上會顯示部署時的內容資訊,如果想了解部署時的細節內容也可以透過左邊區塊的按鈕下載
    將 Docker Image 部署至 Azure 之後,可透過下列標註黃色區塊開啟剛剛建立的網站
    點選之後開啟網頁可以看到一開始修改的文字 Welcome Marcus 顯示成功 !!!!
    當然,Azure 也貼心的提供監控應用程式的 dashboard,可以觀看應用程式的錯誤及 Application network in/out 相關即時資訊,方便開發者或是運維團隊監控應用程式的服務是否正常
    成功將 .NET Core 應用程式打包成 Docker Image 並部署至 Azure 上,大功告成,打完收工 !!!


    感想
    隔了 7 年的時間在重新使用 Azure 服務,初步覺得除了介面操作上比之前更加好用之外,在部署應用程式之後的監控服務服務更加完善,一開始也有提到這篇文章是照著 Microsoft Azure 官網影片 的筆記,五分鐘的影片看似很簡單但實際操作之後也隱藏了一些細節,還有影片介紹的是部署至 Windows 我這裡改介紹 Linux OS,花了一點時間了解並實作出來之後,決定將過程分享此文章(我承認標題真的很難下 XDDD),並針對自己覺得重要的部分加上說明,如果對於 Azure 提供的 Web App for Container 服務有興趣的朋友歡迎參考與一起討論,也希望這篇介紹可以有幫助到有需要的朋友,謝謝

    參考
    How to deploy ASP.NET application to Docker Hub and Azure | Azure Tips and Tricks

    Related Posts:

    • [C#] Array陣列中加入元素 前言 此篇文章是要記錄 如何在Array陣列中加入元素 ( 之前是 如何移除 Array 陣列中指定的元素 ) 查了一下MSDN Array 陣列成員 不提供add的方法加入新的元素 但仔細看了一下成員中的方法,可以發現有個公用方法 Array.Resize 方法說明:將陣列的大小變更為指定之新大小 雖然沒有add方法,但也可以用 array.resize… Read More
    • [.NET] ASP.NET 狀態管理(State Management):ViewState Web應用程式是沒有狀態(Stateless)的,從前面介紹的文章(Application、Page Life-Cycle)可以了解到,每次用戶端發送請求(Request)到伺服器端時,都會建立Web網頁類別的新執行個體。由於每個請求都是新的個體,這也代表每次來回存取時,網頁及控制項的資訊將會遺失。例如,根據預設,當使用者在網頁textbox控制項輸入「Hello world」,按下按鈕送出後,這項資訊就會傳送到伺服器。但伺服器在回傳(Res… Read More
    • [.NET] 字串加密 MD5、SHA1 常在開發中遇到需要將特定資料加密的動作,在儲存到資料庫中(比如說網站用戶的密碼加密後存到資料庫中,用戶在登入時,在把用戶輸入的密碼進行加密,再與資料庫密碼欄位比較是否一致)在.NET Framework中,可以透過 System.Security.Cryptography 命名空間來產生加密演算法的金鑰(註一),在用雜湊值(Hash Value)的加密方式達到目的,雜湊演算法將任意長度的二進位值對應到固定長度較小的二進位值,稱為雜湊值 (Ha… Read More
    • [C#] 刪除 Array 陣列中指定的元素 前言 此文章紀錄如何移除 Array 陣列中指定的元素! 想要移除 Array 陣列中某項特定的元素,但發現因 Array 類別中,沒有類似 Remove 的方法可使用  QAQ 如下圖所示: 查了一下Array 成員,發現公用方法中並沒有 Remove 方法,但在.NET Framework 2.0 中 Array 類別有實做 IList、ICollection 和 IEnumerable&… Read More
    • [IIS] IIS 站台服務異常中止 - HttpEvent 問題 今天同事反應測試主機 IIS Server 無法使用,進到 QA 主機後發現所有的 IIS 服務都已停止,第一直覺就是到事件檢視器查看是否有異常的 Log 資訊,發現事件檢視器紀錄其中來源  HttpEvent  嫌疑重大,以下就針對解決此問題的方式做說明,若有問題歡迎提出一起討論或是給予指導。 解決方案 由於公司測試機對外預設都是以 80 port 為主,無故發生異常是蠻很奇怪,過去… Read More

    0 意見:

    張貼留言

    Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com