YAML(컨테이너 작업) 정의

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

기본적으로 작업은에이전트 가 설치된 호스트 컴퓨터에서 실행됩니다. 이는 Azure Pipelines를 채택하기 시작한 프로젝트에 편리하고 일반적으로 적합합니다. 시간이 지남에 따라 태스크가 실행되는 컨텍스트를 보다 세세하게 제어할 수 있습니다. YAML 파이프라인은 이 수준의 제어에 대한 컨테이너 작업을 제공합니다.

Linux 및 Windows 에이전트에서 작업은 호스트 또는 컨테이너에서 실행될 수 있습니다. (macOS 및 Red Hat Enterprise Linux 6에서는 컨테이너 작업을 사용할 수 없습니다.) 컨테이너는 호스트에서 격리를 제공하며 특정 버전의 도구 및 종속성을 고정할 수 있습니다. 호스트 작업에는 유지 관리하기 위한 초기 설정 및 인프라가 덜 필요합니다.

컨테이너는 호스트 운영 체제를 통해 간단한 추상화가 제공됩니다. 빌드에 필요한 운영 체제, 도구 및 종속성의 정확한 버전을 선택할 수 있습니다. 파이프라인에서 컨테이너를 지정하면 에이전트가 먼저 컨테이너를 가져와서 시작합니다. 그런 다음, 작업의 각 단계가 컨테이너 내에서 실행됩니다. 중첩된 컨테이너는 사용할 수 없습니다. 에이전트가 이미 컨테이너 내에서 실행 중인 경우 컨테이너는 지원되지 않습니다.

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

요구 사항

Linux 기반 컨테이너

Azure Pipelines 시스템에는 Linux 기반 컨테이너에 몇 가지 사항이 필요합니다.

  • Bash
  • glibc 기반
  • Node.js 실행할 수 있음(에이전트가 제공하는)
  • 를 정의하지 않습니다. ENTRYPOINT
  • USER 에 대한 액세스 권한 groupadd 및 기타 권한 명령이 없는 경우 sudo

에이전트 호스트에서 다음을 수행합니다.

  • Docker가 설치되어 있는지 확인
  • 에이전트에 Docker 디먼에 액세스할 수 있는 권한이 있어야 합니다.

컨테이너에 이러한 각 도구를 사용할 수 있는지 확인합니다. Docker Hub 사용할 수 있는 제거된 컨테이너 중 일부, 특히 Alpine Linux를 기반으로 하는 컨테이너는 이러한 최소 요구 사항을 충족하지 않습니다. Azure Pipelines ENTRYPOINTdocker create 대기 중인 컨테이너와 docker exec 컨테이너가 항상 실행될 것으로 예상되는 일련의 명령을 실행하므로 컨테이너가 작동하지 않을 수 있습니다.

참고

Windows 기반 Linux 컨테이너의 경우 Node.js 미리 설치해야 합니다.

Windows 컨테이너

Azure Pipelines는 Windows 컨테이너를 실행할 수도 있습니다. Windows Server 버전 1803 이상이 필요합니다. Docker를 설치해야 합니다. 파이프라인 에이전트에 Docker 디먼에 액세스할 수 있는 권한이 있는지 확인합니다.

Windows 컨테이너는 Node.js 실행을 지원해야 합니다. 기본 Windows Nano Server 컨테이너에 노드를 실행하는 데 필요한 종속성이 없습니다.

호스트된 에이전트

ubuntu-* 이미지만 windows-2019 컨테이너 실행을 지원합니다. macOS 이미지는 컨테이너 실행을 지원하지 않습니다.

단일 작업

간단한 예는 다음과 같습니다.

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

그러면 시스템에서 Docker Hub 태그가 ubuntu 지정된 18.04 이미지를 가져온 다음 컨테이너를 시작하도록 지시합니다. 명령이 printenv 실행되면 컨테이너 내에서 ubuntu:18.04 발생합니다.

Windows 예제:

pool:
  vmImage: 'windows-2019'

container: mcr.microsoft.com/windows/servercore:ltsc2019

steps:
- script: set

참고

Windows에서는 호스트 및 컨테이너의 커널 버전이 일치해야 합니다. 이 예제에서는 Windows 2019 이미지를 사용하므로 컨테이너에 2019 대한 태그를 사용합니다.

