클라우드 네이티브 앱을 Azure Kubernetes Service에 수동으로 배포

완료됨

웹 사이트 배포를 자동화하려면 먼저 AKS(Azure Kubernetes Service)에 기존 eShop 앱을 수동으로 배포해야 합니다. Azure CLI 명령과 bash 스크립트를 사용하여 Azure 리소스를 만들고 AKS에 앱을 배포합니다. 마지막으로 GitHub Actions가 AKS 및 Azure Container Registry에 배포할 수 있도록 Azure AD(Azure Active Directory) 서비스 주체를 만듭니다.

이 명령은 eShop 앱의 업데이트된 버전을 배포하기 위해 다음 리소스를 만듭니다.

  • ACR(Azure Container Registry)을 프로비전한 다음 이미지를 레지스트리에 푸시합니다.
  • AKS 클러스터를 프로비전한 다음, 컨테이너를 클러스터에 배포합니다.
  • 배포를 테스트합니다.
  • GitHub Actions가 AKS 및 Azure Container Registry에 배포할 수 있도록 서비스 주체를 만듭니다.

Important

시작하기 전에 필수 조건을 완료했는지 확인합니다.

개발 환경 열기

연습을 호스팅하는 GitHub 코드 공간을 사용하거나 Visual Studio Code에서 로컬로 연습을 완료하도록 선택할 수 있습니다.

GitHub Codespaces 설정

https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops 리포지토리를 고유의 GitHub 계정으로 포크합니다. 그런 다음 새 포크에서 다음을 수행합니다.

  1. 코드를 선택합니다.
  2. Codespaces 탭을 선택합니다.
  3. 코드 공간을 만들려면 + 아이콘을 선택합니다.

GitHub는 코드 공간을 만들고 구성하는 데 몇 분 정도 걸립니다. 프로세스가 완료되면 연습용 코드 파일이 표시됩니다.

선택 사항: Visual Studio Code 설정

Visual Studio Code를 사용하려면 https://github.com/MicrosoftDocs/mslearn-dotnet-cloudnative-devops 리포지토리를 고유의 GitHub 계정으로 포크하고 로컬로 복제합니다. 다음 작업:

  1. Visual Studio Code에서 Dev Container를 실행하려면 시스템 요구 사항을 설치합니다.
  2. Docker가 실행 중인지 확인합니다.
  3. 새 Visual Studio Code 창에서 복제된 리포지토리의 폴더를 엽니다.
  4. 명령 팔레트를 열려면 Ctrl+Shift+P를 누릅니다.
  5. 검색: >개발 컨테이너: 다시 빌드 및 컨테이너에서 다시 열기
  6. Visual Studio Code는 개발 컨테이너를 로컬로 만듭니다.

컨테이너 빌드

  1. 터미널 창에서 다음 dotnet CLI 명령을 실행합니다.

    dotnet publish /p:PublishProfile=DefaultContainer 
    

