다음을 통해 공유


Azure Batch를 사용하여 컨테이너 워크로드 실행

Azure Batch를 사용하면 Azure에서 많은 수의 일괄 처리 계산 작업을 실행하고 확장할 수 있습니다. Batch 작업은 Batch 풀의 가상 머신(노드)에서 직접 실행할 수 있지만, 노드의 Docker 호환 컨테이너에서 작업을 실행하도록 Batch 풀을 설정할 수도 있습니다. 이 문서에서는 컨테이너 작업의 실행을 지원하는 컴퓨팅 노드 풀을 만드는 방법과 풀에서 컨테이너 작업을 실행하는 방법을 보여 줍니다.

여기에서 코드 예제는 Batch .NET 및 Python SDK를 사용합니다. Azure Portal을 포함하여 다른 Batch SDK 및 도구를 사용하여 컨테이너 사용이 가능한 Batch 풀을 만들고 컨테이너 작업을 실행할 수도 있습니다.

컨테이너를 사용하는 이유

컨테이너는 애플리케이션 실행을 위한 환경 및 종속성을 관리할 필요 없이 Batch 작업을 실행하는 쉬운 방법을 제공합니다. 컨테이너는 애플리케이션을 다양한 환경에서 실행될 수 있는 이식이 가능한 일체형 경량 단위로 배포합니다. 예를 들어, 컨테이너를 로컬로 빌드 및 테스트한 다음, Azure의 레지스트리 또는 다른 위치로 컨테이너 이미지를 업로드할 수 있습니다. 컨테이너 배포 모델은 애플리케이션을 호스트하는 어느 곳이든 애플리케이션의 런타임 환경이 항상 올바르게 설치 및 구성되도록 합니다. Batch의 컨테이너 기반 작업은 리소스 파일 및 출력 파일 관리, 애플리케이션 패키지 등 컨테이너가 아닌 작업의 기능을 활용할 수도 있습니다.

필수 조건

컨테이너 개념과 Batch 풀 및 Batch 작업을 만드는 방법을 잘 알고 있어야 합니다.

  • SDK 버전: Batch SDK에서 지원하는 컨테이너 이미지의 버전은 다음과 같습니다.

    • Batch REST API 버전 2017-09-01.6.0
    • Batch .NET SDK 버전 8.0.0
    • Batch Python SDK 버전 4.0
    • Batch Java SDK 버전 3.0
    • Batch Node.js SDK 버전 3.0
  • 계정: Azure 구독에서 Batch 계정을 만들고, 필요에 따라 Azure Storage 계정도 만들어야 합니다.

  • 지원되는 VM(가상 머신) 이미지: 컨테이너는 지원되는 이미지(다음 섹션에 나열됨)에서 가상 머신 구성으로 만들어진 풀에서만 지원됩니다. 사용자 지정 이미지를 제공하는 경우 다음 섹션의 고려 사항과 관리 이미지를 사용하여 사용자 지정 이미지 풀 만들기의 요구 사항을 참조하세요.

참고 항목

Batch SDK 버전에서:

  • Batch .NET SDK 버전 16.0.0
  • Batch Python SDK 버전 14.0.0
  • Batch Java SDK 버전 11.0.0
  • Batch Node.js SDK 버전 11.0.0

현재 containerConfiguration에는 Type 속성이 전달되어야 하며 지원되는 값은 ContainerType.DockerCompatibleContainerType.CriCompatible입니다.

다음 제한 사항에 유의합니다.

  • Batch는 Linux 풀에서 실행되는 컨테이너에 대해서만 RDMA(원격 직접 메모리 액세스) 지원을 제공합니다.
  • Windows 컨테이너 워크로드의 경우 풀에 대한 다중 코어 VM 크기를 선택해야 합니다.

Important

Docker는 기본적으로 172.17.0.0/16의 서브넷 사양을 사용하여 네트워크 브리지를 만듭니다. 풀에 대한 가상 네트워크를 지정하는 경우 충돌하는 IP 범위가 없는지 확인합니다.

지원되는 VM 이미지

