Verwenden von Azure Batch zum Ausführen von Containerworkloads

Mit Azure Batch können Sie eine große Anzahl von Batchcomputingaufträgen in Azure ausführen und skalieren. Batchaufgaben können direkt auf virtuellen Maschinen (Knoten) in einem Batch-Pool ausgeführt werden, Sie können jedoch auch einen Batch-Pool so konfigurieren, dass Aufgaben in Docker-kompatiblen Containern auf den Knoten ausgeführt werden. In diesem Artikel wird erläutert, wie Sie einen Pool von Computeknoten erstellen, die das Ausführen von Containeraufgaben unterstützen. Außerdem erfahren Sie, wie Sie anschließend Containeraufgaben im Pool ausführen.

In den Codebeispielen werden der .NET-Batch und Python-SDKs verwendet. Sie können auch andere Batch-SDKs und -Tools, einschließlich des Azure-Portals, verwenden, um containerfähige Batch-Pools zu erstellen und Containeraufgaben auszuführen.

Gründe für die Verwendung von Containern

Container bieten eine einfache Möglichkeit zum Ausführen von Batch-Aufgaben, ohne eine Umgebung und Abhängigkeiten zum Ausführen von Anwendungen verwalten zu müssen. Container stellen Anwendungen als einfache, portable, eigenständige Einheiten bereit, die in vielen verschiedenen Umgebungen ausgeführt werden können. Sie können beispielsweise einen Container lokal erstellen und testen und dann das Containerimage in eine Registrierung in Azure oder an anderer Stelle hochladen. Das Containerbereitstellungsmodell stellt sicher, dass die Laufzeitumgebung der Anwendung immer ordnungsgemäß installiert und konfiguriert ist, und zwar ganz unabhängig davon, wo Sie die Anwendung hosten. Containerbasierte Vorgänge in Batch können auch Funktionen von Nicht-Containeraufgaben nutzen, z.B. Anwendungspakete und die Verwaltung von Ressourcendateien und Ausgabedateien.

Voraussetzungen

Sie sollten mit Containerkonzepten sowie dem Erstellen von Batch-Pools und -aufträgen vertraut sein.

  • SDK-Versionen: Die Batch SDKs unterstützen Containerimages ab den folgenden Versionen:

    • 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
  • Konten: Sie müssen in Ihrem Azure-Abonnement ein Batch-Konto und optional ein Azure Storage-Konto erstellen.

  • Ein unterstütztes VM-Image: Container werden nur in Pools unterstützt, die mit der Konfiguration des virtuellen Computers aus einem unterstützten (im folgenden Abschnitt aufgelisteten) Image erstellt wurden. Wenn Sie ein benutzerdefiniertes Image bereitstellen, finden Sie hierzu Überlegungen im folgenden Abschnitt und Anforderungen unter Verwenden eines verwalteten Images zum Erstellen eines benutzerdefinierten Imagepools.

Hinweis

Aus Batch SDK-Versionen:

  • 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

Derzeit erfordert containerConfiguration, dass die Type-Eigenschaft übergeben werden muss, und die unterstützten Werte sind: ContainerType.DockerCompatible und ContainerType.CriCompatible.

Beachten Sie die folgenden Einschränkungen:

  • Batch bietet RDMA-Unterstützung (Remote Direct Memory Access, direkter Remotespeicherzugriff) nur für Container, die in Linux-Pools ausgeführt werden.
  • Für Windows-Containerworkloads sollten Sie eine Größe einer Multikern-VM für Ihren Pool auswählen.

Wichtig

Docker erstellt standardmäßig eine Netzwerkbrücke mit einer Subnetzspezifikation von 172.17.0.0/16. Wenn Sie ein virtuelles Netzwerk für Ihren Pool angeben, stellen Sie sicher, dass keine in Konflikt stehenden IP-Bereiche vorhanden sind.

Unterstützte VM-Images

Sie müssen eines der folgenden unterstützten Windows- oder Linux-Images verwenden, um einen Pool mit VM-Computeknoten für Containerworkloads zu erstellen. Weitere Informationen zu Marketplace-Images, die mit Azure Batch kompatibel sind, finden Sie in der Liste mit VM-Images.

