다음을 통해 공유


YAML 파이프라인의 컨테이너 작업

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

이 문서에서는 Azure Pipelines의 컨테이너 작업을 설명합니다.

기본적으로 Azure Pipelines 작업은 에이전트가 설치된 호스트 머신에서 직접 실행됩니다. 호스트된 에이전트 작업은 편리하고, 유지 관리하기 위한 초기 설정 및 인프라가 거의 필요하지 않으며, 기본 프로젝트에 적합합니다.

작업 컨텍스트를 더 자세히 제어하려면 컨테이너에서 작업을 정의하고 실행할 수 있습니다. 컨테이너는 호스트로부터 격리를 제공하는 호스트 운영 체제에 대한 간단한 추상화입니다. 컨테이너에서 작업을 실행할 때 빌드에 필요한 운영 체제, 도구 및 종속성의 정확한 버전을 선택할 수 있습니다.

Linux 및 Windows 에이전트는 호스트 또는 컨테이너에서 직접 파이프라인 작업을 실행할 수 있습니다. 컨테이너 작업은 macOS에서 사용할 수 없습니다.

컨테이너 작업의 경우 에이전트는 먼저 컨테이너를 가져오고 시작합니다. 그런 다음 작업의 각 단계가 컨테이너 내에서 실행됩니다.

개별 빌드 단계 수준에서 세분화된 제어가 필요한 경우 단계 대상을 통해 각 단계에 대한 컨테이너 또는 호스트를 선택할 수 있습니다.

필수 조건

  • YAML 파이프라인을 사용합니다. 클래식 파이프라인은 컨테이너 작업을 지원하지 않습니다.
  • 호스트된 Windows 또는 Ubuntu 에이전트를 사용합니다. windows-*ubuntu-* 에이전트만 컨테이너 실행을 지원합니다. 에이전트는 macos-* 컨테이너 실행을 지원하지 않습니다.
  • 에이전트가 컨테이너 작업에 대해 준비되었습니다.
    • Windows 및 Linux 에이전트에는 Docker가 설치되어 있어야 하며 Docker 디먼에 액세스할 수 있는 권한이 필요합니다.
    • 에이전트가 컨테이너 내에서 이미 실행 중인 경우 컨테이너는 지원되지 않습니다. 중첩된 컨테이너는 사용할 수 없습니다.

추가 컨테이너 요구 사항

Linux 기반 컨테이너에는 다음과 같은 요구 사항이 있습니다. 해결 방법은 Nonglibc 기반 컨테이너를 참조 하세요.

  • Bash 설치됨
  • GNU C 라이브러리(glibc) 기반
  • ENTRYPOINT 아님
  • USERgroupadd 및 기타 권한 있는 명령에 대한 액세스를 제공하되 sudo를 사용하지 않음
  • 에이전트가 제공하는 Node.js 실행할 수 있습니다.

    참고

    Node.js Windows 호스트의 Linux 컨테이너용으로 미리 설치해야 합니다.

Docker 허브에서 사용할 수 있는 일부 제거된 컨테이너, 특히 Alpine Linux 기반 컨테이너는 이러한 요구 사항을 충족하지 않습니다. ENTRYPOINT이 포함된 컨테이너는 docker createdocker exec이 컨테이너가 항상 실행 중일 것으로 예상하기 때문에 작동하지 않을 수 있습니다.

단일 작업 예제

다음 예제에서는 단일 작업에 대한 Windows 또는 Linux 컨테이너를 정의합니다.

다음 간단한 예제에서는 Linux 컨테이너를 정의합니다.

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

앞의 예제에서는 Docker Hububuntu태그가 지정된 18.04 이미지를 가져온 다음 컨테이너를 시작하도록 시스템에 지시합니다. printenv 명령은 ubuntu:18.04 컨테이너 안에서 실행됩니다.

여러 작업

컨테이너를 사용하여 여러 작업에서 동일한 단계를 실행할 수 있습니다. 다음 예제에서는 여러 버전의 Ubuntu Linux에서 동일한 단계를 실행합니다. 단일 작업만 정의되므로 키워드를 언급 jobs 할 필요가 없습니다.

pool:
  vmImage: 'ubuntu-latest'

strategy:
  matrix:
    ubuntu16:
      containerImage: ubuntu:16.04
    ubuntu18:
      containerImage: ubuntu:18.04
    ubuntu20:
      containerImage: ubuntu:20.04

container: $[ variables['containerImage'] ]

steps:
- script: printenv

단일 에이전트 호스트에서 에이전트 풀과 함께하는 여러 작업

컨테이너 작업은 이미지 레지스트리 권한 부여를 위해 기본 호스트 에이전트의 Docker 구성 파일을 사용합니다. 이 파일은 Docker 레지스트리 컨테이너 초기화가 끝날 때 로그아웃합니다. 병렬로 실행되는 다른 작업이 이미 Docker 구성 파일을 로그아웃했기 때문에 후속 컨테이너 작업에 대한 unauthorized authentication 레지스트리 이미지 끌어오기는 거부될 수 있습니다.

