이 세션에서는 .NET Aspire로 개발한 애플리케이션을 Aspirate를 이용해 Azure Kubernetes Service(AKS)로 배포해 보겠습니다.
GitHub Codespaces 또는 Visual Studio Code 환경에서 작업하는 것을 기준으로 합니다.
-
아래 명령어를 실행시켜 Azure에 로그인합니다.
# Azure CLI login az login
중요: GitHub Codespaces를 사용하면서 만약
az login
명령어 실행시 새 브라우저 탭이 뜨면서 404 에러가 날 경우, 주소창의 URL 값을 복사해서 새 zsh 터미널을 열고curl <복사한 URL>
을 해 줍니다. -
로그인이 끝났다면 아래 명령어를 통해 제대로 로그인이 되어 있는지 확인합니다.
# Azure CLI az account show
-
터미널을 열고 아래 명령어를 차례로 실행시켜 리포지토리의 루트 디렉토리로 이동합니다.
# GitHub Codespaces REPOSITORY_ROOT=$CODESPACE_VSCODE_FOLDER cd $REPOSITORY_ROOT # bash/zsh REPOSITORY_ROOT=$(git rev-parse --show-toplevel) cd $REPOSITORY_ROOT # PowerShell $REPOSITORY_ROOT = git rev-parse --show-toplevel cd $REPOSITORY_ROOT
-
아래 명령어를 차례로 실행시켜 배포 환경을 준비합니다.
# bash/zsh AZURE_ENV_NAME="{{ GITHUB_ID }}" AZ_LOCATION=australiaeast # PowerShell $AZURE_ENV_NAME = "{{ GITHUB_ID }}" $AZ_LOCATION = "australiaeast"
중요:
{{ GITHUB_ID }}
는 자신의 GitHub 아이디로 변경해야 합니다. 예를 들어 GitHub 아이디가Azure-Samples
라면{{ GITHUB_ID }}
를Azure-Samples
로 변경하세요. -
아래 명령어를 실행시켜 Azure Container Registry(ACR) 및 Azure Kubernetes Service(AKS) 클러스터를 생성합니다.
# bash/zsh PROVISIONED=$($REPOSITORY_ROOT/scripts/provision-aks.sh -e $AZURE_ENV_NAME -l $AZ_LOCATION) # PowerShell $PROVISIONED = & "$REPOSITORY_ROOT/scripts/Provision-AKS.ps1" -AzureEnvName $AZURE_ENV_NAME -Location $AZ_LOCATION
-
아래 명령어를 통해 AKS 클러스터에 연결합니다.
# bash/zsh AZ_RESOURCE_GROUP=$(echo $PROVISIONED | jq -r '.resourceGroup') AKS_CLUSTER_NAME=$(echo $PROVISIONED | jq -r '.aksClusterName') az aks get-credentials \ -g $AZ_RESOURCE_GROUP \ -n $AKS_CLUSTER_NAME # PowerShell $AZ_RESOURCE_GROUP = $($PROVISIONED | ConvertFrom-Json).resourceGroup $AKS_CLUSTER_NAME = $($PROVISIONED | ConvertFrom-Json).aksClusterName az aks get-credentials ` -g $AZ_RESOURCE_GROUP ` -n $AKS_CLUSTER_NAME
-
아래 명령어를 통해 ACR에 연결합니다.
# bash/zsh ACR_LOGIN_SERVER=$(echo $PROVISIONED | jq -r '.acrLoginServer') ACR_USERNAME=$(echo $PROVISIONED | jq -r '.acrUsername') ACR_PASSWORD=$(echo $PROVISIONED | jq -r '.acrPassword') docker login $ACR_LOGIN_SERVER -u $ACR_USERNAME -p $ACR_PASSWORD # PowerShell $ACR_LOGIN_SERVER = $($PROVISIONED | ConvertFrom-Json).acrLoginServer $ACR_USERNAME = $($PROVISIONED | ConvertFrom-Json).acrUsername $ACR_PASSWORD = $($PROVISIONED | ConvertFrom-Json).acrPassword docker login $ACR_LOGIN_SERVER -u $ACR_USERNAME -p $ACR_PASSWORD
-
터미널을 열고 아래 명령어를 차례로 실행시켜 리포지토리의 루트 디렉토리로 이동합니다.
# GitHub Codespaces REPOSITORY_ROOT=$CODESPACE_VSCODE_FOLDER cd $REPOSITORY_ROOT # bash/zsh REPOSITORY_ROOT=$(git rev-parse --show-toplevel) cd $REPOSITORY_ROOT # PowerShell $REPOSITORY_ROOT = git rev-parse --show-toplevel cd $REPOSITORY_ROOT
세이브 포인트에서 가져온 프로젝트를 사용하려면 아래 명령어를 차례로 실행시켜 프로젝트를 복원합니다.
# bash/zsh mkdir -p workshop && cp -a save-points/session-04/. workshop/ cd workshop dotnet restore && dotnet build # PowerShell New-Item -Type Directory -Path workshop -Force && Copy-Item -Path ./save-points/session-04/* -Destination ./workshop -Recurse -Force cd workshop dotnet restore && dotnet build
-
AspireYouTubeSummariser.AppHost
프로젝트의appsettings.Development.json
파일에 세션 04: Azure 배포 - Azure Container Apps에서 등록한 OpenAI 정보를 다시 입력합니다."OpenAI": { "Endpoint": "{{ Azure OpenAI Proxy Service Endpoint }}", "ApiKey": "{{ Azure OpenAI Proxy Service Access Code }}", "DeploymentName": "{{ Azure OpenAI Proxy Service Deployment Name }}" }
중요:
appsettings.json
파일에 추가한 Azure OpenAI 서비스의 값들은 절대로 GitHub에 커밋하지 마세요. 대신appsettings.Development.json
파일에 추가하세요..gitignore
파일에 이미appsettings.Development.json
파일에 대한 제외 옵션이 추가되어 있습니다.
-
아래 명령어를 통해 Aspirate를 설치합니다.
dotnet tool install -g aspirate
-
아래 디렉토리로 이동합니다.
cd $REPOSITORY_ROOT/workshop/AspireYouTubeSummariser.AppHost
-
Aspirate 프로젝트를 초기화 합니다.
aspirate init -cr $ACR_LOGIN_SERVER --non-interactive
-
AspireYouTubeSummariser.AppHost
프로젝트 디렉토리 아래aspirate.json
파일이 생성된 것을 확인합니다. -
아래 명령어를 통해 Aspire 앱을 빌드하고 ACR로 배포합니다.
aspirate generate --image-pull-policy Always --disable-secrets --include-dashboard false --non-interactive
NOTE: 실습의 편의를 위해
--disable-secrets
옵션을 사용합니다. 실제로는 패스워드를 사용해야 합니다. -
AspireYouTubeSummariser.AppHost
프로젝트 디렉토리 아래aspirate-output
디렉토리와aspirate-sate.json
파일,manifest.json
파일이 생성된 것을 확인합니다. -
아래 명령어를 통해 AKS 클러스터로 앱을 배포합니다.
aspirate apply -k $AKS_CLUSTER_NAME --rolling-restart true --non-interactive
-
아래 명령어를 통해 AKS 클러스터에 로드밸런서를 추가합니다.
kubectl apply -f "$REPOSITORY_ROOT/scripts/loadbalancer.yaml"
-
아래 명령어를 통해
webapp-lb
서비스가LoadBalancer
타입인지 확인합니다. 그리고 외부 IP주소를 확인합니다. 외부 IP 주소는EXTERNAL-IP
열에 나옵니다.kubectl get services
-
방금 확인한 외부 IP 주소를 웹 브라우저로 접속해서 애플리케이션이 잘 작동하는지 확인합니다.
http://<EXTERNAL-IP>
-
홈페이지에서 YouTube 링크를 입력하고
Summarise
버튼을 클릭합니다.YouTube 링크는 무엇이든 상관 없습니다. 여기서는 https://youtu.be/NN4Zzp-vOrU 링크를 사용합니다. 혹시나 토큰 길이 관련 에러가 나오는 경우에는 30분 이하의 짧은 동영상을 사용해 보세요.
-
AspireYouTubeSummariser.WebApp
프로젝트의Components/UI/YouTubeSummariserComponent.razor
파일을 열고 아래 라인을 수정합니다.<div class="row"> <div class="mb-3"> <button type="button" class="btn btn-primary" @onclick="SummariseAsync">Summarise!</button> @* 수정 전 *@ <button type="button" class="btn btn-secondary" @onclick="ClearAsync">Clear!</button> @* 수정 후 *@ <button type="button" class="btn btn-secondary" @onclick="ClearAsync">Reset!</button> </div> </div>
-
수정이 끝난 후 아래 명령어를 실행시켜 다시 앱을 배포합니다.
# 앱 빌드 후 컨테이너 배포 aspirate build --non-interactive # AKS 클러스터 배포 aspirate apply -k $AKS_CLUSTER_NAME --rolling-restart true --non-interactive
-
배포가 끝난 후 다시 외부 IP 주소를 웹 브라우저로 접속한 후
Reset!
버튼으로 바뀌었는지 확인합니다.http://<EXTERNAL-IP>
-
YouTube 링크를 입력하고
Summarise
버튼을 클릭합니다.YouTube 링크는 무엇이든 상관 없습니다. 여기서는 https://youtu.be/NN4Zzp-vOrU 링크를 사용합니다. 혹시나 토큰 길이 관련 에러가 나오는 경우에는 30분 이하의 짧은 동영상을 사용해 보세요.
-
요약 결과가 잘 나오는 것을 확인합니다.
-
만약 앱 수정 결과가 반영되지 않았다면, 아래와 같이 컨테이너 이미지를 지우고 다시 배포해 보세요.
# bash/zsh ACR_NAME=$(echo $PROVISIONED | jq -r '.acrName') # PowerShell $ACR_NAME = $($PROVISIONED | ConvertFrom-Json).acrName # AKS 노드 삭제 aspirate destroy -k $AKS_CLUSTER_NAME --non-interactive # 컨테이너 이미지 삭제 az acr repository delete -n $ACR_NAME --repository apiapp -y az acr repository delete -n $ACR_NAME --repository webapp -y # Aspirate로 다시 배포 aspirate build --non-interactive aspirate apply -k $AKS_CLUSTER_NAME --rolling-restart true --non-interactive
NOTE: 필요한 경우 아래 명령어를 통해
webapp-lb
서비스를 삭제하고 다시 생성해야 할 수도 있습니다.# 로드 밸런서 삭제 kubectl delete -f "$REPOSITORY_ROOT/scripts/loadbalancer.yaml" # 로드 밸런서 재추가 kubectl apply -f "$REPOSITORY_ROOT/scripts/loadbalancer.yaml"
-
아래 명령어를 통해
webapp-lb
서비스가LoadBalancer
타입인지 확인합니다. 그리고 외부 IP주소를 확인합니다.kubectl get services
-
방금 확인한 외부 IP 주소를 웹 브라우저로 접속해서 애플리케이션이 잘 작동하는지 확인합니다.
http://<EXTERNAL-IP>
YouTube 링크는 무엇이든 상관 없습니다. 여기서는 https://youtu.be/NN4Zzp-vOrU 링크를 사용합니다. 혹시나 토큰 길이 관련 에러가 나오는 경우에는 30분 이하의 짧은 동영상을 사용해 보세요.
-
아래 명령어를 통해 배포한 모든 리소스를 삭제합니다.
# bash/zsh $REPOSITORY_ROOT/scripts/destroy-aks.sh -e $AZURE_ENV_NAME # PowerShell & "$REPOSITORY_ROOT/scripts/Destroy-AKS.ps1" -AzureEnvName $AZURE_ENV_NAME
축하합니다! Azure Kubernetes Service 클러스터로 배포해 보는 작업이 끝났습니다.
지금까지 GitHub Copilot 기능을 활용해서 빠르게 Blazor 프론트엔드 웹 앱과 ASP.NET Core 백엔드 API 앱을 개발해 봤습니다. 이후 .NET Aspire를 활용해 Cloud-Native 앱으로 변환시켰고, Azure Developer CLI를 이용해 Azure Container Apps로 배포해 보았습니다. 마지막으로 Aspirate를 이용해 Azure Kubernetes Service 클러스터로 배포해 보았습니다.
이 모든 것들에 대해 좀 더 공부해 보고 싶다면 아래 리소스를 참고하세요.
- What is Blazor?
- Build your first Blazor app
- What is Aspire?
- Build your first Aspire app
- What is GitHub Copilot?
- Building an intelligent app with Blazor and Azure OpenAI
- Your stack for building Cloud Native apps
(추가 세션) 이제 세션 06: Blazor JavaScript Interoperability 적용으로 넘어가세요. (추가 세션) 이제 세션 07: Semantic Kernel 앱 개발으로 넘어가세요.