컨테이너 워크로드에 대한 VM 컴퓨팅 노드 풀을 만들려면 다음 지원되는 Windows 또는 Linux 이미지 중 하나를 사용합니다. Batch와 호환되는 Marketplace 이미지에 대한 자세한 내용은 가상 머신 이미지 목록을 참조하세요.

Windows 지원

Batch는 컨테이너 지원 지정이 있는 Windows 서버 이미지를 지원합니다. 지원되는 모든 이미지를 Batch로 나열하는 API는 이미지가 Docker 컨테이너를 지원하는 경우 DockerCompatible 기능을 나타냅니다. Batch는 DockerCompatible로 표시된 기능을 통해 Mirantis에서 게시한 이미지를 허용하지만 직접 지원하지는 않습니다. 이러한 이미지는 사용자 구독 풀 할당 모드 Batch 계정으로만 배포할 수 있습니다.

Windows에서 컨테이너 기능을 사용 설정하는 사용자 지정 이미지를 만들 수도 있습니다.

참고 항목

이미지 SKU -with-containers 또는 -with-containers-smalldisk가 사용 중지됩니다. 자세한 내용 및 대체 컨테이너 런타임 옵션은 공지 참조하세요.

Linux 지원

Linux 컨테이너 워크로드의 경우 현재 Batch는 사용자 지정 이미지 없이 Azure Marketplace에 게시된 다음 Linux 이미지를 지원합니다.

  • 게시자: microsoft-dsvm
    • 제품: ubuntu-hpc
  • 게시자: almalinux
    • 제품: 8-hpc-gen1
    • 제품: 8-hpc-gen2

대체 이미지 옵션

현재 컨테이너 워크로드를 지원하는 다른 이미지를 microsoft-azure-batch에서 게시했습니다.

  • 게시자: microsoft-azure-batch
    • 제품: ubuntu-server-container
    • 제품: ubuntu-server-container-rdma(Infiniband를 사용하는 VM SKU에서만 사용)

Warning

microsoft-azure-batch에서 게시한 이미지 외의 이미지는 곧 이미지 수명이 종료되어 더 이상 사용할 수 없으므로 다른 이미지를 사용하는 것이 좋습니다.

주의

위 이미지의 Docker 데이터 루트는 다른 위치에 있습니다.

  • HPC 이미지 또는 microsoft-dsvm(제품: ubuntu-hpc 등)에 대해 Docker 데이터 루트는 Linux의 경우 /var/lib/docker, Windows의 경우 C:\ProgramData\Docker인 Docker 기본값에서 변경되지 않습니다. 이러한 폴더는 OS 디스크에 있습니다.

비 Batch 게시 이미지의 경우 컨테이너 이미지가 다운로드될 때 OS 디스크가 빠르게 채워질 위험이 있습니다.

고객을 위한 잠재적인 솔루션

BatchExplorer에서 풀을 만들 때 시작 작업에서 Docker 데이터 루트를 변경합니다. 다음은 작업 시작 명령의 예입니다.

1)  sudo systemctl stop docker
2)  sudo vi /lib/systemd/system/docker.service
    +++
    FROM:
    ExecStart=/usr/bin/docker daemon -H fd://
    TO:
    ExecStart=/usr/bin/docker daemon -g /new/path/docker -H fd://
    +++
3)  sudo systemctl daemon-reload
4)  sudo systemctl start docker

이러한 이미지는 Azure Batch 풀에서만 사용할 수 있으며 Docker 컨테이너 실행에 적합합니다. 특징은 다음과 같습니다.

  • 사전 설치된 Docker 호환 Moby 컨테이너 런타임.
  • Azure N 시리즈 VM의 배포를 간소화하기 위해 사전 설치된 NVIDIA GPU 드라이버 및 NVIDIA 컨테이너.
  • 접미사가 -rdma인 VM 이미지는 InfiniBand RDMA VM 크기를 지원하도록 미리 구성됩니다. 이러한 VM 이미지는 InfiniBand를 지원하지 않는 VM 크기와 함께 사용하면 안 됩니다.