솔루션은 호스트된 에이전트에서 실행되는 각 에이전트 풀과 관련된 Docker 환경 변수 DOCKER_CONFIG 를 설정하는 것입니다. DOCKER_CONFIG 다음과 같이 각 에이전트 풀의 runsvc.sh 스크립트에서 내보냅니다.

export DOCKER_CONFIG=./.docker

시작 옵션

다음 예제와 같이 컨테이너 시작을 제어하도록 지정할 options 수 있습니다.

container:
  image: ubuntu:18.04
  options: --hostname container-test --ip 192.168.0.1

steps:
- script: echo hello

실행 docker create --help 하면 Docker 호출에 전달할 수 있는 옵션 목록이 제공됩니다. 이러한 모든 옵션이 Azure DevOps에서 작동하도록 보장되는 것은 아닙니다. 먼저 속성을 사용하여 container 동일한 목표를 달성할 수 있는지 확인합니다.

자세한 내용은 Azure DevOps YAML 스키마 참조의 docker create 명령 참조 및 resources.containers.container 정의를 참조하세요.

재사용 가능한 컨테이너 정의

다음 예제에서는 섹션의 컨테이너를 resources 정의한 다음 할당된 별칭으로 참조합니다. jobs 명확하게 하기 위해 키워드가 명시적으로 나열됩니다.

resources:
  containers:
  - container: u16
    image: ubuntu:16.04

  - container: u18
    image: ubuntu:18.04

  - container: u20
    image: ubuntu:20.04

jobs:
- job: RunInContainer
  pool:
    vmImage: 'ubuntu-latest'

  strategy:
    matrix:
      ubuntu16:
        containerResource: u16
      ubuntu18:
        containerResource: u18
      ubuntu20:
        containerResource: u20

  container: $[ variables['containerResource'] ]

  steps:
  - script: printenv

서비스 엔드포인트

공용 Docker 허브가 아닌 다른 레지스트리에서 컨테이너를 호스트할 수 있습니다. Azure Container Registry 또는 프라이빗 Docker Hub 레지스트리를 포함한 다른 프라이빗 컨테이너 레지스트리에서 이미지를 호스트하려면 레지스트리에 액세스하기 위한 서비스 연결을 추가합니다. 그런 다음 컨테이너 정의에서 엔드포인트를 참조할 수 있습니다.

프라이빗 Docker 허브 연결:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Azure Container Registry 연결:

container:
  image: myprivate.azurecr.io/windowsservercore:1803
  endpoint: my_acr_connection

참고

Amazon ECR은 AWS 자격 증명을 Docker가 인증하는 데 사용할 수 있는 항목으로 변환하기 위해 다른 클라이언트 도구가 필요하기 때문에 Azure Pipelines는 ECR(Amazon Elastic Container Registry)에 대한 서비스 연결을 설정할 수 없습니다.

Nonglibc 기반 컨테이너

Azure Pipelines 에이전트는 작업 및 스크립트를 실행하는 데 필요한 Node.js 복사본을 제공합니다. 호스트된 에이전트에 대한 Node.js 버전을 확인하려면 Microsoft 호스팅 에이전트를 참조 하세요.

Node.js 버전은 호스트된 클라우드에서 사용되는 C 런타임(일반적으로 glibc)에 대해 컴파일됩니다. 일부 Linux 변형은 다른 C 런타임을 사용합니다. 예를 들어 Alpine Linux는 musl을 사용합니다.

nonglibc 기반 컨테이너를 사용하려면 다음을 수행해야 합니다.

  • 고유한 Node.js 복사본을 제공합니다.
  • Node.js 이진 파일을 찾을 위치를 에이전트에 알리는 레이블을 이미지에 추가합니다.
  • Azure Pipelines에서 종속되는 다른 종속성을 제공합니다. bashsudowhichgroupadd

고유한 Node.js 제공

nonglibc 기반 컨테이너를 사용하는 경우 컨테이너에 노드 이진 파일을 추가할 책임이 있습니다. Node.js 18은 안전한 선택입니다. node:18-alpine 이미지에서 시작합니다.

에이전트에 Node.js 대해 알려주세요.

에이전트가 컨테이너 레이블 "com.azure.dev.pipelines.handler.node.path"을 읽습니다. 이 레이블이 있는 경우 Node.js 이진 파일의 경로여야 합니다.

예를 들어 node:18-alpine을(를) 기반으로 한 이미지에서 Dockerfile에 다음 줄을 추가합니다.

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

필수 패키지 추가

Azure Pipelines는 일반적인 관리 패키지가 설치된 Bash 기반 시스템을 가정합니다. 특히 Alpine Linux에는 필요한 몇 가지 패키지가 제공되지 않습니다. bash, sudo, 및 shadow를 설치하여 기본 요구 사항을 충족하도록 합니다.

RUN apk add bash sudo shadow

기본 제공 또는 Marketplace 작업에 의존하는 경우 필요한 이진 파일도 제공합니다.

전체 Dockerfile 예제

FROM node:18-alpine

RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \
  && apk add bash sudo shadow \
  && apk del .pipeline-deps

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

CMD [ "node" ]