Använda Azure Batch för att köra containerarbetsbelastningar

Varning

Den här artikeln refererar till CentOS, en Linux-distribution som närmar sig EOL-status (End Of Life). Överväg att använda och planera i enlighet med detta. Mer information finns i CentOS End Of Life-vägledningen.

Med Azure Batch kan du köra och skala ett stort antal batchberäkningsjobb i Azure. Batch-uppgifter kan köras direkt på virtuella datorer (noder) i en Batch-pool, men du kan också konfigurera en Batch-pool för att köra uppgifter i Docker-kompatibla containrar på noderna. Den här artikeln visar hur du skapar en pool med beräkningsnoder som stöder körning av containeruppgifter och sedan kör containeraktiviteter i poolen.

Kodexemplen här använder Batch .NET- och Python-SDK:er. Du kan också använda andra Batch SDK:er och verktyg, inklusive Azure-portalen, för att skapa containeraktiverade Batch-pooler och för att köra containeruppgifter.

Varför använda containrar?

Containrar är ett enkelt sätt att köra Batch-uppgifter utan att behöva hantera en miljö och beroenden för att köra program. Containrar distribuerar program som enkla, portabla, självförsörjande enheter som kan köras i flera olika miljöer. Du kan till exempel skapa och testa en container lokalt och sedan ladda upp containeravbildningen till ett register i Azure eller någon annanstans. Containerdistributionsmodellen säkerställer att körningsmiljön för ditt program alltid är korrekt installerad och konfigurerad var du än är värd för programmet. Containerbaserade uppgifter i Batch kan också dra nytta av funktioner i icke-containeraktiviteter, inklusive programpaket och hantering av resursfiler och utdatafiler.

Förutsättningar

Du bör känna till containerbegrepp och hur du skapar en Batch-pool och ett jobb.

  • SDK-versioner: Batch SDK:er stöder containeravbildningar från och med följande versioner:

    • Batch REST API version 2017-09-01.6.0
    • Batch .NET SDK version 8.0.0
    • Batch Python SDK version 4.0
    • Batch Java SDK version 3.0
    • Batch Node.js SDK version 3.0
  • Konton: I din Azure-prenumeration måste du skapa ett Batch-konto och eventuellt ett Azure Storage-konto.

  • En avbildning av en virtuell dator som stöds: Containrar stöds endast i pooler som skapats med Konfiguration av virtuell dator från en avbildning som stöds (visas i nästa avsnitt). Om du anger en anpassad avbildning läser du övervägandena i följande avsnitt och kraven i Använda en hanterad avbildning för att skapa en anpassad avbildningspool.

Kommentar

Från Batch SDK-versioner:

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

containerConfiguration För närvarande krävs Type att egenskapen skickas och de värden som stöds är: ContainerType.DockerCompatible och ContainerType.CriCompatible.

Tänk på följande begränsningar:

  • Batch har stöd för fjärråtkomst till direkt minne (RDMA) endast för containrar som körs på Linux-pooler.
  • För Windows-containerarbetsbelastningar bör du välja en vm-storlek med flera kärnor för din pool.

Viktigt!

Docker skapar som standard en nätverksbrygga med en undernätsspecifikation på 172.17.0.0/16. Om du anger ett virtuellt nätverk för din pool kontrollerar du att det inte finns några motstridiga IP-intervall.

Virtuella datoravbildningar som stöds

Använd någon av följande Windows- eller Linux-avbildningar som stöds för att skapa en pool med VM-beräkningsnoder för containerarbetsbelastningar. Mer information om Marketplace-avbildningar som är kompatibla med Batch finns i Lista över avbildningar av virtuella datorer.

Windows-stöd

Batch stöder Windows Server-avbildningar som har containerstöd för beteckningar. API:et för att visa alla avbildningar som stöds i Batch anger en DockerCompatible funktion om avbildningen stöder Docker-containrar. Batch tillåter, men stöder inte direkt, avbildningar publicerade av Mirantis med funktionen angiven som DockerCompatible. Dessa avbildningar kan bara distribueras under ett Batch-konto för användarprenumerationspoolens allokeringsläge.

Du kan också skapa en anpassad avbildning för att aktivera containerfunktioner i Windows.

Kommentar

Avbildningens SKU:er -with-containers eller -with-containers-smalldisk har dragits tillbaka. Mer information och alternativa alternativ för containerkörning finns i meddelandet.

