다음을 통해 공유


서비스 컨테이너

Azure DevOps Services

이 문서에서는 Azure Pipelines에서 서비스 컨테이너를 사용하는 방법에 대해 설명합니다. 파이프라인에 하나 이상의 서비스를 지원해야 하는 경우 작업당 서비스를 만들고, 연결하고, 정리해야 할 수 있습니다. 예를 들어 파이프라인은 파이프라인의 각 작업에 대해 새로 만든 데이터베이스 및 메모리 캐시에 액세스해야 하는 통합 테스트를 실행할 수 있습니다.

서비스 컨테이너는 파이프라인에서 서비스를 실행하는 간단하고 이식 가능한 방법을 제공합니다. 서비스 컨테이너는 필요한 작업에서만 액세스할 수 있습니다.

서비스 컨테이너를 사용하면 파이프라인이 의존하는 서비스의 수명 주기를 자동으로 만들고, 네트워크를 만들고, 관리할 수 있습니다. 서비스 컨테이너는 모든 종류의 작업에서 작동하지만 컨테이너 작업에서 가장 일반적으로 사용됩니다.

참고

클래식 파이프라인은 서비스 컨테이너를 지원하지 않습니다.

조건 및 제한 사항

  • 서비스 컨테이너는 CMD 또는 ENTRYPOINT을 정의해야 합니다. 파이프라인은 제공된 컨테이너에 대한 인수 없이 실행됩니다 docker run .

  • Azure Pipelines는 Linux 또는 Windows 컨테이너를 실행할 수 있습니다. Linux 컨테이너용 호스트된 Ubuntu 풀 또는 Windows 컨테이너용 호스트된 Windows 풀을 사용합니다. 호스트된 macOS 풀은 컨테이너 실행을 지원하지 않습니다.

  • 서비스 컨테이너는 컨테이너 작업과 동일한 컨테이너 리소스를 공유하므로 동일한 시작 옵션을 사용할 수 있습니다.

  • 서비스 컨테이너가 HEALTHCHECK를 지정하는 경우 에이전트는 필요에 따라 컨테이너가 정상 상태가 될 때까지 기다렸다가 작업을 실행할 수 있습니다.

단일 컨테이너 작업

다음 예제 YAML 파이프라인은 서비스 컨테이너를 사용하는 단일 컨테이너 작업을 정의합니다. 파이프라인은 buildpack-depsnginx 컨테이너를 Docker Hub에서 가져오고, 그런 다음 모든 컨테이너를 시작합니다. 컨테이너는 네트워크로 연결되므로 이름으로 서로 services 연결할 수 있습니다.

작업 컨테이너 내부에서 nginx 호스트 이름은 Docker 네트워킹을 사용하여 올바른 서비스로 해결됩니다. 네트워크의 모든 컨테이너는 자동으로 모든 포트를 서로 노출합니다.

resources:
  containers:
  - container: my_container
    image: buildpack-deps:focal
  - container: nginx
    image: nginx

pool:
  vmImage: 'ubuntu-latest'

container: my_container
services:
  nginx: nginx

steps:
- script: |
    curl nginx
  displayName: Show that nginx is running

단일 비컨테이너 작업

비컨테이너 작업에서 서비스 컨테이너를 사용할 수도 있습니다. 파이프라인은 최신 컨테이너를 시작하지만 작업이 컨테이너에서 실행되지 않으므로 자동 이름 확인이 없습니다. 대신 localhost를 사용하여 서비스를 사용할 수 있습니다. 다음 예제 파이프라인은 nginx에 대한 8080:80 포트를 명시적으로 지정합니다.

다른 방법은 런타임에 동적으로 임의 포트를 할당하는 것입니다. 작업이 포트에 액세스할 수 있도록 파이프라인은 폼agent.services.<serviceName>.ports.<port>를 만듭니다. Bash 스크립트에서 이 환경 변수 를 사용하여 동적 포트에 액세스할 수 있습니다.

다음 파이프라인 redis 에서 호스트에서 임의의 사용 가능한 포트를 가져오고 변수에는 agent.services.redis.ports.6379 포트 번호가 포함됩니다.

resources:
  containers:
  - container: nginx
    image: nginx
    ports:
    - 8080:80
    env:
      NGINX_PORT: 80
  - container: redis
    image: redis
    ports:
    - 6379

pool:
  vmImage: 'ubuntu-latest'

services:
  nginx: nginx
  redis: redis

steps:
- script: |
    curl localhost:8080
    echo $AGENT_SERVICES_REDIS_PORTS_6379

여러 작업

서비스 컨테이너는 동일한 서비스의 여러 버전에 대해 동일한 단계를 실행하는 데에도 유용합니다. 다음 예제에서는 여러 버전의 PostgreSQL에 대해 동일한 단계를 실행합니다.