Azure 리소스 만들기

  1. 터미널 창에서 다음 Azure CLI 명령을 사용하여 Azure에 로그인합니다.

    az login --use-device-code
    
  2. 선택한 Azure 구독을 봅니다.

    az account show -o table
    

    잘못된 구독을 선택한 경우 az account set 명령을 사용하여 올바른 구독을 선택합니다.

  3. 다음 Azure CLI 명령을 실행하여 Azure 지역 목록 및 이와 연결된 이름을 가져옵니다.

    az account list-locations -o table
    

    가장 가까운 지역을 찾아 [Closest Azure region]을 바꿔 다음 단계에서 사용합니다.

  4. 다음 bash 문을 실행합니다.

    export LOCATION=[Closest Azure region]
    export RESOURCE_GROUP=rg-eshop
    export CLUSTER_NAME=aks-eshop
    export ACR_NAME=acseshop$SRANDOM
    

    이전 명령은 다음 Azure CLI 명령에서 사용할 환경 변수를 만듭니다. 지역을 가까운 Azure 지역(예: eastus)으로 변경해야 합니다. 리소스 그룹, AKS 클러스터 또는 ACR에 다른 이름을 사용하려면 해당 값을 변경합니다. Azure Portal에서 새 리포지토리를 보려면 컨테이너 레지스트리의 액세스 제어(IAM)에서 자신을 앱 준수 자동화 관리자로 할당합니다.

  5. 다음 Azure CLI 명령을 실행합니다.

    az group create --name $RESOURCE_GROUP --location $LOCATION
    az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Basic
    az acr login --name $ACR_NAME
    

    az acr login --name $ACR_Name 실행 시 인증 오류가 발생하는 경우 Azure의 설정 - 액세스 키 아래에 새로 생성된 컨테이너 레지스터에서 관리자를 켜야 합니다. 계속하려면 Azure에서 이러한 자격 증명을 입력하라는 메시지를 표시합니다. az login --use-device-code를 사용하여 다시 인증해야 할 수도 있습니다.

    이러한 명령은 Azure 리소스, 이미지에 대한 ACR을 포함하는 리소스 그룹을 만든 다음, ACR에 로그인합니다. 다음 출력이 표시될 때까지 몇 분 정도 걸릴 수 있습니다.

      ...
      },
      "status": null,
      "systemData": {
        "createdAt": "2023-10-19T09:11:51.389157+00:00",
        "createdBy": "",
        "createdByType": "User",
        "lastModifiedAt": "2023-10-19T09:11:51.389157+00:00",
        "lastModifiedBy": "",
        "lastModifiedByType": "User"
      },
      "tags": {},
      "type": "Microsoft.ContainerRegistry/registries",
      "zoneRedundancy": "Disabled"
    }
    Login Succeeded
    
  6. 이미지에 태그를 지정하고 만든 ACR에 푸시하려면 다음 명령을 실행합니다.

    docker tag store $ACR_NAME.azurecr.io/storeimage:v1
    docker tag products $ACR_NAME.azurecr.io/productservice:v1
    
    docker push $ACR_NAME.azurecr.io/storeimage:v1
    docker push $ACR_NAME.azurecr.io/productservice:v1
    

    다음 명령을 사용하면 이미지 푸시가 성공적으로 완료되었는지 확인할 수 있습니다.

    az acr repository list --name $ACR_NAME --output table
    
  7. AKS를 만들고 다음 명령을 사용하여 ACR에 연결합니다.

    az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --node-count 1 --generate-ssh-keys --node-vm-size Standard_B2s --network-plugin azure --attach-acr $ACR_NAME
    
    az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
    

    위 명령은 단일 노드 AKS 클러스터를 만들고 이를 ACR에 연결한 다음 로컬 컴퓨터를 AKS 클러스터에 연결합니다. 위 명령을 완료하는 데 몇 분 정도 걸릴 수 있습니다.

  8. 다음 명령을 사용하여 새 AKS가 ACR에서 이미지를 가져올 수 있는지 확인합니다.

    az aks check-acr --acr $ACR_NAME.azurecr.io --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
    

    다음 메시지와 유사한 출력이 표시됩니다.

    [2023-10-19T13:33:09Z] Loading azure.json file from /etc/kubernetes/azure.json
    [2023-10-19T13:33:09Z] Checking managed identity...
    [2023-10-19T13:33:09Z] Cluster cloud name: AzurePublicCloud
    [2023-10-19T13:33:09Z] Kubelet managed identity client ID: 00001111-aaaa-2222-bbbb-3333cccc4444
    [2023-10-19T13:33:09Z] Validating managed identity existance: SUCCEEDED
    [2023-10-19T13:33:09Z] Validating image pull permission: SUCCEEDED
    [2023-10-19T13:33:09Z] 
    Your cluster can pull images from acseshop1251599299.azurecr.io!
    

    이제 새 AKS 클러스터에 대해 kubectl 명령을 실행할 수 있습니다. 출력에서 전체 ACR URL을 복사합니다. 예를 들어, URL 위는 acseshop1251599299입니다.

  9. AKS 클러스터의 상태를 확인합니다.

    kubectl get nodes -A
    

    다음 메시지와 유사한 출력이 표시됩니다.

    NAME                                STATUS   ROLES   AGE     VERSION
    aks-nodepool1-37200563-vmss000000   Ready    agent   3h44m   v1.26.6
    

Kubernetes 배포 매니페스트 구성