Support för Linux

För Linux-containerarbetsbelastningar stöder Batch för närvarande följande Linux-avbildningar som publicerats på Azure Marketplace utan behov av en anpassad avbildning.

  • Publisher: microsoft-dsvm
    • Erbjuder: ubuntu-hpc

Alternativ för bildalternativ

För närvarande finns det andra avbildningar som har publicerats av microsoft-azure-batch som stöder containerarbetsbelastningar:

  • Publisher: microsoft-azure-batch
    • Erbjuder: centos-container
    • Erbjudande: centos-container-rdma (För användning exklusivt på VM-SKU:er med Infiniband)
    • Erbjuder: ubuntu-server-container
    • Erbjudande: ubuntu-server-container-rdma (För användning exklusivt på VM-SKU:er med Infiniband)

Viktigt!

Vi rekommenderar att du använder vm-avbildningen microsoft-dsvmubuntu-hpc i stället för avbildningar som publiceras av microsoft-azure-batch. Den här avbildningen kan användas på valfri VM-SKU.

Kommentar

Docker-dataroten för ovanstående bilder finns på olika platser:

  • För Azure Batch-publicerade microsoft-azure-batch avbildningar (Erbjudande: centos-container-rdmaosv.) mappas docker-dataroten till /mnt/batch/docker, som finns på den tillfälliga disken.
  • För HPC-avbildningen eller microsoft-dsvm (Erbjudande: ubuntu-hpcosv.) är docker-dataroten oförändrad från Docker-standardvärdet, som är /var/lib/docker i Linux och C:\ProgramData\Docker i Windows. Dessa mappar finns på OS-disken.

För icke-Batch-publicerade avbildningar har OS-disken en potentiell risk att snabbt fyllas i när containeravbildningar laddas ned.

Potentiella lösningar för kunder

Ändra docker-dataroten i en startaktivitet när du skapar en pool i BatchExplorer. Här är ett exempel på kommandot Starta uppgift:

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

Dessa avbildningar stöds endast för användning i Azure Batch-pooler och är anpassade för Docker-containerkörning. De innehåller:

  • En förinstallerad Docker-kompatibel Moby-containerkörning.
  • Förinstallerade NVIDIA GPU-drivrutiner och NVIDIA-containerkörning för att effektivisera distributionen på virtuella Datorer i Azure N-serien.
  • VM-avbildningar -rdma med suffixet är förkonfigurerade med stöd för VM-storlekar för InfiniBand RDMA. Dessa VM-avbildningar ska inte användas med VM-storlekar som inte har InfiniBand-stöd.

Du kan också skapa anpassade avbildningar som är kompatibla för Batch-containrar på en av de Linux-distributioner som är kompatibla med Batch. För Docker-stöd för en anpassad avbildning installerar du en lämplig Docker-kompatibel körning, till exempel en version av Docker eller Mirantis Container Runtime. Det är inte tillräckligt att bara installera ett Docker-CLI-kompatibelt verktyg. en Docker Engine-kompatibel körning krävs.

Viktigt!

Varken Microsoft eller Azure Batch ger stöd för problem som rör Docker (någon version eller utgåva), Mirantis Container Runtime eller Moby-körning. Kunder som väljer att använda dessa körningar i sina avbildningar bör kontakta företaget eller entiteten och ge stöd för körningsproblem.

Fler överväganden för att använda en anpassad Linux-avbildning:

  • Om du vill dra nytta av GPU-prestanda för Storlekar i Azure N-serien när du använder en anpassad avbildning installerar du NVIDIA-drivrutiner i förväg. Du måste också installera Docker Engine-verktyget för NVIDIA GPU:er, NVIDIA Docker.
  • Om du vill komma åt Azure RDMA-nätverket använder du en RDMA-kompatibel VM-storlek. Nödvändiga RDMA-drivrutiner installeras i CentOS HPC- och Ubuntu-avbildningar som stöds av Batch. Extra konfiguration kan behövas för att köra MPI-arbetsbelastningar. Se Använda RDMA- eller GPU-instanser i Batch-poolen.

Containerkonfiguration för Batch-pool

Om du vill aktivera en Batch-pool för att köra containerarbetsbelastningar måste du ange Inställningar för ContainerConfiguration i poolens VirtualMachineConfiguration-objekt . Den här artikeln innehåller länkar till Batch .NET API-referensen. Motsvarande inställningar finns i Batch Python-API:et.