Windows-Unterstützung

Batch unterstützt Windows Server-Images, die Container-Unterstützungsbezeichnungen aufweisen. Die API zum Auflisten aller unterstützten Images in Batch gibt eine DockerCompatible-Funktion an, wenn das Image Docker-Container unterstützt. Batch erlaubt, unterstützt aber nicht direkt Images, die von Mirantis veröffentlicht wurden, mit der Funktion, die als DockerCompatible angegeben ist. Diese Images können nur unter einem Batch-Konto für den Zuordnungsmodus für Benutzerabonnements bereitgestellt werden.

Sie können auch ein benutzerdefiniertes Image erstellen, um Containerfunktionen unter Windows zu aktivieren.

Hinweis

Die Image-SKUs -with-containers oder -with-containers-smalldisk sind eingestellt. Details und alternative Containerlaufzeitoptionen finden Sie in der Ankündigung.

Linux-Unterstützung

Für Linux-Containerworkloads unterstützt Batch derzeit die folgenden in Azure Marketplace veröffentlichten Linux-Images, ohne dass ein benutzerdefiniertes Image erforderlich ist.

  • Herausgeber: microsoft-dsvm
    • Angebot: ubuntu-hpc
  • Herausgeber: almalinux
    • Angebot: 8-hpc-gen1
    • Angebot: 8-hpc-gen2

Alternative Image-Optionen

Derzeit gibt es weitere von microsoft-azure-batch veröffentlichte Images, die Container-Workloads unterstützen:

  • Herausgeber: microsoft-azure-batch
    • Angebot: ubuntu-server-container
    • Angebot: ubuntu-server-container-rdma (ausschließlich für VM-SKUs mit Infiniband)

Warnung

Es wird empfohlen, Images zu verwenden, die nicht von microsoft-azure-batch veröffentlicht werden, da diese Images aufgrund des bevorstehenden Endes der Lebensdauer des Image veraltet sind.

Hinweise

Der Docker-Datenstamm der obigen Images befindet sich an verschiedenen Stellen:

  • Für das HPC-Image oder microsoft-dsvm (Angebot: ubuntu-hpc, usw.) ist der Docker-Datenstamm gegenüber dem Docker-Standardwert /var/lib/docker auf Linux und C:\ProgramData\Docker auf Windows unverändert. Diese Ordner befinden sich auf dem Betriebssystemdatenträger.

Für nicht von Batch veröffentlichte Images besteht das Risiko, dass der Betriebssystemdatenträger beim Herunterladen von Containerimages schnell gefüllt wird.

Mögliche Lösungen für den Kunden

Ändern Sie den Docker-Datenstamm in einer Startaufgabe, wenn Sie einen Pool in BatchExplorer erstellen. Hier sehen Sie ein Beispiel für den Befehl Task starten:

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

Diese Images werden nur für die Verwendung in Azure Batch-Pools unterstützt und sind für die Docker-Containerausführung konzipiert. Sie bieten:

  • Eine vorinstallierte, Docker-kompatible Moby-Container-Runtime.
  • Vorinstallierte NVIDIA-GPU-Treiber und NVIDIA-Container-Runtime zum Optimieren der Bereitstellung auf Azure-VMs der N-Serien.
  • VM-Images mit dem Suffix -rdma sind mit Unterstützung für InfiniBand RDMA-VM-Größen vorkonfiguriert. Diese VM-Images sollten nicht mit VM-Größen ohne InfiniBand-Unterstützung verwendet werden.

Sie können auch benutzerdefinierte Images erstellen, die mit Batch-Containern kompatibel sind und auf einer der Linux-Distributionen basieren, die mit Batch kompatibel sind. Installieren Sie für die Docker-Unterstützung auf einem benutzerdefinierten Image eine geeignete mit Docker kompatible Laufzeit, z. B. eine Version von Docker oder Mirantis Container Runtime. Die Installation nur eines Docker-CLI-kompatiblen Tools ist unzureichend; eine mit dem Docker-Modul kompatible Laufzeit ist erforderlich.

