연습 - Kubernetes 클러스터에 다중 컨테이너 솔루션 배포

완료됨

프로젝트와 함께 제공되는 릴리스 파이프라인은 솔루션을 Docker 컨테이너로 빌드하고 Azure App Service에 배포하도록 설계되었습니다. Kubernetes 클러스터에 여러 컨테이너 배포를 지원하려면 이 파이프라인을 수정해야 합니다.

이 단원에서 학습할 내용은 다음과 같습니다.

  • 기본 분기에 대한 커밋에서 트리거하도록 파이프라인을 업데이트합니다.
  • 파이프라인 전반에서 공유할 변수를 정의합니다.
  • Docker 이미지를 빌드하고 게시합니다.
  • Kubernetes 매니페스트를 게시합니다.
  • Kubernetes와 컨테이너 레지스트리 인스턴스 간에 사용할 이미지 끌어오기 비밀을 만드는 태스크를 추가합니다.
  • Kubernetes 클러스터에 업데이트된 이미지를 배포합니다.

트리거를 지원하도록 파이프라인 업데이트

  1. Azure DevOps 조직에 로그인한 다음 프로젝트로 이동합니다.

  2. 파이프라인을 선택하고 파이프라인을 선택합니다.

  3. 편집을 선택하여 azure-pipelines.yml을 편집합니다.

    Andy: 이전 단일 컨테이너 솔루션에 대해 준비했던 빌드 단계였습니다. 이 단계는 제대로 실행되지 않았다는 사실을 확인했으므로 사용하지 않도록 설정했습니다. main 분기에 대한 커밋을 위해 트리거를 다시 사용하도록 설정하여 시작할 수 있습니다.

  4. 파일 맨 위에 있는 기존 trigger 줄을 다음 코드 조각으로 바꿉다. 이렇게 하면 기본 분기에 커밋할 때마다 파이프라인 실행이 트리거됩니다.

    trigger:
    - 'main'
    

파이프라인에서 액세스할 수 있는 변수 정의

Andy: 두 개의 파이프라인 변수를 추가하고자 합니다. 순위표 리포지토리의 이름(순위표)을 지정하기 위한 것입니다. 다른 하나는 배포 중에 AKS와 ACR 인스턴스 간에 공유하는 데 사용되는 이미지 풀 암호 이름에 대한 것입니다.

  1. 섹션에 강조 표시된 다음 코드를 추가합니다 variables .

    variables:
      buildConfiguration: 'Release'
      leaderboardRepository: 'leaderboard'
      webRepository: 'web'
      tag: '$(Build.BuildId)'
      imagePullSecret: 'secret'
    

Docker 이미지를 Azure Container Registry에 빌드 및 게시합니다.

Andy: 컨테이너 레지스트리에 게시하는 Docker 컨테이너로 웹앱을 빌드하기 위한 태스크가 이미 있습니다. 두 번째 태스크를 사용하여 순위표에 대해 동일한 작업을 수행할 수 있습니다.

  1. 강조 표시된 다음 코드 조각을 사용하여 순위표 컨테이너를 빌드하고 게시하는 두 번째 Docker@2 작업을 추가합니다. 웹 컨테이너 태스크 바로 다음에 이 태스크를 추가합니다.

    - task: Docker@2
      displayName: 'Build and push the web image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(webRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.Web/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    

YAML 파일에서는 공백이 중요하므로 여기서 추가하는 작업이 이전 작업과 일관된 들여쓰기를 사용하는지 확인합니다.

Kubernetes 매니페스트 게시

Andy: 다음 스테이지를 계속 진행할 수 있다고 생각합니다. 놓친 부분이 있나요?

Mara: 배포를 정의하는 일부 매니페스트 파일과 배포 시 Kubernetes에 필요한 서비스가 있다는 멘션. 이 스테이지를 완료하기 전에 게시해야 합니다.

Andy: 그 작업이 필요할까요? 로컬 디스크에 없을 것 같은데요.

Mara: 빌드와 동일한 스테이지 내에서 배포 태스크를 추가하는 경우에는 로컬 디스크에 있겠죠. 그러나 배포 작업은 자체 배포 단계에서 수행되므로 다른 에이전트에서도 새로운 환경에서 실행됩니다. 우리는이 단계가 다른 단계가 필요로하는 모든 것을 게시해야합니다.