Batch와 호환되는 Linux 배포판 중 하나에서 Batch와 호환되는 사용자 지정 이미지를 만들 수도 있습니다. 사용자 지정 이미지에 대한 Docker 지원을 위해 Docker 버전 또는 Mirantis Container Runtime과 같이 적합한 Docker 호환 런타임을 설치합니다. Docker-CLI 호환 도구만 설치하는 것은 충분하지 않습니다. Docker 엔진 호환 런타임이 필요합니다.

Important

Microsoft 또는 Azure Batch는 Docker(모든 버전 또는 버전), Mirantis Container Runtime 또는 Moby 런타임과 관련된 문제에 대한 지원을 제공하지 않습니다. 이미지에서 이러한 런타임을 사용하도록 선택하려는 고객은 런타임 문제에 대한 지원을 제공하는 회사 또는 엔터티에 문의해야 합니다.

사용자 지정 Linux 이미지를 사용하기 위한 추가 고려 사항:

  • 사용자 지정 이미지 사용 시 Azure N-시리즈 크기의 GPU 성능을 활용하려면 NVIDIA 드라이버를 사전 설치합니다. 또한 NVIDIA GPU용 Docker 엔진 유틸리티인 NVIDIA Docker를 설치해야 합니다.
  • Azure RDMA 네트워크에 액세스하려면 RDMA 가능 VM 크기를 사용합니다. 필수 RDMA 드라이버는 Batch에서 지원되는 CentOS HPC 및 Ubuntu 이미지에 설치됩니다. MPI 워크로드를 실행하기 위한 추가 구성이 필요할 수 있습니다. Batch 풀에서 RDMA 또는 GPU 인스턴스 사용을 참조하세요.

Batch 풀에 대한 컨테이너 구성

Batch 풀을 사용하여 컨테이너 워크로드를 실행하려면 해당 풀의 VirtualMachineConfiguration 개체에서 ContainerConfiguration 설정을 지정해야 합니다. 이 문서는 Batch .NET API 참조에 대한 링크를 제공합니다. 해당 설정은 Batch Python API에 있습니다.

다음 예제와 같이 프리페치된 컨테이너 이미지를 사용하거나 사용하지 않고 컨테이너 지원 풀을 만들 수 있습니다. 끌어오기(또는 프리페치) 프로세스를 사용하면 Docker 허브 또는 인터넷의 다른 컨테이너 레지스트리에서 컨테이너 이미지를 미리 로드할 수 있습니다. 최상의 성능을 위해 Batch 계정과 동일한 영역의 Azure Container Registry를 사용합니다.

컨테이너 이미지를 프리페치할 때의 장점은 작업을 처음 실행하기 시작할 때 컨테이너 이미지가 다운로드될 때까지 기다릴 필요가 없다는 것입니다. 컨테이너 구성은 풀이 생성될 때 컨테이너 이미지를 VM으로 끌어옵니다. 그러면 풀에서 실행되는 작업은 컨테이너 이미지 및 컨테이너 실행 옵션 목록을 참조할 수 있습니다.

참고 항목

Docker Hub는 이미지 끌어오기 횟수를 제한합니다. Docker Hub 기반 이미지에 대한 워크로드가 게시된 속도 제한을 초과하지 않는지 확인합니다. Azure Container Registry를 직접 사용하거나 ACR의 아티팩트 캐시를 활용하는 것이 좋습니다.

프리페치된 컨테이너 이미지 없는 풀

프리페치된 컨테이너 이미지 없이 컨테이너 지원 풀을 구성하려면 다음 예제와 같이 ContainerConfigurationVirtualMachineConfiguration 개체를 정의합니다. 이 예제에서는 Marketplace에서 Azure Batch 컨테이너 풀 이미지의 Ubuntu Server를 사용합니다.

참고: 예제에서 사용되는 Ubuntu 서버 버전은 설명을 위해 제공된 것입니다. node_agent_sku_id를 사용 중인 버전으로 자유롭게 변경할 수 있습니다.

image_ref_to_use = batch.models.ImageReference(
    publisher='microsoft-dsvm',
    offer='ubuntu-hpc',
    sku='2204',
    version='latest')

"""
Specify container configuration. This is required even though there are no prefetched images.
"""

