本教學課程說明如何使用 Azure Pipelines、Cloud Run 和 Container Registry,為 ASP.NET MVC Core 網頁應用程式建立持續整合/持續部署 (CI/CD) 管道。
CI/CD 管道使用兩個 Google Cloud 專案,一個用於開發環境,另一個用於實際工作環境,如下圖所示。
在管道的一開始,開發人員會將變更推送至範例程式碼基底。這個動作會觸發管道建立版本,並將版本部署至開發叢集中的 Cloud Run。接著,版本管理員會升級版本,將版本部署至正式版專案。
本教學課程適用於開發人員和 DevOps 工程師。本文假設您具備 .NET、Azure Pipelines、Cloud Run 和 git 的基礎知識。如要完成本教學課程,您必須具備 Azure DevOps 帳戶的管理員存取權。
目標
- 將 Artifact Registry 連結至 Azure Pipelines,以發布 Docker 映像檔。
- 準備 .NET 範例應用程式,以部署至 Cloud Run。
- 設定 Azure Pipelines 與 Google Cloud之間的驗證。
- 使用 Azure Pipelines 版本管理來自動化調度管理 Cloud Run 部署。
費用
在本文件中,您會使用下列 Google Cloud的計費元件:
您可以使用 Pricing Calculator,根據預測用量估算費用。
完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」一節。
如要瞭解使用 Azure DevOps 可能需要支付的任何費用,請參閱 Azure DevOps 定價頁面。
事前準備
在本教學課程中,您會使用兩個不同的專案,一個用於開發,另一個用於實際工作。使用不同的專案,您就能在將版本部署至實際工作環境前進行測試,也能個別管理身分與存取權管理 (IAM) 角色和權限。
- 建立 Google Cloud 開發專案。本教學課程將此專案稱為「開發專案」。
- 建立用於實際工作環境的 Google Cloud 專案。本教學課程將這個專案稱為「正式環境專案」。
-
Verify that billing is enabled for your Google Cloud project.
- 確認您有 Azure DevOps 帳戶並具備其管理權限。如果您還沒有 Azure DevOps 帳戶,可以在 Azure DevOps 首頁進行註冊。
建立 Azure DevOps 專案
您可使用 Azure DevOps 來管理原始碼、執行建構與測試,以及自動化調度管理 Cloud Run 部署作業。首先,請在您的 Azure DevOps 帳戶中建立專案。
- 前往 Azure DevOps 首頁 (https://dev.azure.com/YOUR_AZURE_DEVOPS_ACCOUNT_NAME)。
- 按一下「New Project」。
- 輸入專案名稱,例如
CloudDemo。 - 將「Visibility」設為「Private」,然後按一下 [Create project]。
- 建立專案之後,請在左側的選單中按一下「Repos」。
- 按一下「Import」,從 GitHub 建立
dotnet-docs-samples存放區的分支,然後設定下列值:- 「存放區類型」:
Git - 「Clone URL」:
https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
- 「存放區類型」:
按一下「匯入」。
匯入程序完成後,您會看到
dotnet-docs-samples存放區的原始碼。
將 Azure Pipelines 連結至 Artifact Registry
如要為 CloudDemo 應用程式設定持續整合,必須先將 Azure Pipelines 連線至 Artifact Registry。這個連線可讓 Azure Pipelines 將容器映像檔發布至 Artifact Registry。
設定服務帳戶以發布映像檔
在正式版專案中建立Google Cloud 服務帳戶:
- 在 Google Cloud 控制台中,切換至正式版專案。
-
In the Google Cloud console, activate Cloud Shell.
初始化下列環境變數:
DEV_PROJECT_ID=DEV_PROJECT_ID PROD_PROJECT_ID=PROD_PROJECT_ID
更改下列內容:
DEV_PROJECT_ID:開發專案的專案 IDPROD_PROJECT_ID:生產專案的專案 ID
在正式版專案中啟用 Artifact Registry API:
gcloud services enable artifactregistry.googleapis.com \ --project=$PROD_PROJECT_ID建立 Artifact Registry 存放區,用於儲存 Docker 映像檔:
gcloud artifacts repositories create docker \ --project=$PROD_PROJECT_ID \ --repository-format=docker \ --location REGION將
REGION替換為 Artifact Registry 存放區的區域,例如us-central1。建立 Azure Pipelines 用於發布 Docker 映像檔的服務帳戶:
gcloud iam service-accounts create azure-pipelines-publisher \ --display-name="Azure Pipelines Publisher" \ --project=$PROD_PROJECT_ID將 Artifact Registry 寫入者角色 (
roles/artifactregistry.writer) 授予服務帳戶,允許 Azure Pipelines 推送至 Artifact Registry:AZURE_PIPELINES_PUBLISHER=azure-pipelines-publisher@$PROD_PROJECT_ID.iam.gserviceaccount.com gcloud projects add-iam-policy-binding $PROD_PROJECT_ID \ --member serviceAccount:$AZURE_PIPELINES_PUBLISHER \ --role roles/artifactregistry.writer \ --project=$PROD_PROJECT_ID產生服務帳戶金鑰:
gcloud iam service-accounts keys create azure-pipelines-publisher.json \ --iam-account $AZURE_PIPELINES_PUBLISHER \ --project=$PROD_PROJECT_ID tr -d '\n' < azure-pipelines-publisher.json > azure-pipelines-publisher-oneline.json查看服務帳戶金鑰檔案的內容:
echo $(<azure-pipelines-publisher-oneline.json)您會在下列其中一個步驟中用到服務帳戶金鑰。
- 在 Azure DevOps 選單中,選取「專案設定」,然後選取「管線」 >「服務連線」。
- 按一下「建立服務連線」。
- 從清單中選取「Docker Registry」,然後按一下「下一步」。
在對話方塊中,在下列欄位輸入這些值:
- 登記類型:其他
Docker 登錄檔:
https://REGION-docker.pkg.dev/PROD_PROJECT_ID/docker/更改下列內容:
REGION:Artifact Registry 存放區的區域PROD_PROJECT_ID:換成您的正式版專案名稱
「Docker ID」:
_json_key密碼:貼上
azure-pipelines-publisher-oneline.json的內容。服務連線名稱:
gcr-tutorial
按一下「儲存」建立連結。
- 使用 Visual Studio 或指令列
git用戶端複製新的 Git 存放區。 - 在存放區的根目錄中,建立名為
azure-pipelines.yml的檔案。 將下列程式碼複製到檔案中:
resources: - repo: self fetchDepth: 1 pool: vmImage: ubuntu-22.04 trigger: - master variables: TargetFramework: 'net6.0' BuildConfiguration: 'Release' DockerImageName: 'PROD_PROJECT_ID/docker/CloudDemo' steps: - task: DotNetCoreCLI@2 displayName: Publish inputs: projects: 'applications/clouddemo/netcore/CloudDemo.MvcCore.sln' publishWebProjects: false command: publish arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)' zipAfterPublish: false modifyOutputPath: false - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact' inputs: PathtoPublish: '$(build.artifactstagingdirectory)' - task: Docker@2 displayName: 'Login to Container Registry' inputs: command: login containerRegistry: 'gcr-tutorial' - task: Docker@2 displayName: 'Build and push image' inputs: Dockerfile: 'applications/clouddemo/netcore/Dockerfile' command: buildAndPush repository: '$(DockerImageName)'
將
PROJECT_ID替換成正式版專案的名稱,然後儲存檔案。由於 Cloud Run 是以 Linux 為基礎的環境,管道會使用以 Linux 為基礎的建構代理程式。
修訂變更並推送到 Azure Pipelines。
Visual Studio
- 開啟 Team Explorer,然後按一下「首頁」圖示。
- 按一下 [Changes] (變更)。
- 輸入修訂訊息,例如
Add pipeline definition。 - 按一下 [Commit All and Push] (全部認可並推送)。
指令列
暫存所有已修改的檔案:
git add -A修訂本機存放區的變更:
git commit -m "Add pipeline definition"將變更推送至 Azure DevOps:
git push
在 Azure DevOps 選單中選取「Pipelines」,然後按一下「Create Pipeline」。
選取「Azure Repos Git」。
選取存放區。
在「Review your pipeline YAML」(檢查管道 YAML) 頁面中,按一下「Run」(執行)。
系統會觸發新的建構作業。建構約需 2 分鐘才能完成。
如要確認映像檔是否已發布至 Artifact Registry,請在 Google Cloud 控制台中切換至正式版專案,選取「Artifact Registry」 >「docker」,然後按一下「CloudDemo」。
畫面上會顯示單一圖片和該圖片的標記。這個標記與在 Azure Pipelines 中執行的建構的數字 ID 相同。
- 「版本」是指一組構件,這些構件組成了應用程式的特定版本,且通常是建構過程的結果。
- 「部署」是指建立版本,並將它部署至特定環境中的過程。
- 部署會執行一組「任務」,您可將這組任務組成工作。
- 「階段」可讓您為管道分段,以用來自動化調度管理部署作業到多個環境,例如部署與測試環境。
開啟 Cloud Shell。
初始化下列環境變數:
DEV_PROJECT_ID=DEV_PROJECT_ID PROD_PROJECT_ID=PROD_PROJECT_ID
更改下列內容:
DEV_PROJECT_ID:開發專案的專案 IDPROD_PROJECT_ID:生產專案的專案 ID
在開發和產品專案中啟用 Cloud Run 和 Compute Engine API:
gcloud services enable run.googleapis.com --project=$DEV_PROJECT_ID gcloud services enable run.googleapis.com --project=$PROD_PROJECT_ID啟用這些 API 後,系統會在專案中建立 Cloud Run 服務代理帳戶。
在儲存 Docker 映像檔的正式版專案中,授予兩個 Cloud Run 服務代理程式帳戶 Artifact Registry 的存取權:
DEV_PROJECT_NUMBER=$(gcloud projects describe $DEV_PROJECT_ID \ --format='value(projectNumber)') PROD_PROJECT_NUMBER=$(gcloud projects describe $PROD_PROJECT_ID \ --format='value(projectNumber)') gcloud projects add-iam-policy-binding $PROD_PROJECT_ID \ --member=serviceAccount:service-$DEV_PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com \ --role roles/artifactregistry.reader gcloud projects add-iam-policy-binding $PROD_PROJECT_ID \ --member=serviceAccount:service-$PROD_PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com \ --role roles/artifactregistry.reader建立名為
CloudDemo-runner的服務帳戶:gcloud iam service-accounts create clouddemo-runner \ --display-name="CloudDemo Runner" \ --project=$DEV_PROJECT_ID gcloud iam service-accounts create clouddemo-runner \ --display-name="CloudDemo Runner" \ --project=$PROD_PROJECT_ID DEV_CLOUDDEMO_RUNNER=clouddemo-runner@$DEV_PROJECT_ID.iam.gserviceaccount.com PROD_CLOUDDEMO_RUNNER=clouddemo-runner@$PROD_PROJECT_ID.iam.gserviceaccount.com建立名為
azure-pipelines-deployer的服務帳戶:gcloud iam service-accounts create azure-pipelines-deployer \ --display-name="Azure Pipelines Deployer" \ --project=$PROD_PROJECT_ID AZURE_PIPELINES_DEPLOYER=azure-pipelines-deployer@$PROD_PROJECT_ID.iam.gserviceaccount.com指派必要 IAM 角色,在開發專案中部署新的 Cloud Run 服務或修訂版本:
gcloud projects add-iam-policy-binding $DEV_PROJECT_ID \ --member serviceAccount:$AZURE_PIPELINES_DEPLOYER \ --role roles/run.admin gcloud iam service-accounts add-iam-policy-binding \ $DEV_CLOUDDEMO_RUNNER \ --member=serviceAccount:$AZURE_PIPELINES_DEPLOYER \ --role="roles/iam.serviceAccountUser" \ --project=$DEV_PROJECT_ID為正式版專案指派相同的角色組合:
gcloud projects add-iam-policy-binding $PROD_PROJECT_ID \ --member serviceAccount:$AZURE_PIPELINES_DEPLOYER \ --role roles/run.admin gcloud iam service-accounts add-iam-policy-binding \ $PROD_CLOUDDEMO_RUNNER \ --member=serviceAccount:$AZURE_PIPELINES_DEPLOYER \ --role="roles/iam.serviceAccountUser" \ --project=$PROD_PROJECT_ID產生服務帳戶金鑰:
gcloud iam service-accounts keys create azure-pipelines-deployer.json \ --iam-account=$AZURE_PIPELINES_DEPLOYER \ --project=$PROD_PROJECT_ID cat azure-pipelines-deployer.json | base64 -w 0設定發布管道時,您會使用這項指令的輸出內容。
- 部署至開發環境。
- 要求通過手動核准後,才啟動部署到實際工作環境。
- 部署至實際工作環境。
- 在 Azure DevOps 選單中,選取「Pipelines」 >「Releases」。
- 按一下 [New pipeline]。
- 從範本清單中選取 [Empty job]。
- 當系統提示您輸入階段名稱時,請輸入
Development。 - 在畫面頂端為管道命名
CloudDemo。 - 在管道圖的 [Artifacts] 旁,按一下 [Add]。
- 選取「Build」,然後新增下列設定:
- 來源類型:建構
- 「Source (build pipeline)」:選取建構定義 (應該只有一個選項)
- Default version:Latest
- 來源別名:
build
- 按一下「新增」。
- 按一下「Artifact」方塊中的「Continuous deployment trigger」(持續部署觸發程序) (閃電圖示),新增部署觸發條件。
- 在「Continuous deployment trigger」(持續部署觸發程序) 底下,將切換按鈕設定為 [Enabled] (已啟用)。
- 按一下 [儲存]。
視需要輸入註解,然後按一下 [OK] 確認。
管道會顯示類似下列內容。
- 在選單中,切換至「Tasks」分頁標籤。
- 按一下 [Agent job]。
- 將「代理程式規格」設為「ubuntu-22.04」。
- 在「Agent job」旁,按一下「Add a task to agent job」 ,即可在階段中新增步驟。
- 選取「Command line」工作,然後按一下「Add」。
按一下新增的工作,然後進行下列設定:
- 顯示名稱:
Deploy image to development project 腳本:
gcloud auth activate-service-account \ --quiet \ --key-file <(echo $(ServiceAccountKey) | base64 -d) && \ gcloud run deploy clouddemo \ --quiet \ --service-account=clouddemo-runner@$(CloudRun.ProjectId.Development).iam.gserviceaccount.com \ --allow-unauthenticated \ --image=$(CloudRun.Region)-docker.pkg.dev/$(ContainerRegistry.ProjectId)/docker/clouddemo:$BUILD_BUILDID \ --platform=managed \ --region=$(CloudRun.Region) \ --project=$(CloudRun.ProjectId.Development)這項指令會從環境變數取得服務帳戶金鑰,然後使用 gcloud CLI 將應用程式部署至 Cloud Run。Azure Pipelines 代理程式預設提供 gcloud CLI。
- 顯示名稱:
切換至「變數」分頁,然後新增下列變數。
名稱 值 密鑰 ServiceAccountKey先前已為 azure-pipelines-deployer建立服務帳戶金鑰。是 ContainerRegistry.ProjectId正式版專案的專案 ID。 CloudRun.Region您先前選取的區域,用於部署 Artifact Registry 資源。 CloudRun.ProjectId.Development開發專案的專案 ID。 CloudRun.ProjectId.Production正式版專案的專案 ID。 按一下 [儲存]。
視需要輸入註解,然後按一下 [OK] 確認。
- 在選單中,切換至「Pipeline」分頁標籤。
- 在「Stages」方塊中,選取「Add」 >「New stage」。
- 從範本清單中選取 [Empty job]。
- 當系統提示您輸入階段名稱時,請輸入
Production。 - 按一下新建立階段的閃電圖示。
進行下列設定:
- 選取觸發條件:After stage
- 階段:開發
- 「Pre-deployment approvals」(部署前核准):(啟用)
- 「Approvers」(核准者):選取您的使用者名稱。
管道會顯示類似下方的檢視畫面。
切換至「Tasks」分頁標籤。
將滑鼠停在「Tasks」分頁上方,然後選取「Tasks」 >「Production」。
按一下 [Agent job]。
將「代理程式規格」設為「ubuntu-22.04」。
按一下「Add a task to agent job」(將工作新增至代理程式工作) ,即可在階段中新增步驟。
選取「Command line」工作,然後按一下「Add」。
按一下新增的工作,然後進行下列設定:
- 顯示名稱:
Deploy image to production project 腳本:
gcloud auth activate-service-account \ --quiet \ --key-file <(echo $(ServiceAccountKey) | base64 -d) && \ gcloud run deploy clouddemo \ --quiet \ --service-account=clouddemo-runner@$(CloudRun.ProjectId.Production).iam.gserviceaccount.com \ --allow-unauthenticated \ --image=$(CloudRun.Region)-docker.pkg.dev/$(ContainerRegistry.ProjectId)/docker/clouddemo:$BUILD_BUILDID \ --platform=managed \ --region=$(CloudRun.Region) \ --project=$(CloudRun.ProjectId.Production)
- 顯示名稱:
按一下 [儲存]。
視需要輸入註解,然後按一下 [OK] 確認。
- 在本機電腦上,開啟先前複製的 Git 存放區中的檔案。
applications\clouddemo\netcore\CloudDemo.MvcCore\Views\Home\Index.cshtml - 將
ViewBag.Title的值從Home Page變更為Home Page Cloud Run。 確認變更,然後將其推送到 Azure Pipelines。
Visual Studio
- 開啟 Team Explorer,然後按一下「首頁」圖示。
- 按一下 [Changes] (變更)。
- 輸入修訂訊息,例如
Change site title。 - 按一下 [Commit All and Push] (全部認可並推送)。
指令列
暫存所有已修改的檔案:
git add -A修訂本機存放區的變更:
git commit -m "Change site title"將變更推送至 Azure Pipelines:
git push
在 Azure DevOps 選單中,選取「Pipelines」。系統會觸發建構作業。
建構完成後,請選取「Pipelines」 >「Releases」。啟動發布程序。
按一下「Release-1」開啟詳細資料頁面,並等候「Development」階段的狀態切換為「Succeeded」。
在 Google Cloud 控制台中,切換至開發專案。
在選單中,依序選取「Compute」 >「Cloud Run」。
「clouddemo」服務已成功部署。
按一下「clouddemo」即可查看更多詳細資料。
系統會顯示網址,表示 Cloud Run 已佈建服務。
在新瀏覽器分頁中開啟網址,確認 CloudDemo 應用程式已部署,並使用自訂標題。
在 Azure Pipelines 中,按一下「Production」階段旁的「Approve」,將部署推送至實際工作環境。
(選用) 輸入註解。
按一下「核准」確認,並等待「Production」環境的狀態切換為「Succeeded」。
在 Google Cloud 控制台中,切換至正式版專案。
在選單中,依序選取「Compute」 >「Cloud Run」。
clouddemo 服務已部署至正式環境專案。
按一下「clouddemo」即可查看更多詳細資料。
系統會顯示網址,表示 Cloud Run 已佈建服務。
在新瀏覽器分頁中開啟網址,確認 CloudDemo 應用程式已部署至正式環境,且使用自訂標題。
為 Artifact Registry 建立服務連線
在 Azure Pipelines 中,為 Artifact Registry 建立新的服務連線:
持續建構
您現在可以使用 Azure Pipelines 設定持續整合。Azure Pipelines 會為每個推送至 Git 存放區的修訂版本建構程式碼,並將成果封裝至 Docker 容器中,接著將容器發布至 Artifact Registry。
存放區已包含下列 Dockerfile:
現在請建立使用 YAML 語法的新管道:
持續部署
Azure Pipelines 已可自動建構程式碼並為每個修訂版本發佈 Docker 映像檔。因此,您現在可以專注在部署上。
Azure Pipelines 與其他持續整合系統不同,會區分建構與部署,並提供一套名為「Release Management」的特殊工具,供所有部署相關工作使用。
Azure Pipelines Release Management 是根據下列概念建構而成:
您設定發布管道,在每次完成新版本建構作業時觸發管道。這個管線包含兩個階段:開發和製作。在每個階段中,發布管道都會使用建構管道產生的 Docker 映像檔,然後將其部署至 Cloud Run。
您先前設定的建構管道會先使用建構 ID 標記每個 Docker 映像檔,再將其發布至 Artifact Registry。因此,在發布管道中,您可以使用 $BUILD_BUILDID 變數來找出要部署的正確 Docker 映像檔。
設定 Cloud Run
Cloud Run 是全代管的無伺服器環境,因此您不需要佈建任何基礎架構。為確保 Cloud Run 部署作業安全無虞,您需要設定 IAM。
如以下圖表所示,部署及執行 Cloud Run 服務會涉及多個身分。
這些身分都以服務帳戶的形式實作,並用於特定用途,如下表所述。
| 服務帳戶 | 用於 | Purpose | 必要角色 |
|---|---|---|---|
| Azure Pipelines Publisher | 建立管道 | 將 Docker 映像檔發布至 Artifact Registry | roles/artifactregistry.writer (僅限正式專案) |
| Azure Pipelines Deployer | 發布管道 | 啟動 Cloud Run 部署作業 | roles/run.admin |
| 啟動 CloudDemo 服務 | roles/iam.serviceAccountUser |
||
| Cloud Run 服務代理人 | Cloud Run | 從 Artifact Registry 提取 Docker 映像檔 | roles/artifactregistry.reader (僅限正式專案) |
| CloudDemo 執行者 (執行階段服務帳戶) | CloudDemo 服務 | 存取 Google Cloud上的資源 | 無 |
您已建立並設定 Azure Pipelines Publisher 服務帳戶。在接下來的章節中,您將建立及設定其餘服務帳戶。
設定 Cloud Run 服務帳戶
設定 CloudDemo 執行器帳戶
現在可以設定 CloudDemo 執行器帳戶,這是 CloudDemo 服務的自訂執行階段服務帳戶:
設定 Azure Pipelines Deployer 帳戶
最後,建立並設定 Azure Pipelines Deployer 帳戶,Azure 發布管道會使用這個帳戶部署至 Cloud Run。
設定發布管道
您現在可以返回 Azure Pipelines 自動化部署作業,這包含了下列步驟:
建立發布定義
首先,建立發行定義:
部署至開發專案
建立發行定義之後,您現在可以將 Cloud Run 部署設定至開發專案。
部署至正式環境叢集
最後,將部署設定至正式版專案:
執行管道
您已經設定了整個管道,現在可以開始執行原始碼變更來進行測試:
清除所用資源
如要避免在完成本教學課程後繼續產生費用,請刪除您建立的實體。
刪除 Azure Pipelines 專案
如要刪除 Azure Pipelines 專案,請參閱 Azure DevOps Services 文件。刪除 Azure Pipelines 專案會導致所有原始碼變更遺失。
刪除 Google Cloud 開發和正式環境專案
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
後續步驟
- 為 Cloud Run 服務設定自訂網域。
- 瞭解如何使用 Azure Pipelines 將相同應用程式部署至 Google Kubernetes Engine。
- 進一步瞭解在 Google Cloud上部署 .NET 應用程式。
- 查看 Google Cloud 的參考架構、圖表和最佳做法。 歡迎瀏覽我們的 Cloud Architecture Center。