이제 eShop 이미지가 ACR에 있으므로 AKS 배포 매니페스트를 업데이트하여 이러한 새 이미지를 사용할 수 있습니다.

  1. Visual Studio Code의 EXPLORER 패널에서 프로젝트 루트에 있는 deployment.yml 파일을 선택합니다.

  2. 줄 17을 바꿉니다.

    - image: [replace with your ACR name].azurecr.io/storeimage:v1
    

    이전 단계에서 복사한 ACR 이름을 붙여넣습니다. 줄은 다음 yaml과 유사해야 합니다.

    - image: acseshop1251599299.azurecr.io/storeimage:v1
    
  3. 줄 65에 대해 다음 단계를 반복합니다.

    - image: [replace with your ACR name].azurecr.io/productservice:v1
    

    CTRL+S를 눌러 파일을 저장합니다.

  4. 터미널 창에서 다음 kubernetes 명령을 사용하여 NGINX 수신 컨트롤러를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.3/deploy/static/provider/cloud/deploy.yaml
    

    위의 kubectl 명령은 AKS 클러스터에 대한 수신을 허용하는 서비스와 구성 요소를 추가합니다. 다음 kubernetes 명령을 사용하여 수신이 실행될 준비가 되었는지 확인합니다.

    kubectl get services --namespace ingress-nginx 
    

    다음 메시지와 유사한 출력이 표시됩니다.

    NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGE
    ingress-nginx-controller             LoadBalancer   10.0.135.51    20.26.154.64   80:32115/TCP,443:32254/TCP   58s
    ingress-nginx-controller-admission   ClusterIP      10.0.137.137   <none>         443/TCP                      58s
    
  5. 다음 명령을 사용하여 eShop 앱을 배포합니다.

    kubectl apply -f deployment.yml
    

    kubectl 적용 명령은 eShop 앱, 프런트 엔드 Blazor 웹앱, 백 엔드 REST API 제품 서비스, AKS 클러스터의 올바른 서비스로 트래픽을 라우팅하는 수신 규칙을 배포합니다. 배포 시 오류가 발생하면 이 명령을 다시 실행합니다.

    다음 메시지와 유사한 출력이 표시됩니다.

    deployment.apps/storeimage created
    service/eshop-website created
    deployment.apps/productservice created
    service/eshop-backend created
    ingress.networking.k8s.io/eshop-ingress created
    
  6. 다음 명령을 사용하여 두 개의 마이크로 서비스가 배포되었는지 확인합니다.

    kubectl get pods -A
    

    다음 메시지와 유사한 출력이 표시됩니다.

    NAMESPACE       NAME                                        READY   STATUS      RESTARTS   AGE
    default         productservice-7569b8c64-vfbfz              1/1     Running     0          3m56s
    default         storeimage-6c7c999d7c-zsnxd                 1/1     Running     0          3m56s
    ingress-nginx   ingress-nginx-admission-create-szb8l        0/1     Completed   0          4m4s
    ingress-nginx   ingress-nginx-admission-patch-czdbv         0/1     Completed   0          4m4s
    ingress-nginx   ingress-nginx-controller-58bf5bf7dc-nwtsr   1/1     Running     0          4m4s
    
  7. 다음 명령을 사용하여 배포된 eShop을 확인합니다.

    echo "http://$(kubectl get services --namespace ingress-nginx ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}')"
    

    위 명령은 웹앱의 외부 IP 주소를 반환합니다. CTRL을 누른 채 링크를 클릭하면 새 탭에서 앱이 열립니다.

    eShop 웹앱 홈페이지의 스크린샷.

GitHub에서 배포하기 위한 서비스 주체 만들기

GitHub Actions는 컨테이너 이미지를 Azure Container Registry에 게시할 수 있습니다. 따라서 GitHub 실행기에는 Azure에 연결할 수 있는 권한이 있어야 합니다. 다음 단계에서는 Azure에서 GitHub Actions ID 역할을 하는 Azure AD 서비스 주체를 만듭니다.

  1. 환경 변수에 구독 ID를 저장하려면 터미널에서 다음 명령을 실행합니다.

    export SUBS=$(az account show --query 'id' --output tsv)
    
  2. GitHub에서 액세스할 수 있는 Azure AD 서비스 주체를 만들려면 다음 명령을 실행합니다.

    az ad sp create-for-rbac --name "eShop" --role contributor --scopes /subscriptions/$SUBS/resourceGroups/$RESOURCE_GROUP --json-auth
    

    다음과 유사한 출력이 표시됩니다.

    Creating 'Contributor' role assignment under scope '/subscriptions/ffffffff-aaaa-bbbb-6666-777777777777'
    
    The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli
     {
      "clientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
      "clientSecret": "abc1A~abc123ABC123abc123ABC123abc123ABC1",
      "subscriptionId": "00000000-0000-0000-0000-000000000000",
      "tenantId": "00000000-0000-0000-0000-000000000000",
      "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/"
    }
    
  3. 다음 단계에서 사용할 JSON 출력 및 대괄호를 복사합니다.

GitHub 비밀 만들기

GitHub Actions 실행기가 Container Registry 및 AKS와 상호 작용하려면 자격 증명을 사용합니다. 컨테이너 레지스트리에 대한 서비스 주체 및 자격 증명은 중요한 정보입니다. 중요한 정보를 암호화된 비밀로 안전한 위치에 저장하는 것이 가장 좋습니다. GitHub는 비밀 및 기타 변수를 저장할 수 있는 기본 제공 위치를 제공합니다.

중요한 정보를 리포지토리에 환경 변수로 안전하게 저장하려면 다음 단계를 완료합니다. 리포지토리 관리자는 GitHub Actions 실행기에서 액세스할 수 있는 비밀을 관리해야 합니다.

  1. 포크된 GitHub 리포지토리에서 Settings>Secrets and variables>Actions로 이동합니다.

  2. Actions secrets and variables 페이지에서 New repository secret을 선택합니다.

  3. New secret 페이지의 NameAZURE_CREDENTIALS를 입력하고 Secret에 터미널에서 복사한 JSON 출력을 입력합니다.

    설정은 다음 스크린 샷과 비슷해야 합니다.

    GitHub에서 환경 변수 비밀을 설정하는 새 비밀 페이지의 스크린샷

  4. Add secret를 선택합니다.

다음 섹션에서는 이 GitHub 비밀을 사용하여 컨테이너 이미지를 빌드하는 GitHub 작업을 만듭니다.