Andy: 좋은 지적이네요. 그렇게 하는 게 쉬울까요? manifests 폴더가 새 에이전트로 복사되었는지 확인하기만 하면 됩니다.

Mara: PublishBuildArtifacts@1 태스크가 그러한 용도로 필요합니다. 너무 흔하게 사용하다보니 간단히 publish라고도 합니다.

  1. 다음 코드 조각에서 보듯이 후속 스테이지를 위해 manifests 폴더를 저장하는 publish 태스크를 추가합니다. 이 작업의 들여쓰기가 이전 작업의 들여쓰기와 일치하는지 확인합니다.

    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - publish: '$(Build.SourcesDirectory)/manifests'
      artifact: manifests
    

배포 스테이지 바꾸기

Mara: 기존 배포 스테이지를 배포 작업을 사용하는 스테이지로 바꾸겠습니다. ‘배포 작업’은 배포를 이전에 만든 Azure DevOps 환경에 연결할 수 있는 특별한 종류의 작업입니다. 이렇게 하면 배포 기록을 더 쉽게 추적할 수 있으며, 솔루션이 더욱 정교해짐에 따라 특히 유용합니다.

  1. 기존 배포 단계(빌드 단계 이후의 모든 단계)를 제거하고 다음 코드 조각으로 바꿉니다. 사용할 배포 환경을 나타내는 강조 표시된 줄을 기록해 둡다.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'Dev'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
    

    Mara: 배포 스테이지에서 추가하는 첫 번째 단계는 DownloadBuildArtifacts@0 작업을 사용하여 이전에 게시된 매니페스트 아티팩트를 다운로드하는 것입니다.

    Andy: 잠깐만요. 이 태스크에 대한 download 축약형이 있나요?

    Mara: 맞아요! current 지정자를 사용하여 현재 파이프라인 실행의 아티팩트를 원한다는 사실을 나타낼 수 있습니다.

  2. 강조 표시된 줄을 배포 스테이지의 첫 번째 단계로 추가합니다.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'spike.default'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: manifests
    

    Andy: 이제 ACR 및 AKS 인스턴스 간에 공유될 이미지 끌어오기 비밀을 만들어야 합니다. 사용할 수 있는 태스크가 있는지 아시나요?

    Mara: 저도 찾고 있었는데 다행이네요. KubernetesManifest@0 태스크는 필요한 비밀을 만들기 위한 작업을 지원합니다.

Kubernetes 매니페스트 작업