여러 작업

컨테이너는 여러 작업에서 동일한 단계를 실행하는 데에도 유용합니다. 다음 예제에서는 동일한 단계가 여러 버전의 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 Hub 레지스트리 이외의 레지스트리에서 호스트할 수 있습니다. Azure Container Registry 또는 다른 프라이빗 컨테이너 레지스트리(프라이빗 Docker Hub 레지스트리 포함)에서 이미지를 호스트하려면 프라이빗 레지스트리에 서비스 연결을 추가합니다. 그런 다음 컨테이너 사양에서 참조할 수 있습니다.

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

steps:
- script: echo hello

또는

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

steps:
- script: echo hello

다른 컨테이너 레지스트리도 작동할 수 있습니다. AWS 자격 증명을 Docker가 인증하는 데 사용할 수 있는 항목으로 변환하는 데 필요한 다른 클라이언트 도구가 있으므로 Amazon ECR은 현재 작동하지 않습니다.

참고

에이전트의 Red Hat Enterprise Linux 6 빌드는 컨테이너 작업을 실행하지 않습니다. Red Hat Enterprise Linux 7 이상과 같은 다른 Linux 버전을 선택합니다.

옵션

컨테이너 시작을 options제어해야 하는 경우 .

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

steps:
- script: echo hello

실행 docker create --help 하면 지원되는 옵션 목록이 제공됩니다. 명령과 함께 docker create사용할 수 있는 모든 옵션을 사용할 수 있습니다.

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

다음 예제에서는 컨테이너가 리소스 섹션에 정의되어 있습니다. 그런 다음 각 컨테이너는 할당된 별칭을 참조하여 나중에 참조됩니다. (여기서는 명확성을 위해 키워드를 명시적으로 나열합니다 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

비 glibc 기반 컨테이너

Azure Pipelines 에이전트는 작업 및 스크립트를 실행하는 데 필요한 Node.js 복사본을 제공합니다. Node.js 버전은 호스트된 클라우드에서 사용하는 C 런타임(일반적으로 glibc)에 대해 컴파일됩니다. Linux의 일부 변형은 다른 C 런타임을 사용합니다. 예를 들어 Alpine Linux는 musl을 사용합니다.

glibc 기반이 아닌 컨테이너를 작업 컨테이너로 사용하려는 경우 몇 가지를 직접 정렬해야 합니다. 먼저 고유한 Node.js 복사본을 제공해야 합니다. 둘째, Node.js 이진 파일을 찾을 위치를 에이전트에 알리는 레이블을 이미지에 추가해야 합니다. 마지막으로, Stock Alpine은 Azure Pipelines가 종속하는 다른 종속성인 bash, sudo, 및 groupadd와 함께 제공되지 않습니다.

사용자 고유의 Node.js 가져오기

컨테이너에 노드 이진 파일을 추가할 책임이 있습니다. 노드 14는 안전한 선택입니다. 이미지에서 node:14-alpine 시작할 수 있습니다.

에이전트에 Node.js

에이전트는 컨테이너 레이블 "com.azure.dev.pipelines.handler.node.path"를 읽습니다. 이 레이블이 있는 경우 Node.js 이진 파일의 경로여야 합니다. 예를 들어 기반 이미지에서 Dockerfile에 node:10-alpine다음 줄을 추가합니다.

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

요구 사항 추가

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

RUN apk add bash sudo shadow

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

Dockerfile의 전체 예제

FROM node:10-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" ]

호스트된 단일 에이전트에서 에이전트 풀이 있는 여러 작업

컨테이너 작업은 Docker 레지스트리 컨테이너 초기화가 끝날 때 로그아웃되는 이미지 레지스트리 권한 부여에 기본 호스트 에이전트 Docker config.json을 사용합니다. 인증을 위해 시스템에 등록된 Docker config.json 파일이 병렬로 실행되는 다른 컨테이너 작업 중 하나에서 이미 로그아웃되었으므로 후속 레지스트리 이미지 끌어오기 권한 부여가 "권한 없는 인증"에 대해 거부될 수 있습니다.

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

#insert anything to set up env when running as a service
export DOCKER_CONFIG=./.docker