container_conf = batch.models.ContainerConfiguration()

new_pool = batch.models.PoolAddParameter(
    id=pool_id,
    virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
        image_reference=image_ref_to_use,
        container_configuration=container_conf,
        node_agent_sku_id='batch.node.ubuntu 22.04'),
    vm_size='STANDARD_D2S_V3',
    target_dedicated_nodes=1)
...
ImageReference imageReference = new ImageReference(
    publisher: "microsoft-dsvm",
    offer: "ubuntu-hpc",
    sku: "2204",
    version: "latest");

// Specify container configuration. This is required even though there are no prefetched images.
ContainerConfiguration containerConfig = new ContainerConfiguration();

// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;

// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    targetDedicatedComputeNodes: 1,
    virtualMachineSize: "STANDARD_D2S_V3",
    virtualMachineConfiguration: virtualMachineConfiguration);

컨테이너 구성을 위해 이미지 프리페치

컨테이너 이미지를 풀에 프리페치하려면 컨테이너 이미지 목록(container_image_names, Python에서)을 ContainerConfiguration에 추가합니다.

다음 기본 Python 예제는 Docker 허브에서 표준 Ubuntu 컨테이너 이미지를 프리페치하는 방법을 보여 줍니다.

image_ref_to_use = batch.models.ImageReference(
    publisher='microsoft-dsvm',
    offer='ubuntu-hpc',
    sku='2204',
    version='latest')

"""
Specify container configuration, fetching the official Ubuntu container image from Docker Hub.
"""

container_conf = batch.models.ContainerConfiguration(
    container_image_names=['ubuntu'])

new_pool = batch.models.PoolAddParameter(
    id=pool_id,
    virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
        image_reference=image_ref_to_use,
        container_configuration=container_conf,
        node_agent_sku_id='batch.node.ubuntu 22.04'),
    vm_size='STANDARD_D2S_V3',
    target_dedicated_nodes=1)
...

다음 C# 예제에서는 Docker 허브에서 TensorFlow 이미지를 프리페치한다고 가정합니다. 이 예에는 풀 노드의 VM 호스트에서 실행되는 시작 작업이 포함되어 있습니다. 예를 들어 컨테이너에서 액세스할 수 있는 파일 서버를 탑재하려는 경우 호스트에서 시작 작업을 실행할 수 있습니다.

ImageReference imageReference = new ImageReference(
    publisher: "microsoft-dsvm",
    offer: "ubuntu-hpc",
    sku: "2204",
    version: "latest");

ContainerRegistry containerRegistry = new ContainerRegistry(
    registryServer: "https://hub.docker.com",
    identityReference: new ComputeNodeIdentityReference() { ResourceId = "/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name" }
);

// Specify container configuration, prefetching Docker images
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> { "tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry };

// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;

// Set a native host command line start task
StartTask startTaskContainer = new StartTask( commandLine: "<native-host-command-line>" );

// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    virtualMachineSize: "Standard_NC6S_V3",
    virtualMachineConfiguration: virtualMachineConfiguration);

// Start the task in the pool
pool.StartTask = startTaskContainer;
...

프라이빗 컨테이너 레지스트리에서 이미지 프리페치

프라이빗 컨테이너 레지스트리 서버에서 인증을 받아 컨테이너 이미지를 프리페치할 수도 있습니다. 다음 예제에서는 ContainerConfigurationVirtualMachineConfiguration 개체가 프라이빗 Azure Container Registry에서 프라이빗 TensorFlow 이미지를 프리페치한다고 가정합니다. 이미지 참조는 앞의 예와 동일합니다.

image_ref_to_use = batch.models.ImageReference(
    publisher='microsoft-dsvm',
    offer='ubuntu-hpc',
    sku='2204',
    version='latest')

# Specify a container registry
subscription_id = "yyyy-yyy-yyy-yyy-yyy"
resource_group_name = "TestRG"
user_assigned_identity_name = "testUMI"
resource_id = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{user_assigned_identity_name}"

container_registry = batch.models.ContainerRegistry(
        registry_server="myRegistry.azurecr.io",
        identity_reference = ComputeNodeIdentityReference(resource_id = resource_id))