Du kan skapa en containeraktiverad pool med eller utan förinstallerade containeravbildningar, som du ser i följande exempel. Med pull-processen (eller prefetch) kan du förinläsa containeravbildningar från Docker Hub eller ett annat containerregister på Internet. För bästa prestanda använder du ett Azure-containerregister i samma region som Batch-kontot.

Fördelen med att förinstallera containeravbildningar är att när aktiviteterna först börjar köras behöver de inte vänta tills containeravbildningen laddas ned. Containerkonfigurationen hämtar containeravbildningar till de virtuella datorerna när poolen skapas. Uppgifter som körs i poolen kan sedan referera till listan över containeravbildningar och alternativ för containerkörning.

Pool utan förinstallerade containeravbildningar

Om du vill konfigurera en containeraktiverad pool utan förinstallerade containeravbildningar definierar ContainerConfiguration du och VirtualMachineConfiguration objekt som visas i följande exempel. I de här exemplen används Ubuntu Server för Azure Batch-containerpooler från Marketplace.

Obs! Ubuntu-serverversionen som används i exemplet är i illustrationssyfte. Ändra gärna node_agent_sku_id till den version du använder.

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);

Prefetch-avbildningar för containerkonfiguration

Lägg till listan över containeravbildningar (container_image_names i Python) ContainerConfigurationi förinställda containeravbildningar i poolen.

Följande grundläggande Python-exempel visar hur du förinstallerar en Ubuntu-standardcontaineravbildning från Docker Hub.

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)
...

I följande C#-exempel förutsätts att du vill förinstallera en TensorFlow-avbildning från Docker Hub. Det här exemplet innehåller en startaktivitet som körs på den virtuella datorns värd på poolnoderna. Du kan till exempel köra en startaktivitet i värden för att montera en filserver som kan nås från containrarna.

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

ContainerRegistry containerRegistry = new ContainerRegistry(
    registryServer: "https://hub.docker.com",
    userName: "UserName",
    password: "YourPassword"
);

// 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;
...

Prefetch-avbildningar från ett privat containerregister

Du kan också förinstallera containeravbildningar genom att autentisera till en privat containerregisterserver. I följande exempel förinstallerar objekten ContainerConfiguration och VirtualMachineConfiguration en privat TensorFlow-avbildning från ett privat Azure-containerregister. Bildreferensen är densamma som i föregående exempel.

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

# Specify a container registry
container_registry = batch.models.ContainerRegistry(
        registry_server="myRegistry.azurecr.io",
        user_name="myUsername",
        password="myPassword")

# 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",
    userName: "myUserName",
    password: "myPassword");

// 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);
...

Stöd för hanterad identitet för ACR

När du kommer åt containrar som lagras i Azure Container Registry kan antingen ett användarnamn/lösenord eller en hanterad identitet användas för att autentisera med tjänsten. Om du vill använda en hanterad identitet kontrollerar du först att identiteten har tilldelats till poolen och att identiteten har rollen AcrPull tilldelad för det containerregister som du vill komma åt. Instruera sedan Batch med vilken identitet som ska användas när du autentiserar med ACR.

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);
...

Containerinställningar för uppgiften

Om du vill köra en containeraktivitet i en containeraktiverad pool anger du containerspecifika inställningar. Inställningar inkludera avbildningen som ska användas, register- och containerkörningsalternativ.

  • ContainerSettings Använd egenskapen för aktivitetsklasserna för att konfigurera containerspecifika inställningar. De här inställningarna definieras av klassen TaskContainer Inställningar. Containeralternativet --rm kräver inte något annat --runtime alternativ eftersom det tas hand om av Batch.

  • Om du kör uppgifter på containeravbildningar kräver molnaktiviteten och jobbhanteraraktiviteten containerinställningar. Startaktiviteten, jobbförberedelseaktiviteten och jobbpubliceringsaktiviteten kräver dock inte behållarinställningar (dvs. de kan köras i en containerkontext eller direkt på noden).

  • För Linux mappar Batch användar-/gruppbehörigheten till containern. Om åtkomst till en mapp i containern kräver administratörsbehörighet kan du behöva köra uppgiften som poolomfång med administratörshöjningsnivå. Detta säkerställer att Batch kör uppgiften som rot i containerkontexten. Annars kanske en icke-administratörsanvändare inte har åtkomst till dessa mappar.

  • För containerpooler med GPU-aktiverad maskinvara aktiverar Batch automatiskt GPU för containeruppgifter, så du bör inte ta med –gpus argumentet.

