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. Stapelverarbeitungsaufgaben lassen sich direkt auf virtuellen Computern (Knoten) in einem Batch-Pool ausführen, doch Sie können auch einen Batch-Pool zum Ausführen von Aufgaben in Docker-kompatiblen Containern auf den Knoten einrichten. 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 und -with-containers-smalldisk laufen aus. 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 andere Images, die von microsoft-azure-batch veröffentlicht werden und Containerworkloads 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, die für Batchcontainer kompatibel sind, erstellen, die Docker unter einer der Linux-Distributionen ausführen, 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

Damit ein Batch-Pool Containerworkloads ausführen kann, müssen Sie ContainerConfiguration-Einstellungen im VirtualMachineConfiguration-Objekt des Pools festlegen. 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. Mithilfe des Pull-Vorgangs (oder Vorabrufs) können Sie Containerimages entweder über Docker Hub oder eine andere Containerregistrierung im Internet vorab laden. Verwenden Sie für optimale Leistung eine Azure-Containerregistrierung in der gleichen Region wie das Batch-Konto.

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 Workload die Veröffentlichungsrate für Docker Hub-basierte Images nicht überschreitet. Es wird empfohlen, Azure Container Registry direkt zu verwenden oder Artefaktcache in ACR zu nutzen.

Pool ohne vorabgerufene Containerimages

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 die Angabe für node_agent_sku_id in die von Ihnen verwendete Version ändern.

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

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

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.

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

Vorabrufen von Images aus einer privaten Containerregistrierung

Sie können Containerimages auch durch Authentifizierung bei einem Server für die Containerregistrierung vorabrufen. Beim folgenden Beispiel rufen die Objekte ContainerConfiguration und VirtualMachineConfiguration ein privates TensorFlow-Image aus einer privaten Azure-Containerregistrierung vorab ab. Der Bildverweis ist derselbe wie im vorherigen Beispiel.

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

Unterstützung verwalteter Identitäten für ACR

Wenn Sie auf Container zugreifen, die in Azure Container Registry gespeichert sind, kann entweder ein Benutzername/Kennwort oder 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.

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

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 durch die TaskContainerSettings-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 Cloudaufgabe und die Auftrags-Manager-Aufgabe Containereinstellungen erforderlich. Die Startaufgabe, die Auftragsvorbereitungsaufgabe und die Auftragsfreigabeaufgabe benötigen jedoch keine Containereinstellungen (diese können in einem Containerkontext 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 den Task als Stamm im Containerkontext 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.

Für eine Containeraufgabe muss genau wie bei containerfremden Batch-Aufgaben eine Befehlszeile festgelegt werden. 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 sind einige Beispiele für Containerimages und Batchcontaineroptionen oder Aufgabenbefehlszeilen und deren Wirkung aufgeführt:

  • Containerimage ENTRYPOINT ist nicht angegeben, und die Batchaufgaben-Befehlszeile 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 Aufgabenbefehlszeile als „/bin/sh -c python /path/to/script/myscript.py“ angegeben wurde, kann diese Aufgabe auch dann ordnungsgemäß funktionieren, wenn alle Abhängigkeiten für das Skript erfüllt 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 Batch-Containeraufgaben gilt Folgendes:

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

Dank dieser Zuordnungen können Containeraufgaben ganz ähnlich verwendet werden wie containerfremde 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.

Behandeln von Problemen mit 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 = 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
)

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

// 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ächste Schritte