# Create container configuration, prefetching Docker images from the container registry
container_conf = batch.models.ContainerConfiguration(
        container_image_names = ["myRegistry.azurecr.io/samples/myImage"],
        container_registries =[container_registry])

new_pool = batch.models.PoolAddParameter(
            id="myPool",
            virtual_machine_configuration=batch.models.VirtualMachineConfiguration(
                image_reference=image_ref_to_use,
                container_configuration=container_conf,
                node_agent_sku_id='batch.node.ubuntu 22.04'),
            vm_size='STANDARD_D2S_V3',
            target_dedicated_nodes=1)
// Specify a container registry
ContainerRegistry containerRegistry = new ContainerRegistry(
    registryServer: "myContainerRegistry.azurecr.io",
    identityReference: new ComputeNodeIdentityReference() { ResourceId = "/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name" }
);

// Create container configuration, prefetching Docker images from the container registry
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> {
        "myContainerRegistry.azurecr.io/tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry } );

// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;

// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    targetDedicatedComputeNodes: 2,
    virtualMachineSize: "Standard_NC6S_V3",
    virtualMachineConfiguration: virtualMachineConfiguration);
...

ACR에 대한 관리 ID 지원

Azure Container Registry에 저장된 컨테이너에 액세스하는 경우 관리 ID를 사용하여 서비스를 인증할 수 있습니다. 관리 ID를 사용하려면 먼저 ID가 풀에 할당되었는지, ID에 액세스하려는 컨테이너 레지스트리에 할당된 AcrPull 역할이 있는지 확인합니다. 그런 다음, ACR을 사용하여 인증할 때 사용할 ID를 Batch에 알립니다.

ContainerRegistry containerRegistry = new ContainerRegistry(
    registryServer: "myContainerRegistry.azurecr.io",
    identityReference: new ComputeNodeIdentityReference() { ResourceId = "/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name" }
);

// Create container configuration, prefetching Docker images from the container registry
ContainerConfiguration containerConfig = new ContainerConfiguration();
containerConfig.ContainerImageNames = new List<string> {
        "myContainerRegistry.azurecr.io/tensorflow/tensorflow:latest-gpu" };
containerConfig.ContainerRegistries = new List<ContainerRegistry> { containerRegistry } );

// VM configuration
VirtualMachineConfiguration virtualMachineConfiguration = new VirtualMachineConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04");
virtualMachineConfiguration.ContainerConfiguration = containerConfig;

// Create pool
CloudPool pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    targetDedicatedComputeNodes: 2,
    virtualMachineSize: "Standard_NC6S_V3",
    virtualMachineConfiguration: virtualMachineConfiguration);
...

작업(task)에 대한 컨테이너 설정

컨테이너 사용 풀에서 컨테이너 작업을 실행하려면 컨테이너별 설정을 지정합니다. 설정에는 사용할 이미지, 레지스트리 및 컨테이너 실행 옵션이 포함됩니다.

  • 작업 클래스의 ContainerSettings 속성을 사용하여 컨테이너별 설정을 구성합니다. 이러한 설정은 TaskContainerSettings 클래스에 의해 정의됩니다. --rm 컨테이너 옵션은 Batch에 의해 처리되므로 다른 --runtime 옵션이 필요하지 않습니다.

  • 컨테이너 이미지에 대해 작업(task)를 실행하는 경우 클라우드 작업(task)작업(Job) 관리자 작업(task)에 컨테이너 설정이 필요합니다. 그러나 시작 태스크, 작업(Job) 준비 작업(task)작업(Job) 릴리스 작업(task)에는 컨테이너 설정이 필요하지 않습니다(즉, 컨테이너 컨텍스트 내에서 또는 노드에서 직접 실행될 수 있음).

  • Linux의 경우 Batch는 사용자/그룹 권한을 컨테이너에 매핑합니다. 컨테이너 내의 폴더에 액세스할 때 관리자 권한이 필요한 경우 관리자 권한 상승 수준인 풀 범위로 작업을 실행해야 할 수 있습니다. 이렇게 하면 Batch가 컨테이너 컨텍스트에서 루트로 작업을 실행합니다. 그렇지 않으면 관리자가 아닌 사용자가 해당 폴더에 액세스하지 못할 수도 있습니다.

  • GPU 지원 하드웨어가 있는 컨테이너 풀의 경우 Batch는 컨테이너 작업에 대해 GPU를 자동으로 사용하도록 설정하므로 –gpus 인수를 포함하면 안 됩니다.