Kommandorad för containeraktivitet

När du kör en containeraktivitet använder Batch automatiskt kommandot docker create för att skapa en container med den avbildning som anges i uppgiften. Batch styr sedan aktivitetskörningen i containern.

Precis som med Batch-uppgifter som inte är containrar anger du en kommandorad för en containeraktivitet. Eftersom Batch skapar containern automatiskt anger kommandoraden endast kommandot eller kommandona som körs i containern.

Om containeravbildningen för en Batch-uppgift har konfigurerats med ett ENTRYPOINT-skript kan du ange att kommandoraden antingen ska använda standard-ENTRYPOINT eller åsidosätta den:

  • Om du vill använda standardinmatningspunkten för containeravbildningen anger du aktivitetskommandoraden till den tomma strängen "".

  • Om du vill åsidosätta standard-ENTRYPOINT lägger du till --entrypoint argumentet till exempel: --entrypoint "/bin/sh - python"

  • Om avbildningen inte har en ENTRYPOINT anger du en kommandorad som är lämplig för containern, till exempel eller /app/myapp/bin/sh -c python myscript.py

Valfria ContainerRunOptions är andra argument som du anger för docker create kommandot som Batch använder för att skapa och köra containern. Om du till exempel vill ange en arbetskatalog för containern anger du alternativet --workdir <directory> . Se docker create-referensen för fler alternativ.

Arbetskatalog för containeraktivitet

En Batch-containeraktivitet körs i en arbetskatalog i containern som liknar den katalog som Batch konfigurerar för en vanlig (icke-container) uppgift. Den här arbetskatalogen skiljer sig från WORKDIR om den konfigureras i avbildningen, eller standardkatalogen för containerns arbetskatalog (C:\ i en Windows-container eller / i en Linux-container).

För en Batch-containeraktivitet:

  • Alla kataloger rekursivt under AZ_BATCH_NODE_ROOT_DIR på värdnoden (roten för Azure Batch-kataloger) mappas till containern.
  • Alla aktivitetsmiljövariabler mappas till containern.
  • Arbetskatalogen AZ_BATCH_TASK_WORKING_DIR för uppgiften på noden anges på samma sätt som för en vanlig uppgift och mappas till containern.

Viktigt!

För Windows-containerpooler i VM-familjer med tillfälliga diskar mappas hela den tillfälliga disken till containerutrymmet på grund av begränsningar i Windows-containern.

Med de här mappningarna kan du arbeta med containeraktiviteter på ungefär samma sätt som andra aktiviteter än containeruppgifter. Du kan till exempel installera program med programpaket, komma åt resursfiler från Azure Storage, använda inställningar för aktivitetsmiljö och spara utdatafiler efter att containern har stannat.

Felsöka containeruppgifter

Om containeraktiviteten inte körs som förväntat kan du behöva hämta information om WORKDIR- eller ENTRYPOINT-konfigurationen för containeravbildningen. Om du vill se konfigurationen kör du kommandot docker image inspect .

Om det behövs justerar du inställningarna för containeraktiviteten baserat på avbildningen:

  • Ange en absolut sökväg på aktivitetskommandoraden. Om avbildningens standardpostpunkt används för aktivitetskommandoraden kontrollerar du att en absolut sökväg har angetts.
  • I aktivitetens alternativ för containerkörning ändrar du arbetskatalogen så att den matchar WORKDIR i avbildningen. Ange --workdir /apptill exempel .

Exempel på containeraktivitet

Följande Python-kodfragment visar en grundläggande kommandorad som körs i en container som skapats från en fiktiv avbildning som hämtats från Docker Hub. Här tar containeralternativet --rm bort containern när uppgiften har slutförts och --workdir alternativet anger en arbetskatalog. Kommandoraden åsidosätter containern ENTRYPOINT med ett enkelt gränssnittskommando som skriver en liten fil till aktivitetsarbetskatalogen på värden.

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
)

I följande C#-exempel visas grundläggande containerinställningar för en molnaktivitet:

// 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;

Nästa steg