Use o Lote do Azure para executar as cargas de trabalho de contêiner

Cuidado

Este artigo faz referência ao CentOS, uma distribuição do Linux que está se aproximando do status de EOL (fim da vida útil). Considere seu uso e planejamento adequadamente. Para obter mais informações, veja a orientação CentOS End Of Life.

O Lote do Azure permite executar e dimensionar um grande número trabalhos de computação em lote no Azure. Tarefas em lote podem executar diretamente em máquinas virtuais (nós) em um pool do Lote, mas também é possível configurar um pool do Lote para executar tarefas em contêineres compatíveis com Docker nos nós. Este artigo mostra como criar um pool de nós de computação que dão suporte a tarefas de contêiner em execução e, em seguida, executar tarefas de contêiner no pool.

Os exemplos de código usam SDKs do Lote para Python e .NET. Também é possível usar outras ferramentas e SDKs do Lote, incluindo o portal do Azure para criar pools do Lote habilitados para o contêiner e para executar tarefas de contêiner.

Por que usar contêineres?

Os contêineres fornecem uma maneira fácil para executar tarefas do Lote do Azure sem ter que gerenciar um ambiente e as dependências para executar aplicativos. Os contêineres implantam aplicativos como unidades leves, portáteis e autossuficientes que podem ser executadas em vários ambientes diferentes. Por exemplo, crie e teste um contêiner localmente e, em seguida, carregue a imagem do contêiner em um registro no Azure ou em outro local. O modelo de implantação do contêiner garante que o ambiente de runtime do aplicativo sempre seja instalado e configurado corretamente, independente de onde você hospeda o aplicativo. As tarefas baseadas em contêiner no Lote também podem aproveitar os recursos de tarefas que não são de contêiner, incluindo pacotes de aplicativos e o gerenciamento de arquivos de recurso e arquivos de saída.

Pré-requisitos

Você deve estar familiarizado com os conceitos de contêiner e como criar um pool do Lote e um trabalho.

  • Versão do SDK: Os SDKs do Lote começam a dar suporte a imagens de contêiner nas seguintes versões:

    • API REST do Lote versão 2017-09-01.6.0
    • SDK do .NET para o Lote versão 8.0.0
    • SDK do Python para o Lote versão 4.0
    • SDK Java para o Lote versão 3.0
    • SDK Node. js para o Lote versão 3.0
  • Contas: em sua assinatura do Azure, você precisa criar uma conta do Lote e, opcionalmente, uma conta do Armazenamento do Azure.

  • Uma imagem de máquina virtual (VM) com suporte: Há suporte para contêineres apenas nos pools criados com a Configuração de Máquina Virtual a partir de uma imagem com suporte (listada na próxima seção). Se você fornecer uma imagem personalizada, consulte as considerações na seção seguinte e os requisitos em Usar uma imagem gerenciada para criar um pool de imagens personalizadas.

Observação

Nas versões do SDK do Lote:

  • SDK do .NET para o Lote versão 16.0.0
  • SDK do Python para o Lote versão 14.0.0
  • SDK Java para o Lote versão 11.0.0
  • Lote Node.js SDK versão 11.0.0

Atualmente, a propriedade containerConfiguration requer que Type seja passada e os valores suportados são: ContainerType.DockerCompatible e ContainerType.CriCompatible.

Lembre-se do seguinte:

  • O Lote do Azure fornece acesso remoto direto à memória (RDMA) somente para contêineres executados em pools do Linux.
  • Para cargas de trabalho de contêiner do Windows, você deve escolher um tamanho de VM com vários núcleos para seu pool.

Importante

O Docker, por padrão, criará uma ponte de rede com uma especificação de sub-rede de 172.17.0.0/16. Se você estiver especificando uma rede virtual para o pool, verifique se não há intervalos de IP conflitantes.

Imagens de VM com suporte

Use uma das imagens a seguir com suporte do Windows ou Linux para criar um conjunto de nós de computação da VM para cargas de trabalho de contêiner. Para obter mais informações sobre imagens do Marketplace compatíveis com o Lote, consulte Lista de imagens de máquinas virtuais.

Suporte do Windows

O Lote dá suporte a imagens do Windows Server que têm designações de suporte de contêiner. A API para listar todas as imagens com suporte no Lote do Azure denota uma funcionalidade de DockerCompatible se a imagem for compatível com contêineres do Docker. O Lote permite, mas não dá suporte diretamente, a imagens publicadas pelo Mirantis com funcionalidade anotada como DockerCompatible. Essas imagens só podem ser implantadas em uma conta do Lote do modo de alocação do pool de Assinaturas de Usuário.