컨테이너 작업 명령줄

컨테이너 작업을 실행하면 Batch에서 docker create 명령을 사용하여 작업에 지정된 이미지를 사용하여 컨테이너를 생성합니다. 그런 다음, Batch는 컨테이너의 작업 실행을 제어합니다.

컨테이너가 아닌 Batch 작업을 사용하여 컨테이너 작업에 대한 명령줄을 설정합니다. Batch에서 자동으로 컨테이너를 만들기 때문에 명령줄은 컨테이너에서 실행되는 명령만 지정합니다.

다음은 Batch가 Docker 컨테이너 태스크에 적용하는 기본 동작입니다.

컨테이너 이미지에 지정된 ENTRYPOINT가 있고 태스크 명령줄을 지정하는 경우 발생할 수 있는 상호 작용 효과를 이해하려면 ENTRYPOINT와 CMD 사이의 Docker 설명서를 검토해야 합니다.

컨테이너 이미지 ENTRYPOINT를 재정의하려면 --entrypoint <args> 인수를 containerRunOption으로 지정할 수 있습니다. Batch가 컨테이너를 만들고 실행하는 데 사용하는 docker create 명령에 제공할 수 있는 인수에 대해서는 선택적 ContainerRunOptions를 참조하세요. 예를 들어 컨테이너에 대한 작업 디렉터리를 설정하려면 --workdir <directory> 옵션을 설정합니다.

다음은 컨테이너 이미지와 Batch 컨테이너 옵션 또는 태스크 명령줄과 그 효과에 대한 몇 가지 예입니다.

  • 컨테이너 이미지 ENTRYPOINT가 지정되지 않았고, Batch 태스크 명령줄은 "/bin/sh -c python myscript.py"입니다.
    • Batch는 지정된 Batch 태스크 명령줄로 컨테이너를 만들고 Batch 태스크 작업 디렉터리에서 실행합니다. "myscript.py"가 Batch 태스크 작업 디렉터리에 없으면 실패할 수 있습니다.
    • 태스크 명령줄이 "/bin/sh -c python /path/to/script/myscript.py"로 지정된 경우 스크립트에 대한 모든 종속성이 충족된다면 작업 디렉터리를 Batch 태스크 작업 디렉터리로 설정하더라도 이 태스크는 올바르게 작동할 수 있습니다.
  • 컨테이너 이미지 ENTRYPOINT가 "./myscript.sh"로 지정되었고, Batch 태스크 명령줄이 비어 있습니다.
    • Batch는 ENTRYPOINT를 기반으로 컨테이너를 만들고 Batch 태스크 작업 디렉터리에서 실행합니다. 컨테이너 이미지 WORKDIR이 Batch 태스크 작업 디렉터리와 동일하지 않으면 이 태스크가 실패할 수 있습니다. 이는 운영 체제, 작업 ID, 태스크 ID 등 다양한 요소에 따라 달라집니다.
    • containerRunOption으로 "--workdir /path/to/script"가 지정된 경우 스크립트에 대한 모든 종속성이 충족되면 이 태스크가 올바르게 작동할 수 있습니다.
  • 컨테이너 이미지 ENTRYPOINT가 지정되지 않았고, Batch 태스크 명령줄은 "./myscript.sh"이며, WORKDIR은 ContainerRunOptions에서 "--workdir /path/to/script"로 재정의됩니다.
    • Batch는 작업 디렉터리를 "/path/to/script"로 하여 컨테이너를 만들고 명령줄 "./myscript.sh"를 실행합니다. 스크립트가 지정된 작업 디렉터리에서 발견되었으므로 성공합니다.

컨테이너 작업의 작업 디렉터리

