系列導航及源代碼
需求和目標
在這個系列的最后一節中,我們將使用GitHub Actions將TodoList應用部署到Azure Container Instance上。
實現
為了確保部署的應用能夠正確運行,我們需要做以下幾件事:
創建Azure SQL Server實例
選擇最便宜的數據庫規格就可以了,新建一個ResourceGroup名為todolist
,並新建數據庫實例,獲得連接字符串:
創建Azure Container Registry
用於構建好的鏡像上傳和部署
設置GitHub Secrets
首先創建Service Principle認證:
groupId=$(az group show \
--name todolist \
--query id --output tsv)
az ad sp create-for-rbac \
--scope $groupId \
--role Contributor \
--sdk-auth
# 會得到類似下面的輸出
{
"clientId": "xxxx6ddc-xxxx-xxxx-xxx-ef78a99dxxxx",
"clientSecret": "xxxx79dc-xxxx-xxxx-xxxx-aaaaaec5xxxx",
"subscriptionId": "xxxx251c-xxxx-xxxx-xxxx-bf99a306xxxx",
"tenantId": "xxxx88bf-xxxx-xxxx-xxxx-2d7cd011xxxx",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": "https://management.azure.com/",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com/",
"managementEndpointUrl": "https://management.core.windows.net/"
}
接下來更新Registry的認證
registryId=$(az acr show \
--name code4nothing \
--query id --output tsv)
az role assignment create \
--assignee <ClientId> \
--scope $registryId \
--role AcrPush
最后將Secrets配置到Github Repo的設置里:
具體的參數說明請參考:Save credentials to GitHub repo
創建Actions配置
在Github的Repo里選擇Actions,選擇set up a workflow yourself
定義以下構建步驟:
on: [push]
name: Linux_Container_Workflow
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# checkout the repo
- name: 'Checkout GitHub Action'
uses: actions/checkout@main
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Build and push image'
uses: azure/docker-login@v1
with:
login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build -f src/TodoList.Api/Dockerfile.prod . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }}
docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }}
- name: 'Deploy to Azure Container Instances'
uses: 'azure/aci-deploy@v1'
with:
resource-group: ${{ secrets.RESOURCE_GROUP }}
dns-name-label: ${{ secrets.RESOURCE_GROUP }}${{ github.run_number }}
image: ${{ secrets.REGISTRY_LOGIN_SERVER }}/todolist:${{ github.sha }}
registry-login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
registry-username: ${{ secrets.REGISTRY_USERNAME }}
registry-password: ${{ secrets.REGISTRY_PASSWORD }}
name: aci-todolist
location: 'east asia'
修改項目代碼以進行Production部署
Dockerfile.prod
ARG NET_IMAGE=6.0-bullseye-slim
FROM mcr.microsoft.com/dotnet/aspnet:${NET_IMAGE} AS base
WORKDIR /app
EXPOSE 80
ENV ASPNETCORE_ENVIRONMENT=Production
FROM mcr.microsoft.com/dotnet/sdk:${NET_IMAGE} AS build
WORKDIR /src
COPY ["src/TodoList.Api/TodoList.Api.csproj", "TodoList.Api/"]
COPY ["src/TodoList.Application/TodoList.Application.csproj", "TodoList.Application/"]
COPY ["src/TodoList.Domain/TodoList.Domain.csproj", "TodoList.Domain/"]
COPY ["src/TodoList.Infrastructure/TodoList.Infrastructure.csproj", "TodoList.Infrastructure/"]
RUN dotnet restore "TodoList.Api/TodoList.Api.csproj"
COPY ./src .
WORKDIR "/src/TodoList.Api"
RUN dotnet build "TodoList.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish --no-restore "TodoList.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TodoList.Api.dll"]
appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"UseFileToLog": true,
"ConnectionStrings": {
"SqlServerConnection": "Server=tcp:code4nothing.database.windows.net,1433;Initial Catalog=TodoListDb;Persist Security Info=False;User ID=code4nothing;Password=TestTodo@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
}
}
將代碼合並到main上以后,自動觸發Actions:
ACI實例運行起來后可以看到:
驗證
我們從本地的Insomia上訪問API端口,先看看liveness probes是否正常工作:
請求的host可以從這里獲取:
查詢TodoList后查詢TodoItems結果:
一點擴展
微軟新推出的Azure服務Azure Container Apps(preview)
是作為容器化服務部署的另一個選擇,簡單的說明:
Deploy containerized apps without managing complex infrastructure. Write code using your preferred programming language or framework, and build microservices with full support for Distributed Application Runtime (Dapr). Scale dynamically based on HTTP traffic or events powered by Kubernetes Event-Driven Autoscaling (KEDA).
來自官方文檔Azure Container Apps
總結
如果在部署ACI的過程中失敗了,尤其是容器在ACI中沒有成功運行,可以參考:Troubleshoot common issues in Azure Container Instances來查看和解決問題。
在本文中我們實現了如何將應用通過Github Actions部署到Azure Container Instance服務中。那么到本節為止,使用.NET 6開發TodoList應用文章索引這個用於串聯.NET Web API開發基礎系列的文章就結束了,感謝各位朋友在此過程中的支持。
在這個系列的寫作和發表中,我們還漏掉了幾篇文章暫時沒有完成,包括有評論指出的幾個沒有填完的坑,我會找時間盡量都補齊。但是更新速度應該不會像寫這個系列的時候那么密集了。
后面的計划是,在正式開始微服務系列實踐文章開始之前,會寫幾個小的系列來預先熟悉一下后面也許會用到的知識點,例如GraphQL,RabbitMQ,gRPC,Envoy以及Dapr等內容。
感謝各位對文章中錯誤的指正,希望我們能繼續一起努力,一步一個腳印地掌握更多的技能。