Wichtig

Weder Microsoft noch Azure Batch bietet Unterstützung für Probleme im Zusammenhang mit Docker (alle Versionen oder Editionen), Mirantis Container Runtime oder Moby Runtime. Kunden, die sich für die Verwendung dieser Laufzeiten in ihren Images entscheiden, sollten sich an das Unternehmen oder die Entität wenden, das bzw. die Unterstützung für Laufzeitprobleme bietet.

Weitere Überlegungen zum Verwenden eines benutzerdefinierten Linux-Images:

  • Wenn Sie die GPU-Leistung von Azure-Größen der N-Serie bei der Verwendung eines benutzerdefinierten Images optimal nutzen möchten, installieren Sie im Voraus NVIDIA-Treiber. Außerdem müssen Sie das Docker-Engine-Hilfsprogramm für NVIDIA-GPUs, NVIDIA Docker, installieren.
  • Verwenden Sie für den Zugriff auf das RDMA-Netzwerk von Azure eine RDMA-fähige VM-Größe. Erforderliche RDMA-Treiber sind in den von Batch unterstützten CentOS-HPC- und Ubuntu-Images installiert. Zum Ausführen von MPI-Workloads können weitere Konfigurationsschritte erforderlich sein. Siehe Verwenden RDMA- oder GPU-fähiger Instanzen in Batch-Pools.

Containerkonfiguration für Batch-Pool

Zum Aktivieren eines Batchpools zum Ausführen von Containerworkloads müssen Sie BatchVmContainerConfiguration-Einstellungen im BatchVmConfiguration-Objekt des Pools angeben. Dieser Artikel enthält Links zur .NET-API-Referenz von Batch. Die entsprechenden Einstellungen befinden sich in der Batch Python-API.

Sie können einen containerfähigen Pool mit oder ohne vorabgerufene Containerimages erstellen, wie in den folgenden Beispielen gezeigt. Der Pull- (oder Prefetch-)Vorgang ermöglicht es Ihnen, Container-Images entweder von Docker Hub oder aus einer anderen Container-Registry im Internet vorzuladen. Um eine optimale Leistung zu erzielen, verwenden Sie eine Azure Container-Registrierung in derselben Region wie das Batchkonto.

Der Vorteil vorabgerufener Containerimages ist, dass bei der ersten Ausführung von Tasks diese nicht auf das Herunterladen des Containerimages warten müssen. Die Containerkonfiguration führt beim Erstellen des Pools eine Pullübertragung von Containerimages auf die virtuellen Computer durch. Für den Pool ausgeführte Aufgaben können dann auf die Liste der Containerimages und auf die Containerausführungsoptionen verweisen.

Hinweis

Docker Hub begrenzt die Anzahl der Image-Pulls. Stellen Sie sicher, dass Ihre Arbeitslast die veröffentlichten Ratenlimits nicht überschreitet für Docker-Hub-basierte Images. Es wird empfohlen, Azure Container Registry direkt zu verwenden oder Artefaktcache in ACR zu nutzen.

Pool ohne vorab abgerufene Container-Images

Zum Konfigurieren eines containerfähigen Pools ohne vorab abgerufene Containerimages definieren Sie die Objekte ContainerConfiguration und VirtualMachineConfiguration, wie in den folgenden Beispielen gezeigt. In diesem Beispiel wird für das Containerpool-Image „Ubuntu Server für Azure Batch“ aus Marketplace verwendet.

Hinweis: Die in diesem Beispiel verwendete Ubuntu-Serverversion dient zur Veranschaulichung. Sie können node_agent_sku_id problemlos auf die von Ihnen verwendete Version ändern.