Batch 컨테이너 작업은 Batch가 일반(컨테이너 아님) 작업에 대해 설정하는 디렉터리와 유사한 컨테이너의 작업 디렉터리에서 실행됩니다. 이 작업 디렉터리는 이미지에 구성된 경우 WORKDIR 또는 기본 컨테이너 작업 디렉터리(Windows 컨테이너의 경우 C:\ 또는 Linux 컨테이너의 경우 /)와 다릅니다.

Batch 컨테이너 작업의 경우:

  • 호스트 노드의 AZ_BATCH_NODE_ROOT_DIR(Azure Batch 디렉터리의 루트)의 모든 하위 디렉터리는 컨테이너에 매핑됩니다.
  • 모든 작업 환경 변수는 컨테이너에 매핑됩니다.
  • 노드의 작업 디렉터리 AZ_BATCH_TASK_WORKING_DIR은 일반 작업과 동일하게 설정되며 컨테이너에 매핑됩니다.

Important

임시 디스크가 있는 VM 제품군에서 Windows 컨테이너 풀의 경우 Windows 컨테이너 제한으로 인해 전체 임시 디스크가 컨테이너 공간에 매핑됩니다.

이러한 매핑을 통해 컨테이너 작업이 아닌 작업과 동일한 방식으로 작업할 수 있습니다. 예를 들어, 애플리케이션 패키지를 사용하여 애플리케이션을 설치하고, Azure Storage에서 리소스 파일에 액세스하고, 작업 환경 설정을 사용하고, 컨테이너를 중지한 후 작업 출력 파일을 유지할 수 있습니다.

컨테이너 이미지에 대해 WORKDIR이 어떻게 설정되었는지에 관계없이 stdout.txtstderr.txt는 모두 AZ_BATCH_TASK_DIR에 캡처됩니다.

컨테이너 작업 문제 해결

컨테이너 작업이 예상대로 실행되지 않으면 컨테이너 이미지의 WORKDIR 또는 ENTRYPOINT 구성에 대한 정보를 가져와야 할 수도 있습니다. 구성을 확인하려면 docker image inspect 명령을 실행합니다.

필요한 경우에 이미지를 기반으로 하는 컨테이너 작업의 설정을 조정합니다.

  • 작업 명령줄의 절대 경로를 지정합니다. 이미지의 기본 ENTRYPOINT가 작업 명령줄에 사용되는 경우 절대 경로가 설정되어 있는지 확인합니다.
  • 작업의 컨테이너 실행 옵션에서 이미지의 WORKDIR에 일치하도록 작업 디렉터리를 변경합니다. 예를 들어 --workdir /app으로 설정합니다.

컨테이너 작업 예제

다음 Python 코드 조각은 Docker 허브에서 가져온 가상의 이미지에서 생성된 컨테이너에서 실행되는 기본 명령줄을 보여줍니다. 여기서 --rm 컨테이너 옵션은 작업이 완료된 후 컨테이너를 제거하며, --workdir 옵션은 작업 디렉터리를 설정합니다. 명령줄은 호스트의 작업 디렉터리에 작은 파일을 기록하는 간단한 셸 명령을 사용하여 컨테이너 ENTRYPOINT를 재정의합니다.

task_id = 'sampletask'
task_container_settings = batch.models.TaskContainerSettings(
    image_name='myimage',
    container_run_options='--rm --workdir /')
task = batch.models.TaskAddParameter(
    id=task_id,
    command_line='/bin/sh -c \"echo \'hello world\' > $AZ_BATCH_TASK_WORKING_DIR/output.txt\"',
    container_settings=task_container_settings
)

다음 C# 예제에서는 클라우드 작업에 대한 기본 컨테이너 설정을 보여 줍니다.

// Simple container task command
string cmdLine = "c:\\app\\myApp.exe";

TaskContainerSettings cmdContainerSettings = new TaskContainerSettings (
    imageName: "myimage",
    containerRunOptions: "--rm --workdir c:\\app"
    );

CloudTask containerTask = new CloudTask (
    id: "Task1",
    commandline: cmdLine);
containerTask.ContainerSettings = cmdContainerSettings;

다음 단계