Kubernetes 매니페스트 태스크는 Kubernetes에 필요한 모든 주요 배포 작업을 관리하도록 설계되었습니다. 이 작업은 비밀 만들기부터 이미지 배포까지 여러 action 옵션을 지원합니다. 이 경우 createSecret 작업은 다음 매개 변수와 함께 사용됩니다.

  • action는 실행할 기능을 나타냅니다. 이 경우 createSecret는 공유 암호를 만듭니다.
  • connectionType은(는) 사용할 서비스 연결 유형을 지정합니다. 옵션: azureResourceManager 또는 kubernetesServiceConnection.
  • secretName은 만들 비밀의 이름을 지정합니다.
  • dockerRegistryEndpoint은(는) Azure Container Registry Service 연결의 이름을 지정합니다.
  • azureSubscriptionConnection은(는) ARM Services 연결의 이름을 지정합니다.
  • azureResourceGroup은(는) 리소스 그룹의 이름을 지정합니다.
  • kubernetesCluster은(는) AKS 클러스터의 이름을 지정합니다.
  • namespace는 이 작업이 적용되는 Kubernetes 네임스페이스를 지정합니다.
  1. 다음 코드 조각을 파이프라인 끝에 추가합니다. 리소스 그룹 이름과 클러스터 이름이 모두 이전에 만든 이름과 일치하는지 확인합니다. 이 작업의 들여쓰기가 다운로드 작업의 들여쓰기와 일치하는지 확인합니다.

    - task: KubernetesManifest@1
      displayName: Create imagePullSecret
      inputs:
        action: createSecret
        connectionType: azureResourceManager
        secretName: $(imagePullSecret)
        dockerRegistryEndpoint: 'Container Registry Connection'
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
    

    Andy: 마지막 단계는 Kubernetes 클러스터에 대한 이미지 배포를 트리거하는 것입니다. 설명서에 따르면 다른 작업과 매개 변수를 사용하여 동일한 태스크를 사용할 수 있을 것 같습니다.

    • action는 실행할 기능을 나타냅니다. 이 경우 deploy을(를) AKS 클러스터에 배포합니다.
    • connectionType은(는) 사용할 서비스 연결 유형을 지정합니다. 옵션: azureResourceManager 또는 kubernetesServiceConnection.
    • azureSubscriptionConnection은(는) ARM Services 연결의 이름을 지정합니다.
    • azureResourceGroup은(는) 리소스 그룹의 이름을 지정합니다.
    • kubernetesCluster은(는) AKS 클러스터의 이름을 지정합니다.
    • namespace는 이 작업이 적용되는 Kubernetes 네임스페이스를 지정합니다.
    • imagePullSecrets는 컨테이너 레지스트리에서 끌어오는 데 필요한 비밀 목록을 지정합니다.
    • containers는 배포할 컨테이너 이미지 목록을 지정합니다.
  2. 다음 코드 조각을 파이프라인 끝에 추가합니다. 리소스 그룹 이름과 클러스터 이름이 모두 이전에 만든 이름과 일치하는지 확인합니다. 이 작업의 들여쓰기가 이전 작업의 들여쓰기와 일치하는지 확인합니다.

    - task: KubernetesManifest@1
      displayName: Deploy to Kubernetes cluster
      inputs:
        action: deploy
        connectionType: azureResourceManager
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
        manifests: |
          $(Pipeline.Workspace)/manifests/deployment.yml
          $(Pipeline.Workspace)/manifests/service.yml
        imagePullSecrets: |
          $(imagePullSecret)
        containers: |
          $(RegistryName)/$(webRepository):$(tag)
          $(RegistryName)/$(leaderboardRepository):$(tag)
    

파이프라인을 실행하세요.

  1. 페이지의 오른쪽 상단에서 저장을 선택합니다. 저장을 선택하여 커밋 메시지 확인합니다.

  2. 실행을 선택하고 분기 이름을 확인한 다음 실행을 선택하여 파이프라인 실행을 트리거합니다.

  3. 파이프라인을 선택한 다음, 파이프라인을 선택하여 파이프라인이 실행되면 로그를 봅니다.

  4. 파이프라인 실행이 완료되면 왼쪽 창에서 환경을 선택한 다음 개발 환경을 선택하여 배포 작업을 봅니다.

  5. 이제 배포된 웹앱 및 API 엔드포인트를 체크 아웃합니다. 이렇게 하려면 웹순위표 서비스 모두에 대한 외부 IP 주소를 가져와야 합니다.

  6. Azure Portal로 이동하여 AKS 클러스터를 선택한 다음 서비스 및 수신을 선택합니다.

    Screenshot of how to find the external IPs for your web and leaderboard services.

  7. 서비스의 외부 IP를 선택하여 AKS에서 사이트를 봅니다.

    Screenshot of the Space Game web site.

  8. 중단한 Azure Portal 창으로 돌아간 다음, 순위표 서비스에 대한 외부 IP를 복사합니다. 이 IP 주소는 순위표 API가 공개적으로 호스트되는 위치입니다.

  9. 다음 링크의 자리 표시자를 복사한 외부 IP로 바꿉 있습니다. pageSize=10 쿼리 매개 변수를 추가하여 브라우저에서 JSON 응답을 쉽게 볼 수도 있습니다. 새 브라우저 탭에서 다음과 같은 URL을 사용합니다.

    http://[IP]/api/Leaderboard?pageSize=10
    
  10. AKS 클러스터에 호스트된 순위표 API의 원시 JSON 응답을 볼 수 있습니다. 이제 다른 애플리케이션에서 호출할 수 있는 REST API가 있습니다.

    Screenshot of a web browser showing the JSON response from the leaderboard service.

Andy: 아주 좋네요. Kubernetes를 사용하는 것이 좀 더 광범위한 마이크로 서비스 전략을 채택하는 좋은 방법이라고 생각합니다.