Você também pode criar uma imagem personalizada para habilitar a funcionalidade de contêiner no Windows.

Observação

As SKUs de imagem -with-containers ou -with-containers-smalldisk estão desativadas. Confira o comunicado para obter detalhes e opções alternativas de runtime de contêiner.

Suporte para Linux

Para cargas de trabalho de contêiner do Linux, atualmente o Lote dá suporte para as imagens a seguir do Linux publicadas no Azure Marketplace sem a necessidade de uma imagem personalizada.

  • Editor: microsoft-dsvm
    • Oferta: ubuntu-hpc

Opções alternativas de imagem

Atualmente, há outras imagens publicadas por microsoft-azure-batch que dão suporte a cargas de trabalho de contêiner:

  • Editor: microsoft-azure-batch
    • Oferta: centos-container
    • Oferta: centos-container-rdma (para uso exclusivo em SKUs de VM com Infiniband)
    • Oferta: ubuntu-server-container
    • Oferta: ubuntu-server-container-rdma (para uso exclusivo em SKUs de VM com Infiniband)

Importante

É recomendável usar a imagem da VM microsoft-dsvmubuntu-hpc em vez de imagens publicadas por microsoft-azure-batch. Essa imagem pode ser usada em qualquer SKU de VM.

Observações

A raiz de dados do docker das imagens acima está em lugares diferentes:

  • Para o Lote do Azure publicado microsoft-azure-batch imagens (Oferta: centos-container-rdma, etc.), a raiz de dados do Docker é mapeada para /mnt/batch/docker, que está localizado no disco temporário.
  • Para a imagem HPC ou microsoft-dsvm (Oferta: ubuntu-hpc, etc.), a raiz de dados do Docker é inalterada em relação ao padrão do Docker, que é /var/lib/docker no Linux e C:\ProgramData\Docker no Windows. Essas pastas estão localizadas no disco do sistema operacional.

Para imagens não publicadas em lote, o disco do sistema operacional tem o risco potencial de ser preenchido rapidamente à medida que as imagens de contêiner são baixadas.

Soluções potenciais para clientes

Altere a raiz de dados do docker em uma tarefa inicial ao criar um pool no BatchExplorer. Veja um exemplo do comando Iniciar tarefa:

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

Essas imagens só têm suporte para uso em pools do Lote do Azure e são direcionadas para a execução de contêiner do Docker. Elas apresentam:

  • Um runtime de contêiner Moby compatível com o Docker pré-instalado.
  • Drivers de GPU NVIDIA pré-instalados e runtime de contêiner NVIDIA para simplificar a implantação nas VMs da série N do Azure.
  • As imagens de VM com o sufixo -rdma são pré-configuradas com suporte para tamanhos de VM infiniBand RDMA. Estas imagens de VM não devem ser usadas com tamanhos de VM que não tenham suporte para InfiniBand.

Você também pode criar imagens personalizadas compatíveis com contêineres do Lote em uma das distribuições do Linux compatíveis com o Lote. Para obter suporte do Docker em uma imagem personalizada, instale um runtime compatível com o Docker adequado, como uma versão de Docker ou Runtime de Contêiner do Mirantis. A instalação de apenas uma ferramenta compatível com o Docker-CLI é insuficiente; um runtime compatível com o Mecanismo do Docker é necessário.

Importante

Nem a Microsoft nem o Lote do Azure fornecerão suporte para problemas relacionados ao Docker (qualquer versão ou edição), ao Runtime de Contêiner do Mirantis ou aos runtimes do Moby. Os clientes que optarem por usar esses runtimes em suas imagens devem entrar em contato com a empresa ou entidade que fornece suporte para problemas de runtime.

Mais considerações para usar uma imagem personalizada do Linux:

  • Para aproveitar o desempenho da GPU dos tamanhos da série N do Azure ao usar uma imagem personalizada, pré-instale os drivers da NVIDIA. Além disso, é necessário instalar o Docker Engine Utility para GPUs NVIDIA, NVIDIA Docker.
  • Para acessar a rede RDMA do Azure, use um tamanho de VM compatível com RDMA. Os drivers RDMA necessários são instalados nas imagens CentOS HPC e Ubuntu com suporte pelo Batch. Configurações extra podem ser necessárias para executar cargas de trabalho de MPI. Consulte Usar instâncias de GPU ou RDMA em pools do Lote do Azure.

Configuração do contêiner para o pool do Lote