resources:
  containers:
  - container: my_container
    image: ubuntu:22.04
  - container: pg15
    image: postgres:15
  - container: pg14
    image: postgres:14

pool:
  vmImage: 'ubuntu-latest'

strategy:
  matrix:
    postgres15:
      postgresService: pg15
    postgres14:
      postgresService: pg14

container: my_container

services:
  postgres: $[ variables['postgresService'] ]
steps:
- script: printenv

포트

호스트에서 직접 실행되는 작업은 서비스 컨테이너에 액세스해야 합니다 ports . ports 동일한 Docker 네트워크의 컨테이너가 기본적으로 모든 포트를 서로 자동으로 노출하므로 작업이 컨테이너에서 실행되는 경우 지정할 필요가 없습니다.

포트는 <hostPort>:<containerPort>의 형태를 취하거나 단순히 <containerPort>에 선택적으로 /<protocol>가 추가된 형태일 수 있습니다. 예를 들어 6379/tcp는 호스트 컴퓨터의 임의의 포트에 바인딩된 tcp 포트를 통해 6379을 노출합니다.

컨테이너 리소스 또는 인라인 컨테이너를 호출할 때 다음 예제와 같이 컨테이너에 노출할 배열 ports 을 지정할 수 있습니다.

resources:
  containers:
  - container: my_service
    image: my_service:latest
    ports:
    - 8080:80
    - 5432

services:
  redis:
    image: redis
    ports:
    - 6379/tcp

호스트 컴퓨터의 임의 포트에 바인딩된 포트의 경우 파이프라인은 작업이 포트에 액세스할 수 있도록 양식 agent.services.<serviceName>.ports.<port> 의 변수를 만듭니다. 예를 들어 agent.services.redis.ports.6379 호스트 컴퓨터에서 임의로 할당된 포트로 해결됩니다.

볼륨

볼륨은 서비스 간에 데이터를 공유하거나 작업의 여러 실행 간에 데이터를 유지하는 데 유용합니다. 볼륨 마운트를 volumes 배열로 지정합니다.

각 볼륨은 호스트의 명명된 볼륨 또는 절대 경로인 형식 <source>:<destinationPath><source> 을 사용하며 <destinationPath> 컨테이너의 절대 경로입니다. 호스트에서 볼륨은 Docker 볼륨, 익명 Docker 볼륨 또는 바인드 마운트로 명명될 수 있습니다.

services:
  my_service:
    image: myservice:latest
    volumes:
    - mydockervolume:/data/dir
    - /data/dir
    - /src/dir:/dst/dir

참고

호스트 컴퓨터는 각 작업 후에 정리되므로 Microsoft 호스팅 풀은 작업 간에 볼륨을 유지하지 않습니다.

서비스 예제를 사용하는 여러 컨테이너

다음 예제 파이프라인에는 PostgreSQL 및 MySQL 데이터베이스 컨테이너에 연결된 Django Python 웹 컨테이너가 있습니다.

  • PostgreSQL 데이터베이스는 주 데이터베이스이며 해당 컨테이너의 이름은 지정 db됩니다.
  • 컨테이너는 db 볼륨 /data/db:/var/lib/postgresql/data을 사용하고 3개의 데이터베이스 변수를 통해 env컨테이너에 전달합니다.
  • 컨테이너는 mysql 포트 3306:3306를 사용하고, 데이터베이스 변수를 env를 통해 전달합니다.
  • 컨테이너가 web 포트 8000를 사용하여 열려 있습니다.

이 단계에서 pip 종속성을 설치한 다음 Django 테스트가 실행됩니다.

작업 예제를 설정하려면 두 개의 데이터베이스를 사용하여 Django 사이트를 설정해야 합니다. 이 예제에서는 manage.py 파일과 Django 프로젝트가 루트 디렉터리에 있다고 가정합니다. 그렇지 않은 경우 /__w/1/s/에서 /__w/1/s/manage.py test 경로를 업데이트해야 할 수 있습니다.

resources:
  containers:
    - container: db
      image: postgres
      volumes:
          - '/data/db:/var/lib/postgresql/data'
      env:
        POSTGRES_DB: postgres
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: postgres
    - container: mysql
      image: 'mysql:5.7'
      ports:
         - '3306:3306'
      env:
        MYSQL_DATABASE: users
        MYSQL_USER: mysql
        MYSQL_PASSWORD: mysql
        MYSQL_ROOT_PASSWORD: mysql
    - container: web
      image: python
      volumes:
      - '/code'
      ports:
        - '8000:8000'

pool:
  vmImage: 'ubuntu-latest'

container: web
services:
  db: db
  mysql: mysql

steps:
    - script: |
        pip install django
        pip install psycopg2
        pip install mysqlclient
      displayName: set up django
    - script: |
          python /__w/1/s/manage.py test