Executar tarefas em contas de usuário no Batch
Nota
As contas de usuário discutidas neste artigo são diferentes das contas de usuário usadas para RDP (Remote Desktop Protocol) ou Secure Shell (SSH), por motivos de segurança.
Para se conectar a um nó que executa a configuração da máquina virtual Linux via SSH, consulte Instalar e configurar o xrdp para usar a Área de Trabalho Remota com o Ubuntu. Para se conectar a nós que executam o Windows via RDP, consulte Como se conectar e entrar em uma máquina virtual do Azure executando o Windows.
Para se conectar a um nó que executa o via RDP, consulte Habilitar a conexão de área de trabalho remota para uma função nos Serviços de Nuvem do Azure.
Uma tarefa no Lote do Azure sempre é executada em uma conta de usuário. Por padrão, as tarefas são executadas em contas de usuário padrão, sem permissões de administrador. Para determinados cenários, convém configurar a conta de usuário sob a qual deseja que uma tarefa seja executada. Este artigo discute os tipos de contas de usuário e como configurá-las para seu cenário.
Tipos de contas de utilizador
O Azure Batch fornece dois tipos de contas de usuário para executar tarefas:
Contas de usuário automático. As contas de usuário automático são contas de usuário internas que são criadas automaticamente pelo serviço em lote. Por padrão, as tarefas são executadas em uma conta de usuário automático. Você pode configurar a especificação de usuário automático para uma tarefa para indicar sob qual conta de usuário automático uma tarefa deve ser executada. A especificação de usuário automático permite especificar o nível de elevação e o escopo da conta de usuário automático que executará a tarefa.
Uma conta de usuário nomeada. Você pode especificar uma ou mais contas de usuário nomeadas para um pool ao criar o pool. Cada conta de usuário é criada em cada nó do pool. Além do nome da conta, você especifica a senha da conta de usuário, o nível de elevação e, para pools Linux, a chave privada SSH. Ao adicionar uma tarefa, você pode especificar a conta de usuário nomeada sob a qual essa tarefa deve ser executada.
Importante
A versão do serviço Batch 2017-01-01.4.0 introduziu uma alteração de quebra que requer que você atualize seu código para chamar essa versão ou posterior. Consulte Atualizar seu código para a biblioteca de cliente Batch mais recente para obter diretrizes rápidas para atualizar seu código de lote de uma versão mais antiga.
Acesso de conta de usuário a arquivos e diretórios
Tanto uma conta de usuário automático quanto uma conta de usuário nomeada têm acesso de leitura/gravação ao diretório de trabalho, diretório compartilhado e diretório de tarefas de várias instâncias da tarefa. Ambos os tipos de contas têm acesso de leitura aos diretórios de inicialização e preparação de trabalho.
Se uma tarefa for executada na mesma conta que foi usada para executar uma tarefa inicial, a tarefa terá acesso de leitura-gravação ao diretório da tarefa inicial. Da mesma forma, se uma tarefa for executada sob a mesma conta que foi usada para executar uma tarefa de preparação de trabalho, a tarefa terá acesso de leitura-gravação ao diretório de tarefas de preparação de trabalho. Se uma tarefa for executada em uma conta diferente da tarefa inicial ou da tarefa de preparação do trabalho, a tarefa terá apenas acesso de leitura ao respetivo diretório.
Para obter mais informações sobre como acessar arquivos e diretórios a partir de uma tarefa, consulte Arquivos e diretórios.
Acesso elevado para tarefas
O nível de elevação da conta de usuário indica se uma tarefa é executada com acesso elevado. Tanto uma conta de usuário automático quanto uma conta de usuário nomeado podem ser executadas com acesso elevado. As duas opções para o nível de elevação são:
- NonAdmin: A tarefa é executada como um usuário padrão sem acesso elevado. O nível de elevação padrão para uma conta de usuário de lote é sempre NonAdmin.
- Admin: A tarefa é executada como um usuário com acesso elevado e opera com permissões totais de Administrador.
Contas de utilizador automático
Por padrão, as tarefas são executadas no Batch em uma conta de usuário automático, como um usuário padrão sem acesso elevado e com escopo de pool. Escopo do pool significa que a tarefa é executada sob uma conta de usuário automático que está disponível para qualquer tarefa no pool. Para obter mais informações sobre o escopo do pool, consulte Executar uma tarefa como um usuário automático com escopo do pool.
A alternativa ao escopo do pool é o escopo da tarefa. Quando a especificação de usuário automático é configurada para o escopo da tarefa, o serviço de lote cria uma conta de usuário automático somente para essa tarefa.
Há quatro configurações possíveis para a especificação de usuário automático, cada uma das quais corresponde a uma conta de usuário automático exclusiva:
- Acesso não administrativo com escopo de tarefa
- Acesso de administrador (elevado) com escopo da tarefa
- Acesso não administrativo com escopo de pool
- Acesso de administrador com escopo de pool
Importante
As tarefas executadas no escopo da tarefa não têm acesso de fato a outras tarefas em um nó. No entanto, um usuário mal-intencionado com acesso à conta pode contornar essa restrição enviando uma tarefa que é executada com privilégios de administrador e acessa outros diretórios de tarefas. Um usuário mal-intencionado também pode usar RDP ou SSH para se conectar a um nó. É importante proteger o acesso às chaves da sua conta Batch para evitar esse cenário. Se suspeitar que a sua conta pode ter sido comprometida, certifique-se de que regenera as suas chaves.
Executar uma tarefa como um usuário automático com acesso elevado
Você pode configurar a especificação de usuário automático para privilégios de administrador quando precisar executar uma tarefa com acesso elevado. Por exemplo, uma tarefa inicial pode precisar de acesso elevado para instalar software no nó.
Nota
Use o acesso elevado apenas quando necessário. As melhores práticas recomendam conceder o privilégio mínimo necessário para alcançar o resultado desejado. Por exemplo, se uma tarefa inicial instalar software para o usuário atual, em vez de para todos os usuários, você poderá evitar a concessão de acesso elevado às tarefas. Você pode configurar a especificação de usuário automático para escopo do pool e acesso não administrativo para todas as tarefas que precisam ser executadas na mesma conta, incluindo a tarefa iniciar.
Os trechos de código a seguir mostram como configurar a especificação de usuário automático. Os exemplos definem o nível de elevação como Admin
e o escopo como Task
.
.NET do Batch
task.UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.Admin, scope: AutoUserScope.Task));
Batch Java
taskToAdd.withId(taskId)
.withUserIdentity(new UserIdentity()
.withAutoUser(new AutoUserSpecification()
.withElevationLevel(ElevationLevel.ADMIN))
.withScope(AutoUserScope.TASK));
.withCommandLine("cmd /c echo hello");
Batch Python
user = batchmodels.UserIdentity(
auto_user=batchmodels.AutoUserSpecification(
elevation_level=batchmodels.ElevationLevel.admin,
scope=batchmodels.AutoUserScope.task))
task = batchmodels.TaskAddParameter(
id='task_1',
command_line='cmd /c "echo hello world"',
user_identity=user)
batch_client.task.add(job_id=jobid, task=task)
Executar uma tarefa como um usuário automático com escopo de pool
Quando um nó é provisionado, duas contas de usuário automático em todo o pool são criadas em cada nó do pool, uma com acesso elevado e outra sem acesso elevado. Definir o escopo do usuário automático para o escopo do pool para uma determinada tarefa executa a tarefa em uma dessas duas contas de usuário automático em todo o pool.
Quando você especifica o escopo do pool para o usuário automático, todas as tarefas executadas com acesso de administrador são executadas na mesma conta de usuário automático em todo o pool. Da mesma forma, as tarefas executadas sem permissões de administrador também são executadas em uma única conta de usuário automático em todo o pool.
Nota
As duas contas de usuário automático em todo o pool são contas separadas. As tarefas executadas sob a conta administrativa de todo o pool não podem compartilhar dados com tarefas executadas sob a conta padrão e vice-versa.
A vantagem de executar sob a mesma conta de usuário automático é que as tarefas são capazes de compartilhar dados com outras tarefas em execução no mesmo nó.
O compartilhamento de segredos entre tarefas é um cenário em que a execução de tarefas em uma das duas contas de usuário automático em todo o pool é útil. Por exemplo, suponha que uma tarefa inicial precise provisionar um segredo no nó que outras tarefas podem usar. Você pode usar a API de Proteção de Dados do Windows (DPAPI), mas ela requer privilégios de administrador. Em vez disso, você pode proteger o segredo no nível do usuário. As tarefas executadas sob a mesma conta de usuário podem acessar o segredo sem acesso elevado.
Outro cenário em que você pode querer executar tarefas em uma conta de usuário automático com escopo de pool é um compartilhamento de arquivos MPI (Message Passing Interface). Um compartilhamento de arquivos MPI é útil quando os nós na tarefa MPI precisam trabalhar nos mesmos dados de arquivo. O nó principal cria um compartilhamento de arquivos que os nós filho podem acessar se estiverem sendo executados na mesma conta de usuário automático.
O trecho de código a seguir define o escopo do usuário automático para o escopo do pool para uma tarefa no Batch .NET. O nível de elevação é omitido, portanto, a tarefa é executada sob a conta de usuário automático padrão em todo o pool.
task.UserIdentity = new UserIdentity(new AutoUserSpecification(scope: AutoUserScope.Pool));
Contas de usuário nomeadas
Você pode definir contas de usuário nomeadas ao criar um pool. Uma conta de usuário nomeada tem um nome e uma senha que você fornece. Você pode especificar o nível de elevação para uma conta de usuário nomeada. Para nós Linux, você também pode fornecer uma chave privada SSH.
Uma conta de usuário nomeada existe em todos os nós do pool e está disponível para todas as tarefas executadas nesses nós. Você pode definir qualquer número de usuários nomeados para um pool. Ao adicionar uma tarefa ou coleção de tarefas, você pode especificar que a tarefa seja executada em uma das contas de usuário nomeadas definidas no pool.
Uma conta de usuário nomeada é útil quando você deseja executar todas as tarefas em um trabalho sob a mesma conta de usuário, mas isolá-las de tarefas em execução em outros trabalhos ao mesmo tempo. Por exemplo, você pode criar um usuário nomeado para cada trabalho e executar as tarefas de cada trabalho sob essa conta de usuário nomeada. Cada trabalho pode então compartilhar um segredo com suas próprias tarefas, mas não com tarefas executadas em outros trabalhos.
Você também pode usar uma conta de usuário nomeada para executar uma tarefa que define permissões em recursos externos, como compartilhamentos de arquivos. Com uma conta de usuário nomeada, você controla a identidade do usuário e pode usar essa identidade de usuário para definir permissões.
Contas de usuário nomeadas habilitam SSH sem senha entre nós Linux. Você pode usar uma conta de usuário nomeada com nós Linux que precisam executar tarefas de várias instâncias. Cada nó no pool pode executar tarefas em uma conta de usuário definida em todo o pool. Para obter mais informações sobre tarefas de várias instâncias, consulte Usar tarefas de várias instâncias para executar aplicativos MPI.
Criar contas de usuário nomeadas
Para criar contas de usuário nomeadas no Lote, adicione uma coleção de contas de usuário ao pool. Os trechos de código a seguir mostram como criar contas de usuário nomeadas em .NET, Java e Python. Esses trechos de código mostram como criar contas nomeadas de administrador e não administrador em um pool.
Exemplo de lote .NET (Windows)
CloudPool pool = null;
Console.WriteLine("Creating pool [{0}]...", poolId);
// Create a pool using Virtual Machine Configuration.
pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
targetDedicatedComputeNodes: 3,
virtualMachineSize: "standard_d1_v2",
VirtualMachineConfiguration: new VirtualMachineConfiguration(
imageReference: new ImageReference(
publisher: "MicrosoftWindowsServer",
offer: "WindowsServer",
sku: "2019-datacenter-core",
version: "latest"),
nodeAgentSkuId: "batch.node.windows amd64");
// Add named user accounts.
pool.UserAccounts = new List<UserAccount>
{
new UserAccount("adminUser", "A1bC2d", ElevationLevel.Admin),
new UserAccount("nonAdminUser", "A1bC2d", ElevationLevel.NonAdmin),
};
// Commit the pool.
await pool.CommitAsync();
Exemplo de Batch .NET (Linux)
CloudPool pool = null;
// Obtain a collection of all available node agent SKUs.
List<NodeAgentSku> nodeAgentSkus =
batchClient.PoolOperations.ListNodeAgentSkus().ToList();
// Define a delegate specifying properties of the VM image to use.
Func<ImageReference, bool> isUbuntu1804 = imageRef =>
imageRef.Publisher == "Canonical" &&
imageRef.Offer == "UbuntuServer" &&
imageRef.Sku.Contains("20.04-LTS");
// Obtain the first node agent SKU in the collection that matches
// Ubuntu Server 20.04.
NodeAgentSku ubuntuAgentSku = nodeAgentSkus.First(sku =>
sku.VerifiedImageReferences.Any(isUbuntu2004));
// Select an ImageReference from those available for node agent.
ImageReference imageReference =
ubuntuAgentSku.VerifiedImageReferences.First(isUbuntu2004);
// Create the virtual machine configuration to use to create the pool.
VirtualMachineConfiguration virtualMachineConfiguration =
new VirtualMachineConfiguration(imageReference, ubuntuAgentSku.Id);
Console.WriteLine("Creating pool [{0}]...", poolId);
// Create the unbound pool.
pool = batchClient.PoolOperations.CreatePool(
poolId: poolId,
targetDedicatedComputeNodes: 3,
virtualMachineSize: "Standard_A1",
virtualMachineConfiguration: virtualMachineConfiguration);
// Add named user accounts.
pool.UserAccounts = new List<UserAccount>
{
new UserAccount(
name: "adminUser",
password: "A1bC2d",
elevationLevel: ElevationLevel.Admin,
linuxUserConfiguration: new LinuxUserConfiguration(
uid: 12345,
gid: 98765,
sshPrivateKey: new Guid().ToString()
)),
new UserAccount(
name: "nonAdminUser",
password: "A1bC2d",
elevationLevel: ElevationLevel.NonAdmin,
linuxUserConfiguration: new LinuxUserConfiguration(
uid: 45678,
gid: 98765,
sshPrivateKey: new Guid().ToString()
)),
};
// Commit the pool.
await pool.CommitAsync();
Exemplo de Java em lote
List<UserAccount> userList = new ArrayList<>();
userList.add(new UserAccount().withName(adminUserAccountName).withPassword(adminPassword).withElevationLevel(ElevationLevel.ADMIN));
userList.add(new UserAccount().withName(nonAdminUserAccountName).withPassword(nonAdminPassword).withElevationLevel(ElevationLevel.NONADMIN));
PoolAddParameter addParameter = new PoolAddParameter()
.withId(poolId)
.withTargetDedicatedNodes(POOL_VM_COUNT)
.withVmSize(POOL_VM_SIZE)
.withVirtualMachineConfiguration(configuration)
.withUserAccounts(userList);
batchClient.poolOperations().createPool(addParameter);
Exemplo de Python em lote
users = [
batchmodels.UserAccount(
name='pool-admin',
password='A1bC2d',
elevation_level=batchmodels.ElevationLevel.admin)
batchmodels.UserAccount(
name='pool-nonadmin',
password='A1bC2d',
elevation_level=batchmodels.ElevationLevel.non_admin)
]
pool = batchmodels.PoolAddParameter(
id=pool_id,
user_accounts=users,
virtual_machine_configuration=batchmodels.VirtualMachineConfiguration(
image_reference=image_ref_to_use,
node_agent_sku_id=sku_to_use),
vm_size=vm_size,
target_dedicated=vm_count)
batch_client.pool.add(pool)
Executar uma tarefa em uma conta de usuário nomeada com acesso elevado
Para executar uma tarefa como um usuário elevado, defina a propriedade UserIdentity da tarefa como uma conta de usuário nomeada que foi criada com sua propriedade ElevationLevel definida como Admin
.
Este trecho de código especifica que a tarefa deve ser executada em uma conta de usuário nomeada. Essa conta de usuário nomeada foi definida no pool quando ele foi criado. Nesse caso, a conta de usuário nomeada foi criada com permissões de administrador:
CloudTask task = new CloudTask("1", "cmd.exe /c echo 1");
task.UserIdentity = new UserIdentity(AdminUserAccountName);
Atualize seu código para a biblioteca de cliente Batch mais recente
A versão do serviço Batch 2017-01-01.4.0 introduziu uma alteração de quebra, substituindo a propriedade runElevated disponível em versões anteriores pela propriedade userIdentity . As tabelas a seguir fornecem um mapeamento simples que você pode usar para atualizar seu código de versões anteriores das bibliotecas cliente.
.NET do Batch
Se o seu código usar... | Atualize-o para.... |
---|---|
CloudTask.RunElevated = true; |
CloudTask.UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.Admin)); |
CloudTask.RunElevated = false; |
CloudTask.UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.NonAdmin)); |
CloudTask.RunElevated não especificado |
Nenhuma atualização necessária |
Batch Java
Se o seu código usar... | Atualize-o para.... |
---|---|
CloudTask.withRunElevated(true); |
CloudTask.withUserIdentity(new UserIdentity().withAutoUser(new AutoUserSpecification().withElevationLevel(ElevationLevel.ADMIN)); |
CloudTask.withRunElevated(false); |
CloudTask.withUserIdentity(new UserIdentity().withAutoUser(new AutoUserSpecification().withElevationLevel(ElevationLevel.NONADMIN)); |
CloudTask.withRunElevated não especificado |
Nenhuma atualização necessária |
Batch Python
Se o seu código usar... | Atualize-o para.... |
---|---|
run_elevated=True |
user_identity=user , em que user = batchmodels.UserIdentity( auto_user=batchmodels.AutoUserSpecification( elevation_level=batchmodels.ElevationLevel.admin)) |
run_elevated=False |
user_identity=user , em que user = batchmodels.UserIdentity( auto_user=batchmodels.AutoUserSpecification( elevation_level=batchmodels.ElevationLevel.non_admin)) |
run_elevated não especificado |
Nenhuma atualização necessária |
Próximos passos
- Saiba mais sobre o fluxo de trabalho do serviço em lote e os recursos primários, como pools, nós, trabalhos e tarefas.
- Saiba mais sobre arquivos e diretórios no Lote do Azure.