Para permitir que um pool do Lote execute cargas de trabalho de contêiner, é necessário especificar as configurações ContainerConfiguration no objeto VirtualMachineConfiguration do pool. Este artigo fornece links para a referência de API do .NET do Lote do Azure. Configurações correspondentes estão na API do Python do Lote do Azure.

Crie um pool habilitado para contêiner com ou sem imagens de contêiner pré-buscadas, conforme mostrado nos exemplos a seguir. O processo de efetuar pull (ou pré-busca) permite que você carregue previamente imagens de contêineres do Docker Hub ou de outro registro de contêiner na Internet. Para obter o melhor desempenho, use um Registro de contêiner do Azure na mesma região da conta do Lote.

A vantagem de buscar previamente as imagens de contêiner é que quando as tarefas começam a ser executadas, não é preciso que as tarefas esperem que a imagem de contêiner seja baixada. A configuração do contêiner efetua pull de imagens de contêiner para as VMs quando o pool é criado. As tarefas executadas no pool podem fazer referência à lista de imagens de contêiner e a opções de execução do contêiner.

Pool sem imagens de contêiner de pré-busca

Para configurar um pool habilitado para contêineres sem imagens de contêiner pré-buscadas, defina os objetos ContainerConfiguration e VirtualMachineConfiguration, conforme mostrado nos exemplos a seguir. Estes exemplos usam a imagem de pools de contêiner do Ubuntu Server para Lote do Azure do Marketplace.

Observação: a versão do servidor Ubuntu usada no exemplo é apenas ilustrativa. Fique à vontade para alterar a node_agent_sku_id para a versão que você está usando.

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

Imagens de pré-busca para configuração do contêiner

Para pré-buscar imagens de contêiner no pool, adicione a lista de imagens de contêineres (container_image_names em Python) para o ContainerConfiguration.

O exemplo básico do Python a seguir mostra como pré-buscar uma imagem de contêiner padrão do Ubuntu a partir do Hub do Docker.

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

O exemplo C# a seguir pressupõe que você deseja pré-buscar uma imagem do TensorFlow do Hub do Docker. Este exemplo inclui uma tarefa inicial que é executada no host de VM em nós do pool. Você pode executar uma tarefa inicial no host, por exemplo, para montar um servidor de arquivos que pode ser acessado por meio dos contêineres.

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

Imagens de pré-busca de um registro de contêiner privado

Você também pode executar a pré-busca de imagens de contêiner ao fazer a autenticação em um servidor de registro de contêiner privado. No exemplo a seguir, os objetos ContainerConfiguration e VirtualMachineConfiguration pré-buscam uma imagem privada do TensorFlow em um registro de contêiner privado do Azure. A referência da imagem é a mesma do exemplo anterior.

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

Suporte de identidade gerenciada para ACR

Quando você acessar contêineres armazenados no Registro de Contêiner do Azure, um nome de usuário/senha ou uma identidade gerenciada pode ser usada para autenticar com o serviço. Para usar uma identidade gerenciada, primeiro verifique se a identidade foi atribuída ao poolpool e se a identidade tem a função AcrPull atribuída ao registro de contêiner que você deseja acessar. Em seguida, instrua o Lote a usar a identidade ao autenticar com o 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);
...

Configurações de contêiner para a tarefa

Para executar uma tarefa de contêiner em um pool habilitado para contêiner, especifique as configurações específicas do contêiner. As configurações incluem a imagem a ser usada, o registro e as opções de execução do contêiner.

  • Use a propriedade ContainerSettings das classes de tarefa para definir configurações específicas ao contêiner. Essas configurações são definidas pela classe TaskContainerSettings. A --rmopção de contêiner não requer outra opção --runtime, uma vez que é atendida pelo Lote.

  • Se você executar tarefas em imagens de contêiner, a tarefa nuvem e a tarefa do gerenciador de trabalho exigirão configurações de contêiner. Entretanto, a tarefa inicial, a tarefa de preparação de trabalho e a tarefa de liberação de trabalho não exigem configurações de contêineres (ou seja, eles podem ser executados dentro de um contexto de contêineres ou diretamente no nó).

  • Para o Linux, o Lote do Azure mapeia a permissão de usuário/grupo para o contêiner. Se o acesso a qualquer pasta do contêiner exigir permissão de administrador, será preciso executar a tarefa como um escopo de pool com o nível de elevação de administrador. Isto garante que o Lote do Azure execute a tarefa como raiz no contexto do contêiner. Caso contrário, um usuário não administrador pode não ter acesso a essas pastas.

  • Para pools de contêineres com hardware habilitado para GPU, o Lote do Azure habilita automaticamente a GPU para tarefas de contêiner, portanto, você não deve incluir o argumento –gpus.

