Azure DevOps 및 Helm을 사용하여 Kubernetes 상의 마이크로 서비스에 대한 CI/CD 파이프라인 빌드

AKS(Azure Kubernetes Service)
Azure Container Registry
Azure DevOps

마이크로 서비스 아키텍처를 위한 신뢰할 수 있는 CI/CD(연속 통합/지속적인 업데이트) 프로세스를 만드는 것은 어려울 수 있습니다. 개별 팀은 다른 팀을 방해하거나 애플리케이션 전체를 불안정하게 하지 않고 서비스를 빠르고 안정적으로 릴리스할 수 있어야 합니다.

이 아티클에서는 AKS(Azure Kubernetes Service)에 마이크로 서비스를 배포하기 위한 예제 CI/CD 파이프라인에 대해 설명합니다. 모든 팀과 프로젝트가 다르므로 이 아티클을 일련의 엄격한 규칙으로 간주하지 마세요. 대신 고유한 CI/CD 프로세스를 디자인하기 위한 시작점이 됩니다.

Kubernetes 호스팅 마이크로 서비스를 위한 CI/CD 파이프라인의 목표는 다음과 같이 요약할 수 있습니다.

  • 팀은 서비스를 독립적으로 빌드하고 배포할 수 있습니다.
  • CI 프로세스를 거친 코드 변경은 프로덕션과 유사한 환경에 자동으로 배포됩니다.
  • 파이프라인의 각 단계에서 품질 게이트를 적용합니다.
  • 새 버전의 서비스를 이전 버전과 함께 배포할 수 있습니다.

자세한 배경 정보는 마이크로 서비스 아키텍처를 위한 CI/CD를 참조하세요.

가정

이 예제의 목적을 위한 개발 팀과 코드 베이스에 관한 몇 가지 가정은 다음과 같습니다.

  • 코드 리포지토리는 마이크로 서비스별로 정리된 폴더를 사용하는 단일 리포지토리입니다.
  • 팀의 분기 전략이 트렁크 기반 개발을 기반으로 합니다.
  • 팀은 릴리스 분기를 사용하여 릴리스를 관리합니다. 각 마이크로 서비스를 위한 별도의 릴리스가 만들어집니다.
  • CI/CD 프로세스는 Azure Pipelines를 사용하여 마이크로 서비스를 빌드 및 테스트하고 AKS에 배포합니다.
  • 각 마이크로 서비스를 위한 컨테이너 이미지는 Azure Container Registry에 저장됩니다.
  • 팀은 Helm 차트를 사용하여 각 마이크로 서비스를 패키지합니다.
  • 푸시 배포 모델이 사용됩니다. 여기서 Azure Pipelines 및 관련 에이전트는 AKS 클러스터에 직접 연결하여 배포를 수행합니다.

이러한 가정에는 CI/CD 파이프라인에 대한 많은 구체적 세부 정보가 관련될 수 있습니다. 그러나 여기에 설명된 기본 접근 방식은 Jenkins 또는 Docker Hub와 같은 다른 프로세스, 도구 및 서비스에 맞게 조정됩니다.

대안

다음은 고객이 Azure Kubernetes Service를 통해 CI/CD 전략을 선택할 때 사용할 수 있는 일반적인 대안입니다.

  • Helm을 패키지 관리 및 배포 도구로 사용하는 대신 Kustomize는 애플리케이션 구성을 사용자 지정하고 매개 변수화하는 템플릿 없는 방법을 도입하는 Kubernetes 네이티브 구성 관리 도구입니다.
  • Git 리포지토리 및 파이프라인에 Azure DevOps를 사용하는 대신 GitHub 리포지토리를 프라이빗 및 퍼블릭 Git 리포지토리에 사용할 수 있으며 CI/CD 파이프라인에 GitHub Actions를 사용할 수 있습니다.
  • 푸시 배포 모델을 사용하는 대신, GitOps(풀 배포 모델)를 사용하여 Kubernetes 구성을 대규모로 관리할 수 있습니다. 여기서 클러스터 내 Kubernetes 연산자는 Git 리포지토리에 저장된 구성에 따라 클러스터 상태를 동기화합니다.