image_ref_to_use = models.BatchVmImageReference(
    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 = models.BatchContainerConfiguration(type='dockerCompatible')

new_pool = models.BatchPoolCreateOptions(
    id=pool_id,
    virtual_machine_configuration=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)
...
BatchImageReference imageReference = new BatchImageReference()
{
    Publisher = "microsoft-dsvm",
    Offer = "ubuntu-hpc",
    Sku = "2204",
    Version = "latest"
};

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

// VM configuration
BatchVmConfiguration vmConfiguration = new BatchVmConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04")
{
    ContainerConfiguration = containerConfig
};

BatchAccountPoolData poolData = new BatchAccountPoolData()
{
    VmSize = "STANDARD_D2S_V3",
    DeploymentConfiguration = new BatchDeploymentConfiguration() { VmConfiguration = vmConfiguration },
    ScaleSettings = new BatchAccountPoolScaleSettings()
    {
        FixedScale = new BatchAccountFixedScaleSettings() { TargetDedicatedNodes = 1 }
    }
};

await batchAccount.GetBatchAccountPools().CreateOrUpdateAsync(WaitUntil.Completed, poolId, poolData);

Vorabrufen von Images für die Containerkonfiguration

Zum Vorabrufen von Containerimages im Pool fügen Sie die Liste der Containerimages (container_image_names, in Python) zur ContainerConfiguration hinzu.

Im folgenden grundlegenden Python-Beispiel wird gezeigt, wie ein standardmäßiges Ubuntu-Containerimage aus Docker Hub vorabgerufen wird.

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

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

container_conf = models.BatchContainerConfiguration(
    type='dockerCompatible',
    container_image_names=['ubuntu'])

new_pool = models.BatchPoolCreateOptions(
    id=pool_id,
    virtual_machine_configuration=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)
...

Im folgenden C#-Beispiel wird davon ausgegangen, dass Sie vorab ein TensorFlow-Image über Docker Hub abrufen möchten. Dieses Beispiel enthält eine Startaufgabe, die auf den Poolknoten im VM-Host ausgeführt wird. Beispielsweise können Sie eine Startaufgabe auf dem Host ausführen, um einen Dateiserver einzubinden, der über die Container zugänglich ist.

BatchImageReference imageReference = new BatchImageReference()
{
    Publisher = "microsoft-dsvm",
    Offer = "ubuntu-hpc",
    Sku = "2204",
    Version = "latest"
};

BatchVmContainerRegistry containerRegistry = new BatchVmContainerRegistry()
{
    RegistryServer = "https://hub.docker.com",
    IdentityResourceId = new ResourceIdentifier("/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name")
};

// Specify container configuration, prefetching Docker images
BatchVmContainerConfiguration containerConfig = new BatchVmContainerConfiguration("dockerCompatible")
{
    ContainerImageNames = { "tensorflow/tensorflow:latest-gpu" },
    ContainerRegistries = { containerRegistry }
};

// VM configuration
BatchVmConfiguration vmConfiguration = new BatchVmConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04")
{
    ContainerConfiguration = containerConfig
};

// Set a native host command line start task
BatchAccountPoolStartTask startTaskContainer = new BatchAccountPoolStartTask()
{
    CommandLine = "<native-host-command-line>"
};

BatchAccountPoolData poolData = new BatchAccountPoolData()
{
    VmSize = "Standard_NC6S_V3",
    DeploymentConfiguration = new BatchDeploymentConfiguration() { VmConfiguration = vmConfiguration },
    StartTask = startTaskContainer
};

await batchAccount.GetBatchAccountPools().CreateOrUpdateAsync(WaitUntil.Completed, poolId, poolData);

Images aus einer privaten Containerregistrierung vorab abrufen

Sie können Container-Images auch vorab abrufen, indem Sie sich bei einem privaten Container-Registry-Server authentifizieren. In den folgenden Beispielen laden die Objekte ContainerConfiguration und VirtualMachineConfiguration ein privates TensorFlow-Image aus einer privaten Azure-Containerregistrierung vor. Der Bildverweis ist derselbe wie im vorherigen Beispiel.

image_ref_to_use = models.BatchVmImageReference(
    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 = models.ContainerRegistryReference(
        registry_server="myRegistry.azurecr.io",
        identity_reference=models.BatchNodeIdentityReference(resource_id=resource_id))

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

new_pool = models.BatchPoolCreateOptions(
            id="myPool",
            virtual_machine_configuration=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
BatchVmContainerRegistry containerRegistry = new BatchVmContainerRegistry()
{
    RegistryServer = "myContainerRegistry.azurecr.io",
    IdentityResourceId = new ResourceIdentifier("/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name")
};

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

// VM configuration
BatchVmConfiguration vmConfiguration = new BatchVmConfiguration(
    imageReference: imageReference,
    nodeAgentSkuId: "batch.node.ubuntu 22.04")
{
    ContainerConfiguration = containerConfig
};

BatchAccountPoolData poolData = new BatchAccountPoolData()
{
    VmSize = "Standard_NC6S_V3",
    DeploymentConfiguration = new BatchDeploymentConfiguration() { VmConfiguration = vmConfiguration },
    ScaleSettings = new BatchAccountPoolScaleSettings()
    {
        FixedScale = new BatchAccountFixedScaleSettings() { TargetDedicatedNodes = 2 }
    }
};

await batchAccount.GetBatchAccountPools().CreateOrUpdateAsync(WaitUntil.Completed, poolId, poolData);

Unterstützung für verwaltete Identitäten in ACR

Wenn Sie auf Container zugreifen, die in Azure Container Registry gespeichert sind, kann eine verwaltete Identität für die Authentifizierung beim Dienst verwendet werden. Um eine verwaltete Identität zu verwenden, stellen Sie zunächst sicher, dass die Identität dem Pool zugewiesen wurde und dass der Identität die Rolle AcrPull für die Containerregistrierung zugewiesen ist, auf die Sie zugreifen möchten. Weisen Sie Batch dann einfach an, welche Identität bei der Authentifizierung bei ACR verwendet werden soll.

BatchVmContainerRegistry containerRegistry = new BatchVmContainerRegistry()
{
    RegistryServer = "myContainerRegistry.azurecr.io",
    IdentityResourceId = new ResourceIdentifier("/subscriptions/SUB/resourceGroups/RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/identity-name")
};

Containereinstellungen für die Aufgabe

Geben Sie containerspezifische Einstellungen an, wenn Sie eine Containeraufgabe für einen containerfähigen Pool ausführen möchten. Die Einstellungen umfassen das zu verwendende Image, die Registrierung sowie Containerausführungsoptionen.

  • Verwenden Sie die ContainerSettings-Eigenschaft der Aufgabenklassen zum Konfigurieren containerspezifischer Einstellungen. Diese Einstellungen werden von der BatchTaskContainerSettings-Klasse definiert. Die Containeroption --rm erfordert keine andere Option --runtime, da dies von Batch übernommen wird.

  • Wenn Sie Aufgaben in Containerimages ausführen, sind für die BatchTask- und die Auftrags-Manager-Aufgabe Containereinstellungen erforderlich. Die Startaufgabe, die Auftragsvorbereitungsaufgabe und die Auftragsfreigabeaufgabe erfordern jedoch keine Containereinstellungen (d. h. sie können innerhalb eines Containerkontexts oder direkt auf dem Knoten ausgeführt werden).

  • Bei Linux ordnet Batch die Benutzer-/Gruppenberechtigung dem Container zu. Wenn für den Zugriff auf einen Ordner innerhalb des Containers Administratorberechtigungen erforderlich sind, müssen Sie die Aufgabe möglicherweise als Poolbereich mit Administratorrechten ausführen. Dadurch wird sichergestellt, dass Batch die Aufgabe im Containerkontext als Root ausführt. Andernfalls hat ein Benutzer, der kein Administrator ist, möglicherweise keinen Zugriff auf diese Ordner.

  • Bei Containerpools mit GPU-aktivierter Hardware aktiviert Batch automatisch die GPU für Containertasks, sodass Sie das –gpus-Argument nicht einbeziehen sollten.

Befehlszeile für Containeraufgaben

Wenn Sie eine Containeraufgabe ausführen, verwendet Batch automatisch den Befehl docker create, um unter Verwendung des in der Aufgabe angegebenen Images einen Container zu erstellen. Anschließend steuert Batch die Aufgabenausführung im Container.

Wie bei Batchaufgaben ohne Container geben Sie auch für eine Containeraufgabe eine Befehlszeile an. Da Batch den Container automatisch erstellt, gibt die Befehlszeile nur die Befehle an, die im Container ausgeführt werden sollen.

Im Folgenden sind die Standardverhaltensweisen von „Batch“ auf Docker-Containeraufgaben aufgeführt:

  • Batch führt den Container mit der angegebenen Aufgabenbefehlszeile als CMD aus.
  • Batch beeinträchtigt den angegebenen ENTRYPOINT des Containerimages nicht.
  • Batch überschreibt die WORKDIR mit dem Arbeitsverzeichnis Batchaufgaben.

Stellen Sie sicher, dass Sie die Docker-Dokumentation zwischen ENTRYPOINT und CMD überprüfen, damit Sie die Interaktionseffekte verstehen, die auftreten können, wenn Containerimages einen angegebenen ENTRYPOINT haben und Sie auch eine Aufgabenbefehlszeile angeben.

Wenn Sie das Containerimage ENTRYPOINT überschreiben möchten, können Sie das --entrypoint <args>-Argument als containerRunOption angeben. Verweisen Sie auf die optionalen ContainerRunOptions für Argumente, die Sie für den docker create-Befehl bereitstellen können, den Batch zum Erstellen und Ausführen des Containers verwendet. So können Sie beispielsweise mit der Option --workdir <directory> ein Arbeitsverzeichnis für den Container festlegen.

Im Folgenden finden Sie einige Beispiele für Container-Images und Batch-Containeroptionen oder Befehlszeilen für Aufgaben sowie deren Auswirkung:

  • Container-Image ENTRYPOINT ist nicht festgelegt, und die Befehlszeile der Batch-Task lautet „/bin/sh -c python myscript.py“.
    • Batch erstellt den Container mit dem Batchaufgabenbefehl wie angegeben und führt ihn im Arbeitsverzeichnis für Batchaufgaben aus. Dies kann zu einem Fehler führen, wenn „myscript.py“ nicht im Arbeitsverzeichnis für Batchaufgaben enthalten ist.
    • Wenn die Task-Befehlszeile als „/bin/sh -c python /path/to/script/myscript.py“ angegeben wurde, funktioniert diese Task möglicherweise auch dann korrekt, wenn das Arbeitsverzeichnis auf das Arbeitsverzeichnis der Batch-Task festgelegt ist, vorausgesetzt, dass alle Abhängigkeiten des Skripts vorhanden sind.
  • Containerimage ENTRYPOINT wird als „./myscript.sh“ angegeben, und die Batchaufgaben-Befehlszeile ist leer.
    • Batch erstellt den Container, der auf dem ENTRYPOINT basiert, und führt ihn im Arbeitsverzeichnis für Batchaufgaben aus. Dieser Vorgang kann zu einem Fehler führen, wenn das Containerimage WORKDIR nicht mit dem Arbeitsverzeichnis für Batchaufgaben übereinstimmt, das von verschiedenen Faktoren wie Betriebssystem, Auftrags-ID, Aufgaben-ID usw. abhängig ist.
    • Wenn „--workdir /path/to/script“ als containerRunOption angegeben wurde, funktioniert diese Aufgabe möglicherweise ordnungsgemäß, wenn alle Abhängigkeiten für das Skript erfüllt sind.
  • Containerimage ENTRYPOINT ist nicht angegeben, Batchaufgabenbefehl ist „./myscript.sh“, und WORKDIR wird in ContainerRunOptions als „--workdir /path/to/script“ überschrieben.
    • Batch erstellt den Container mit dem Arbeitsverzeichnis in „/path/to/script“ und führt die Befehlszeile „./myscript.sh“ aus, die erfolgreich ist, da das Skript im angegebenen Arbeitsverzeichnis gefunden wird.

Arbeitsverzeichnis für Containeraufgaben

Eine Batch-Containeraufgabe wird in einem Arbeitsverzeichnis des Containers ausgeführt, das dem Verzeichnis ähnelt, das Batch für eine reguläre (containerfremde) Aufgabe einrichtet. Dieses Arbeitsverzeichnis unterscheidet sich von WORKDIR (sofern im Image konfiguriert) bzw. vom standardmäßigen Containerarbeitsverzeichnis (C:\ für Windows-Container, / für Linux-Container).

Für eine Batch-Containeraufgabe:

  • Alle Verzeichnisse unter AZ_BATCH_NODE_ROOT_DIR auf dem Hostknoten (Stamm der Azure Batch-Verzeichnisse) werden dem Container zugeordnet.
  • Alle Umgebungsvariablen der Aufgabe werden dem Container zugeordnet.
  • Das Aufgabenarbeitsverzeichnis AZ_BATCH_TASK_WORKING_DIR auf dem Knoten wird auf die gleiche Weise festgelegt wie für eine reguläre Aufgabe und im Container zugeordnet.

Wichtig

Für Windows-Containerpools auf VM-Familien mit kurzlebigen Datenträgern wird der gesamte kurzlebige Datenträger aufgrund von Windows-Containerbeschränkungen dem Containerspeicher zugeordnet.

Diese Zuordnungen ermöglichen es Ihnen, mit Containeraufgaben fast genauso zu arbeiten wie mit Nicht-Container-Aufgaben. So können Sie beispielsweise Anwendungen unter Verwendung von Anwendungspaketen installieren, auf Ressourcendateien aus Azure Storage zugreifen, Aufgabenumgebungseinstellungen verwenden und Aufgabenausgabedateien über die Beendigung des Containers hinaus beibehalten.

Unabhängig davon, wie WORKDIR für ein Containerimage festgelegt wird, werden sowohl stdout.txt als auch stderr.txt in der AZ_BATCH_TASK_DIR erfasst.

Fehlerbehebung für Containeraufgaben

Sollte Ihre Containeraufgabe nicht wie erwartet funktionieren, müssen Sie ggf. Informationen zur WORKDIR- oder ENTRYPOINT-Konfiguration des Containerimages abrufen. Führen Sie den Befehl docker image inspect aus, um die Konfiguration anzuzeigen.

Passen Sie ggf. die Einstellungen der Containeraufgabe auf der Grundlage des Images an:

  • Geben Sie in der Aufgabenbefehlszeile einen absoluten Pfad an. Falls der Standardeinstiegspunkt des Images für die Aufgabenbefehlszeile verwendet wird, vergewissern Sie sich, dass ein absoluter Pfad festgelegt ist.
  • Ändern Sie in den Containerausführungsoptionen das Arbeitsverzeichnis, sodass es dem Arbeitsverzeichnis (WORKDIR) im Image entspricht. Legen Sie beispielsweise --workdir /app fest.

Beispiele für Containeraufgaben

Der folgende Python-Codeausschnitt zeigt eine einfache Befehlszeile, die in einem Container ausgeführt wird, der auf der Grundlage eines fiktiven, aus Docker Hub gepullten Images erstellt wurde. Hier entfernt die Containeroption --rm den Container, nachdem die Aufgabe abgeschlossen ist, und die Option --workdir legt ein Arbeitsverzeichnis fest. Die Befehlszeile überschreibt den Einstiegspunkt des Containers mithilfe eines einfachen Shell-Befehls, der eine kleine Datei in das Aufgabenarbeitsverzeichnis auf dem Host schreibt.

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

Im folgenden Beispiel C# werden die grundlegenden Containereinstellungen für eine Cloudaufgabe gezeigt:

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

Azure.Compute.Batch.BatchTaskContainerSettings cmdContainerSettings = new Azure.Compute.Batch.BatchTaskContainerSettings("myimage")
{
    ContainerRunOptions = @"--rm --workdir c:\app"
};

BatchTaskCreateOptions containerTask = new BatchTaskCreateOptions(
    id: "Task1",
    commandLine: cmdLine)
{
    ContainerSettings = cmdContainerSettings
};

Nächste Schritte