Linha de Comando da Tarefa do Contêiner

Quando você faz a execução de uma tarefa de contêiner, o Batch usa automaticamente o comando docker create para criar um contêiner usando a imagem especificada na tarefa. Em seguida, o lote controla a execução da tarefa no contêiner.

Assim como ocorre com as tarefas em lotes que não são contêineres, você define uma linha de comando para uma tarefa de contêiner. Como o Lote do Azure cria automaticamente o contêiner, a linha de comando especifica apenas o comando ou comandos que são executados no contêiner.

Se a imagem de contêiner para uma tarefa em lote estiver configurada com um script ENTRYPOINT, você poderá definir sua linha de comando para usar o ENTRYPOINT padrão ou substituí-la:

  • Para usar o ENTRYPOINT padrão da imagem de contêiner, configure a linha de comandos da tarefa para a sequência vazia "".

  • Para substituir o ponto de ENTRADA padrão, adicione o argumento --entrypoint, por exemplo: --entrypoint "/bin/sh - python"

  • Se a imagem não tiver um PONTO DE ENTRADA, defina uma linha de comando apropriada para o contêiner, por exemplo, /app/myapp ou /bin/sh -c python myscript.py

ContainerRunOptions opcionais são outros argumentos fornecidos ao comando docker create que o Batch usa para criar e executar o contêiner. Por exemplo, para definir um diretório de trabalho para o contêiner, defina a opção --workdir <directory>. Veja a referência docker create para obter mais opções.

Diretório de trabalho da tarefa do contêiner

Uma tarefa de contêiner em Lote do Azure é executada em um diretório de trabalho no contêiner que é semelhante ao diretório que o Lote do Azure configura para uma tarefa regular (sem contêiner). Esse diretório de trabalho é diferente do WORKDIR, se configurado na imagem, ou do diretório de trabalho do contêiner padrão (C:\ em um contêiner do Windows ou / em um contêiner do Linux).

Uma tarefa de lote contêiner:

  • Todos os diretórios recursivamente abaixo do AZ_BATCH_NODE_ROOT_DIR no nó do host (a raiz dos diretórios do Lote do Azure) são mapeados para dentro do contêiner.
  • Todas as variáveis de ambiente de tarefa são mapeadas para dentro do contêiner.
  • O diretório de trabalho da tarefa AZ_BATCH_TASK_WORKING_DIR no nó é definido da mesma forma que para uma tarefa regular e mapeado para o contêiner.

Importante

Para pools de contêineres do Windows em famílias de VM com discos efêmeros, todo o disco efêmero é mapeado para o espaço de contêiner devido a limitações de contêiner do Windows.

Esses mapeamentos permitem trabalhar com tarefas de contêiner da mesma maneira que as tarefas que não são contêineres. Por exemplo, instale aplicativos usando pacotes de aplicativos, acesse arquivos de recursos do Armazenamento do Microsoft Azure, use configurações de ambiente de tarefas e persista arquivos de saída de tarefas depois que o contêiner for interrompido.

Solucionar problemas de tarefas de contêiner

Se a tarefa do contêiner não for executada conforme o esperado, talvez seja necessário obter informações sobre a configuração WORKDIR ou ENTRYPOINT da imagem de contêiner. Para ver a configuração, execute o comando docker image inspect.

Se necessário, ajuste as configurações da tarefa do contêiner com base na imagem:

  • Especifique um caminho absoluto na linha de comando da tarefa. Se o ENTRYPOINT padrão da imagem for usado para a linha de comando da tarefa, assegure-se de que um caminho absoluto esteja configurado.
  • Nas opções de execução do contêiner da tarefa, altere o diretório de trabalho para corresponder ao WORKDIR na imagem. Por exemplo, definir --workdir /app.

Exemplos de tarefas de contêiner

O fragmento Python a seguir mostra uma linha de comando básica em execução em um contêiner criado a partir de uma imagem fictícia extraída do Docker Hub. Aqui, a opção de contêiner --rm remove o contêiner após a conclusão da tarefa, e a opção --workdir define um diretório de trabalho. A linha de comando substitui o contêiner ENTRYPOINT por um comando shell simples que grava um arquivo pequeno no diretório de trabalho da tarefa no host.

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
)

O exemplo C# a seguir mostra as configurações básicas do contêiner para uma tarefa de nuvem:

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

Próximas etapas