유효성 검사 빌드

개발자가 Delivery Service라는 마이크로 서비스를 작업 중이라고 가정하세요. 개발자는 새 기능을 개발할 때 기능 분기에 코드를 체크 인합니다. 관례상 기능 분기는 feature/*로 명명합니다.

CI/CD workflow

빌드 정의 파일에는 분기 이름과 원본 경로에 의해 필터링되는 트리거가 포함되어 있습니다.

trigger:
  batch: true
  branches:
    include:
    # for new release to production: release flow strategy
    - release/delivery/v*
    - refs/release/delivery/v*
    - master
    - feature/delivery/*
    - topic/delivery/*
  paths:
    include:
    - /src/shipping/delivery/

각 팀은 이러한 접근법을 사용하여 자체 빌드 파이프라인을 구축할 수 있습니다. /src/shipping/delivery 폴더에 체크 인된 코드만 Delivery Service의 빌드를 트리거합니다. 필터와 일치하는 분기에 커밋을 푸시하면 CI 빌드가 트리거됩니다. 워크플로의 이 시점에서 CI 빌드는 최소한의 코드 확인을 실행합니다.

  1. 코드를 빌드합니다.
  2. 단위 테스트를 실행합니다.

개발자가 신속한 피드백을 얻을 수 있도록 빌드 시간을 짧게 유지하자는 것이 목표입니다. 기능을 마스터에 병합할 준비가 되면 개발자는 PR을 엽니다. 이 작업이 일부 추가 검사를 수행하는 다른 CI 빌드를 트리거합니다.

  1. 코드를 빌드합니다.
  2. 단위 테스트를 실행합니다.
  3. 런타임 컨테이너 이미지를 빌드합니다.
  4. 이미지에 대한 취약성 검사를 실행합니다.

Diagram showing ci-delivery-full in the Build pipeline.

참고 항목

Azure DevOps Repos에서 분기를 보호하는 정책을 정의할 수 있습니다. 예를 들어 마스터에 병합하려면 정책에 승인자의 서명과 성공적인 CI 빌드가 필요할 수 있습니다.

전체 CI/CD 빌드

어느 시점이 되면 팀은 새 버전의 Delivery Service를 배포할 수 있습니다. 릴리스 관리자는 release/<microservice name>/<semver> 이름 지정 패턴을 사용하여 메인 분기에서 분기를 만듭니다. 예들 들어 release/delivery/v1.0.2입니다.

Diagram showing ci-delivery-full in the Build pipeline and cd-delivery in the Release pipeline.

이 분기를 만들면 이전 단계와 다음을 모두 실행하는 전체 CI 빌드가 트리거됩니다.

  1. 컨테이너 이미지를 Azure Container Registry에 푸시합니다. 분기 이름에서 가져온 버전 번호로 이미지에 태그가 지정됩니다.
  2. helm package를 실행하여 서비스를 위한 Helm 차트를 패키지합니다. 또한, 차트에는 버전 번호로 태그가 지정됩니다.
  3. Container Registry에 Helm 패키지를 푸시합니다.

이 빌드가 성공할 경우 Azure Pipelines 릴리스 파이프라인을 사용하여 배포 (CD) 프로세스가 트리거됩니다. 이 파이프라인에는 다음 단계가 있습니다.

  1. QA 환경에 Helm 차트를 배포합니다.
  2. 승인자가 서명한 후 패키지가 프로덕션 단계로 이동합니다. 승인을 통해 릴리스 배포 제어를 참조하세요.
  3. Azure Container Registry에서 프로덕션 네임스페이스용 Docker 이미지에 다시 태그를 지정합니다. 예를 들어 현재 태그가 myrepo.azurecr.io/delivery:v1.0.2라면 프로덕션 태그는 myrepo.azurecr.io/prod/delivery:v1.0.2입니다.
  4. 프로덕션 환경에 Helm 차트를 배포합니다.

단일 리포지토리에서도 이러한 작업의 범위를 개별 마이크로 서비스로 지정해 팀이 빠른 개발속도로 배포하도록 할 수 있습니다. 프로세스에는 PR 승인, 릴리스 분기 만들기 및 프로덕션 클러스터에 대한 배포 승인과 같은 몇 가지 수동 단계가 있습니다. 이러한 단계는 수동으로 실행합니다. 조직에서 선호하는 경우 이러한 단계를 자동화할 수 있습니다.

환경 격리

개발, 스모크 테스트, 통합 테스트, 부하 테스트 및 최종적으로 프로덕션을 위한 환경을 포함한 여러 환경에 서비스를 배포하게 될 것입니다. 이러한 환경에는 일정 수준의 격리가 필요합니다. Kubernetes에서는 물리적 격리와 논리적 격리 중에서 선택할 수 있습니다. 물리적 격리는 별도의 클러스터에 배포하는 것을 의미합니다. 논리적 격리는 앞에서 설명한 것처럼 네임스페이스와 정책을 사용합니다.

개발/테스트 환경에 사용할 별도의 클러스터와 함께 전용 프로덕션 클러스터를 만드는 방법을 권장합니다. 논리적 격리를 사용하여 개발/테스트 클러스터 내에서 별도의 환경을 격리하세요. 개발/테스트 클러스터에 배포된 서비스는 비즈니스 데이터를 보관하는 데이터 저장소에 절대로 액세스하면 안 됩니다.

빌드 프로세스

가능하면 빌드 프로세스를 Docker 컨테이너에 패키지합니다. 이 구성을 사용하면 각 빌드 머신에 빌드 환경을 구성하지 않고도 Docker를 사용하여 코드 아티팩트를 빌드할 수 있습니다. 컨테이너화된 빌드 프로세스를 사용하면 새 빌드 에이전트를 추가하여 CI 파이프라인을 쉽게 스케일 아웃할 수 있습니다. 또한, 팀의 모든 개발자는 빌드 컨테이너를 실행하여 코드를 빌드할 수 있습니다.

Docker에서 다단계 빌드를 사용하면 단일 Dockerfile에서 빌드 환경 및 런타임 이미지를 정의할 수 있습니다. 예를 들어 다음은 .NET 애플리케이션을 빌드하는 Dockerfile입니다.

FROM mcr.microsoft.com/dotnet/core/runtime:3.1 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src/Fabrikam.Workflow.Service

COPY Fabrikam.Workflow.Service/Fabrikam.Workflow.Service.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.csproj

COPY Fabrikam.Workflow.Service/. .
RUN dotnet build Fabrikam.Workflow.Service.csproj -c release -o /app --no-restore

FROM build AS testrunner
WORKDIR /src/tests

COPY Fabrikam.Workflow.Service.Tests/*.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.Tests.csproj

COPY Fabrikam.Workflow.Service.Tests/. .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

FROM build AS publish
RUN dotnet publish Fabrikam.Workflow.Service.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Fabrikam.Workflow.Service.dll"]

이 Dockerfile은 여러 빌드 단계를 정의합니다. base로 불리는 스테이지는 .NET 런타임을 사용하고 build라는 스테이지는 전체 .NET SDK를 사용합니다. build 스테이지는 .NET 프로젝트를 빌드하는 데 사용됩니다. 그러나 최종 런타임 컨테이너는 런타임만 포함하고 전체 SDK 이미지보다 훨씬 작은 base에서 빌드됩니다.

테스트 실행기 빌드

또 다른 좋은 방법은 컨테이너에서 단위 테스트를 실행하는 것입니다. 예를 들어 테스트 실행기를 빌드하는 Docker 파일의 일부는 다음과 같습니다.

FROM build AS testrunner
WORKDIR /src/tests

COPY Fabrikam.Workflow.Service.Tests/*.csproj .
RUN dotnet restore Fabrikam.Workflow.Service.Tests.csproj

COPY Fabrikam.Workflow.Service.Tests/. .
ENTRYPOINT ["dotnet", "test", "--logger:trx"]

개발자는 이 Docker 파일을 사용하여 테스트를 로컬로 실행할 수 있습니다.

docker build . -t delivery-test:1 --target=testrunner
docker run delivery-test:1

또한, CI 파이프라인은 빌드 확인 단계의 일부로 테스트를 실행해야 합니다.

이 파일은 Docker RUN 명령이 아닌 Docker ENTRYPOINT 명령을 사용하여 테스트를 실행한다는 점에 유의하세요.

  • RUN 명령을 사용하는 경우 이미지를 빌드할 때마다 테스트가 실행됩니다. ENTRYPOINT를 사용하면 테스트가 옵트인됩니다. testrunner 스테이지를 명시적으로 대상으로 지정하는 경우에만 실행됩니다.
  • 테스트에 실패해도 Docker build 명령이 실패하지는 않습니다. 이 방법으로 컨테이너 빌드 실패와 테스트 실패를 구분할 수 있습니다.
  • 테스트 결과를 탑재된 볼륨에 저장할 수 있습니다.

컨테이너 모범 사례

다음은 컨테이너에 대해 고려해야 할 몇 가지 다른 모범 사례입니다.

  • 컨테이너 태그, 버전 관리에 대한 조직 전반의 규칙 및 클러스터(포드, 서비스 등)에 배포되는 리소스에 대한 명명 규칙을 정의합니다. 배포 문제를 진단하기 쉽게 만들 수 있습니다.

  • 개발 및 테스트 주기 동안 CI/CD 프로세스는 많은 컨테이너 이미지를 빌드합니다. 이 이미지들 중 일부만이 릴리스 후보이며 해당 릴리스 후보 중 일부만 프로덕션으로 푸시됩니다. 현재 프로덕션에 배포되는 이미지를 알고 필요한 경우 이전 버전으로 롤백할 수 있도록 명확한 버전 관리 전략이 있어야 합니다.

  • 항상 latest가 아닌 특정 컨테이너 버전 태그를 배포합니다.

  • Azure Container Registry에서 네임스페이스를 사용하여 아직 테스트 중인 이미지에서 프로덕션용으로 승인된 이미지를 분리합니다. 프로덕션에 배포할 준비가 될 때까지 이미지를 프로덕션 레지스트리로 이동하지 마세요. 이 연습을 컨테이너 이미지의 의미 체계 버전 관리에 결합하면 릴리스에 대해 승인되지 않은 버전을 실수로 배포하는 가능성을 줄일 수 있습니다.

  • 권한 없는 사용자로 컨테이너를 실행하여 최소 권한 원칙을 따릅니다. Kubernetes에서 컨테이너가 루트로 실행되지 않도록 하는 Pod 보안 정책을 만들 수 있습니다.

Helm 차트

Helm을 사용하여 서비스를 빌드하고 배포하는 방안을 고려해 보세요. 다음은 CI/CD에 도움이 되는 Helm의 몇 가지 기능입니다.

  • 단일 마이크로 서비스는 종종 여러 Kubernetes 개체에 의해 정의됩니다. Helm을 사용하면 이러한 개체를 단일 Helm 차트로 패키지할 수 있습니다.
  • 일련의 kubectl 명령이 아닌 단일 Helm 명령으로 차트를 배포할 수 있습니다.
  • 차트의 버전이 명시적으로 지정됩니다. Helm을 사용하여 버전을 릴리스하고, 릴리스를 보고, 이전 버전으로 롤백합니다. 이전 버전으로 롤백하는 기능과 함께 의미 체계 버전 관리를 사용하여 업데이트 및 수정 버전 추적.
  • Helm 차트는 템플릿을 사용하여 여러 파일에서 레이블 및 선택기 등의 정보가 중복되지 않도록 방지합니다.
  • Helm은 차트 간의 종속성을 관리할 수 있습니다.
  • 차트는 Azure Container Registry와 같은 Helm 리포지토리에 저장하고 빌드 파이프라인에 통합할 수 있습니다.

Container Registry를 Helm 리포지토리로 사용하는 방법에 대한 자세한 내용은 애플리케이션 차트용 Helm 리포지토리로 Azure Container Registry 사용을 참조하세요.

단일 마이크로 서비스는 여러 Kubernetes 구성 파일을 포함할 수 있습니다. 서비스 업데이트는 이러한 모든 파일을 터치하여 선택기, 레이블 및 이미지 태그를 업데이트하는 것을 의미할 수 있습니다. Helm은 이 항목들을 차트라는 단일 패키지로 처리하며 사용자가 변수를 사용하여 YAML 파일을 쉽게 업데이트할 수 있도록 해줍니다. Helm은 템플릿 언어(Go 템플릿 기반)를 사용하여 매개 변수가 있는 YAML 구성 파일을 작성하도록 해줍니다.

예를 들어 다음은 배포를 정의하는 YAML 파일의 일부입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "package.fullname" . | replace "." "" }}
  labels:
    app.kubernetes.io/name: {{ include "package.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

...

  spec:
      containers:
      - name: &package-container_name fabrikam-package
        image: {{ .Values.dockerregistry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        env:
        - name: LOG_LEVEL
          value: {{ .Values.log.level }}

배포 이름, 레이블 및 컨테이너 사양은 모두 배포 시 제공되는 템플릿 매개 변수를 사용하는 것을 볼 수 있습니다. 예를 들어 명령줄에서 다음을 수행합니다.

helm install $HELM_CHARTS/package/ \
     --set image.tag=0.1.0 \
     --set image.repository=package \
     --set dockerregistry=$ACR_SERVER \
     --namespace backend \
     --name package-v0.1.0

CI/CD 파이프라인이 Kubernetes에 직접 차트를 설치할 수 있지만, 차트 보관 파일(.tgz 파일)을 만들고 Azure Container Registry와 같은 Helm 리포지토리(예: )로 차트를 푸시하는 것이 좋습니다. 자세한 내용은 Azure Pipelines의 Helm 차트에서 Docker 기반 앱 패키지를 참조하세요.

수정 내용

Helm 차트에는 항상 의미 체계 버전 관리를 사용해야 하는 버전 번호가 있습니다. 차트에는 appVersion도 있을 수 있습니다. 이 필드는 선택 사항이며 차트 버전과 관련될 필요가 없습니다. 일부 팀은 차트에 대한 업데이트와 별도의 애플리케이션 버전을 원할 수 있습니다. 그러나 더 간단한 접근 방식은 하나의 버전 번호를 사용하여 차트 버전과 애플리케이션 버전 간에 1:1 관계가 성립되도록 하는 것입니다. 이렇게 하면 릴리스당 하나의 차트를 저장하고 원하는 릴리스를 쉽게 배포할 수 있습니다.

helm install <package-chart-name> --version <desiredVersion>

또 다른 좋은 방법은 배포 템플릿에서 변경 원인 주석을 제공하는 것입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "delivery.fullname" . | replace "." "" }}
  labels:
     ...
  annotations:
    kubernetes.io/change-cause: {{ .Values.reason }}

이렇게 하면 kubectl rollout history 명령을 사용하여 각 수정 버전에 대한 변경 원인 필드를 볼 수 있습니다. 이전 예제에서 변경 원인은 Helm 차트 매개 변수로 제공됩니다.

kubectl rollout history deployments/delivery-v010 -n backend
deployment.extensions/delivery-v010
REVISION  CHANGE-CAUSE
1         Initial deployment

helm list 명령을 사용하여 수정 버전 이력을 볼 수도 있습니다.

helm list
NAME            REVISION    UPDATED                     STATUS        CHART            APP VERSION     NAMESPACE
delivery-v0.1.0 1           Sun Apr  7 00:25:30 2020    DEPLOYED      delivery-v0.1.0  v0.1.0          backend

Azure DevOps 파이프라인

Azure Pipelines에서 파이프라인은 빌드 파이프라인릴리스 파이프라인으로 나뉩니다. 빌드 파이프라인은 CI 프로세스를 실행하고 빌드 아티팩트를 만듭니다. Kubernetes 상의 마이크로 서비스 아키텍처의 경우 이러한 아티팩트들은 각 마이크로 서비스를 정의하는 컨테이너 이미지 및 Helm 차트입니다. 릴리스 파이프라인은 마이크로 서비스를 클러스터에 배포하는 CD 프로세스를 실행합니다.

이 아티클의 앞부분에서 설명한 CI 흐름에 기반해 빌드 파이프라인은 다음 작업으로 구성될 수 있습니다.

  1. 테스트 실행기 컨테이너를 빌드합니다.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        arguments: '--pull --target testrunner'
        dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
        imageName: '$(imageName)-test'
    
  2. 테스트 실행기 컨테이너에 대해 docker run을 호출하여 테스트를 실행합니다.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        command: 'run'
        containerName: testrunner
        volumes: '$(System.DefaultWorkingDirectory)/TestResults:/app/tests/TestResults'
        imageName: '$(imageName)-test'
        runInBackground: false
    
  3. 테스트 결과를 게시합니다. 이미지 빌드를 참조하세요.

    - task: PublishTestResults@2
      inputs:
        testResultsFormat: 'VSTest'
        testResultsFiles: 'TestResults/*.trx'
        searchFolder: '$(System.DefaultWorkingDirectory)'
        publishRunAttachments: true
    
  4. 런타임 컨테이너를 빌드합니다.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
        includeLatestTag: false
        imageName: '$(imageName)'
    
  5. 컨테이너 이미지를 Azure Container Registry(또는 다른 컨테이너 레지스트리)에 푸시합니다.

    - task: Docker@1
      inputs:
        azureSubscriptionEndpoint: $(AzureSubscription)
        azureContainerRegistry: $(AzureContainerRegistry)
        command: 'Push an image'
        imageName: '$(imageName)'
        includeSourceTags: false
    
  6. Helm 차트를 패키지합니다.

    - task: HelmDeploy@0
      inputs:
        command: package
        chartPath: $(chartPath)
        chartVersion: $(Build.SourceBranchName)
        arguments: '--app-version $(Build.SourceBranchName)'
    
  7. Helm 패키지를 Azure Container Registry(또는 다른 Helm 리포지토리)에 푸시합니다.

    task: AzureCLI@1
      inputs:
        azureSubscription: $(AzureSubscription)
        scriptLocation: inlineScript
        inlineScript: |
        az acr helm push $(System.ArtifactsDirectory)/$(repositoryName)-$(Build.SourceBranchName).tgz --name $(AzureContainerRegistry);
    

CI 파이프라인의 출력은 프로덕션 준비 컨테이너 이미지이며 마이크로 서비스를 위한 업데이트된 Helm 차트입니다. 이 시점에서 릴리스 파이프라인으로 이어질 수 있습니다. 각 마이크로 서비스를 위한 고유한 릴리스 파이프라인이 있습니다. 릴리스 파이프라인은 아티팩트가 게시된 CI 파이프라인에 대해 트리거 원본을 설정하도록 구성됩니다. 이 파이프라인을 사용하면 각 마이크로 서비스를 독립적으로 배포할 수 있습니다. 릴리스 파이프라인은 다음 단계를 수행합니다.

  • Helm 차트를 개발/QA/스테이징 환경에 배포합니다. Helm upgrade 명령은 --install 플래그와 함께 사용하여 첫 번째 설치 및 후속 업그레이드를 지원할 수 있습니다.
  • 승인자가 배포를 승인하거나 거부할 때까지 기다립니다.
  • 릴리스를 위해 컨테이너 이미지에 다시 태그 지정
  • 릴리스 태그를 컨테이너 레지스트리에 푸시합니다.
  • 프로덕션 클러스터에 Helm 차트를 배포합니다.

릴리스 파이프라인을 만드는 방법에 대한 자세한 내용은 릴리스 파이프라인, 초안 릴리스 및 릴리스 옵션을 참조하세요.

다음 다이어그램은 이 아티클에 설명된 엔드투엔드 CI/CD 프로세스를 보여줍니다.

CD/CD pipeline

참가자

Microsoft에서 이 문서를 유지 관리합니다. 원래 다음 기여자가 작성했습니다.

보안 주체 작성자:

  • 존 풀 | 선임 클라우드 솔루션 설계자

비공개 LinkedIn 프로필을 보려면 LinkedIn에 로그인하세요.

다음 단계