在 Batch 中的用户帐户下运行任务Run tasks under user accounts in Batch

备注

出于安全原因,本文中所述的用户帐户与用于远程桌面协议 (RDP) 或安全外壳 (SSH) 的用户帐户不同。The user accounts discussed in this article are different from users accounts used for Remote Desktop Protocol (RDP) or Secure Shell (SSH), for security reasons.

若要通过 SSH 连接到运行 Linux 虚拟机配置的节点,请参阅使用远程桌面连接到 Azure 中的 Linux VMTo connect to a node running the Linux virtual machine configuration via SSH, see Use Remote Desktop to a Linux VM in Azure. 若要通过 RDP 连接到运行 Windows 的节点,请参阅连接到 Windows Server VMTo connect to nodes running Windows via RDP, see Connect to a Windows Server VM.

若要通过 RDP 连接到运行云服务配置的节点,请参阅为 Azure 云服务中的角色启用远程桌面连接To connect to a node running the cloud service configuration via RDP, see Enable Remote Desktop Connection for a Role in Azure Cloud Services.

Azure Batch 中的任务始终在用户帐户下运行。A task in Azure Batch always runs under a user account. 默认情况下,任务在没有管理员权限的标准用户帐户下运行。By default, tasks run under standard user accounts, without administrator permissions. 这些默认用户帐户设置通常足以满足操作需要。These default user account settings are typically sufficient. 但是,对于某些方案,如果能够配置用于运行任务的用户帐户,则会很有帮助。For certain scenarios, however, it's useful to be able to configure the user account under which you want a task to run. 本文介绍用户帐户的类型以及如何为方案配置这些帐户。This article discusses the types of user accounts and how you can configure them for your scenario.

用户帐户的类型Types of user accounts

Azure Batch 提供两种类型的用户帐户来运行任务:Azure Batch provides two types of user accounts for running tasks:

  • 自动用户帐户。Auto-user accounts. 自动用户帐户是 Batch 服务自动创建的内置用户帐户。Auto-user accounts are built-in user accounts that are created automatically by the Batch service. 默认情况下,任务在自动用户帐户下运行。By default, tasks run under an auto-user account. 可为任务配置自动用户规范,指明任务应在哪个自动用户帐户下运行。You can configure the auto-user specification for a task to indicate under which auto-user account a task should run. 使用自动用户规范可以指定将要运行任务的自动用户帐户的提升级别和范围。The auto-user specification allows you to specify the elevation level and scope of the auto-user account that will run the task.

  • 命名用户帐户。A named user account. 创建池时,可为该池指定一个或多个命名用户帐户。You can specify one or more named user accounts for a pool when you create the pool. 每个用户帐户在该池的每个节点上创建。Each user account is created on each node of the pool. 除了帐户名以外,还可以指定用户帐户密码、提升级别,对于 Linux 池,还可以指定 SSH 私钥。In addition to the account name, you specify the user account password, elevation level, and, for Linux pools, the SSH private key. 添加任务时,可以指定任务应在其下运行的命名用户帐户。When you add a task, you can specify the named user account under which that task should run.

重要

Batch 服务版本 2017-01-01.4.0 引入了一项重大更改,你需要更新代码才能调用该版本。The Batch service version 2017-01-01.4.0 introduces a breaking change that requires that you update your code to call that version. 如果你要从旧版 Batch 迁移代码,请注意,REST API 或 Batch 客户端库不再支持 runElevated 属性。If you are migrating code from an older version of Batch, note that the runElevated property is no longer supported in the REST API or Batch client libraries. 请使用任务的新 userIdentity 属性指定提升级别。Use the new userIdentity property of a task to specify elevation level. 有关使用某个客户端库时如何更新 Batch 代码的快速指导,请参阅标题为将代码更新到最新的 Batch 客户端库的部分。See the section titled Update your code to the latest Batch client library for quick guidelines for updating your Batch code if you are using one of the client libraries.

用户帐户对文件和目录的访问权限User account access to files and directories

自动用户帐户和命名用户帐户对任务的工作目录、共享目录和多实例任务目录拥有读/写访问权限。Both an auto-user account and a named user account have read/write access to the task’s working directory, shared directory, and multi-instance tasks directory. 这两种类型的帐户都对启动目录和作业准备目录拥有读取访问权限。Both types of accounts have read access to the startup and job preparation directories.

如果某个任务在用于运行启动任务的同一帐户下运行,则该任务对启动任务目录拥有读写访问权限。If a task runs under the same account that was used for running a start task, the task has read-write access to the start task directory. 同理,如果某个任务在用于运行作业准备任务的同一帐户下运行,则该任务对作业准备任务目录拥有读写访问权限。Similarly, if a task runs under the same account that was used for running a job preparation task, the task has read-write access to the job preparation task directory. 如果用于运行某个任务的帐户不同于用于启动任务或作业准备任务的帐户,则该任务对相应目录拥有只读访问权限。If a task runs under a different account than the start task or job preparation task, then the task has only read access to the respective directory.

有关通过任务访问文件和目录的详细信息,请参阅使用 Batch 开发大规模并行计算解决方案For more information on accessing files and directories from a task, see Develop large-scale parallel compute solutions with Batch.

任务的提升访问权限Elevated access for tasks

用户帐户的提升级别指示任务是否可以使用提升的访问权限运行。The user account's elevation level indicates whether a task runs with elevated access. 自动用户帐户和命名用户帐户都可以使用提升的访问权限运行。Both an auto-user account and a named user account can run with elevated access. 提升级别的两个选项为:The two options for elevation level are:

  • NonAdmin: 任务以没有提升访问权限的标准用户身份运行。NonAdmin: The task runs as a standard user without elevated access. Batch 用户帐户的默认提升级别始终为 NonAdminThe default elevation level for a Batch user account is always NonAdmin.
  • Admin: 任务以拥有提升访问权限的用户身份运行,以完全管理员权限操作。Admin: The task runs as a user with elevated access and operates with full Administrator permissions.

自动用户帐户Auto-user accounts

默认情况下,任务在 Batch 中的自动用户帐户下,以没有提升访问权限但具有任务范围的标准用户身份运行。By default, tasks run in Batch under an auto-user account, as a standard user without elevated access, and with task scope. 如果为任务范围配置了自动用户规范,Batch 服务只为该任务创建自动用户帐户。When the auto-user specification is configured for task scope, the Batch service creates an auto-user account for that task only.

任务范围的替代设置为池范围。The alternative to task scope is pool scope. 如果为池范围配置了某个任务的自动用户规范,该任务将在可供池中任何任务使用的自动用户帐户下运行。When the auto-user specification for a task is configured for pool scope, the task runs under an auto-user account that is available to any task in the pool. 有关池范围的详细信息,请参阅标题为“以具有池范围的自动用户身份运行任务”部分。For more information about pool scope, see the section titled Run a task as the auto-user with pool scope.

在 Windows 和 Linux 节点上,默认范围不同:The default scope is different on Windows and Linux nodes:

  • 在 Windows 节点上,任务默认在任务范围下运行。On Windows nodes, tasks run under task scope by default.
  • Linux 节点始终在池范围下运行。Linux nodes always run under pool scope.

自动用户规范有四种可能的配置,其中每种配置对应于一个唯一的自动用户帐户:There are four possible configurations for the auto-user specification, each of which corresponds to a unique auto-user account:

  • 具有任务范围的非管理员访问权限(默认的自动用户规范)Non-admin access with task scope (the default auto-user specification)
  • 具有任务范围的管理员(提升的)访问权限Admin (elevated) access with task scope
  • 具有池范围的非管理员访问权限Non-admin access with pool scope
  • 具有池范围的管理员访问权限Admin access with pool scope

重要

在任务范围下运行的任务对节点上的其他任务没有实际访问权限。Tasks running under task scope do not have de facto access to other tasks on a node. 但是,有权访问帐户的恶意用户可能会通过提交一个使用管理员特权运行的任务来解除这种限制,从而能够访问其他任务目录。However, a malicious user with access to the account could work around this restriction by submitting a task that runs with administrator privileges and accesses other task directories. 恶意用户还可能会使用 RDP 或 SSH 连接到节点。A malicious user could also use RDP or SSH to connect to a node. 请务必保护对 Batch 帐户密钥的访问,防止出现这种情况。It's important to protect access to your Batch account keys to prevent such a scenario. 如果你怀疑自己的帐户被泄露,请务必重新生成密钥。If you suspect your account may have been compromised, be sure to regenerate your keys.

以拥有提升访问权限的自动用户身份运行任务Run a task as an auto-user with elevated access

如果需要使用提升的访问权限运行任务,可以针对管理员特权配置自动用户规范。You can configure the auto-user specification for administrator privileges when you need to run a task with elevated access. 例如,启动任务可能需要使用提升的访问权限在节点上安装软件。For example, a start task may need elevated access to install software on the node.

备注

一般而言,最好是仅当有必要时才使用提升的访问权限。In general, it's best to use elevated access only when necessary. 最佳做法建议,只授予实现所需结果而要必须用到的最低特权。Best practices recommend granting the minimum privilege necessary to achieve the desired outcome. 例如,如果某个启动任务要为当前用户而不是所有用户安装软件,你可以避免向该任务授予提升的访问权限。For example, if a start task installs software for the current user, instead of for all users, you may be able to avoid granting elevated access to tasks. 可以针对需要在同一帐户下运行的所有任务(包括启动任务)配置池范围和非管理员访问权限的自动用户规范。You can configure the auto-user specification for pool scope and non-admin access for all tasks that need to run under the same account, including the start task.

以下代码片段演示如何配置自动用户规范。The following code snippets show how to configure the auto-user specification. 这些示例将提升级别设置为 Admin,将范围设置为 TaskThe examples set the elevation level to Admin and the scope to Task. 任务范围是默认设置,但此处出于示范目的包含了此设置。Task scope is the default setting, but is included here for the sake of example.

Batch .NETBatch .NET

task.UserIdentity = new UserIdentity(new AutoUserSpecification(elevationLevel: ElevationLevel.Admin, scope: AutoUserScope.Task));

Batch JavaBatch Java

taskToAdd.withId(taskId)
        .withUserIdentity(new UserIdentity()
            .withAutoUser(new AutoUserSpecification()
                .withElevationLevel(ElevationLevel.ADMIN))
                .withScope(AutoUserScope.TASK));
        .withCommandLine("cmd /c echo hello");                        

Batch PythonBatch 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)

以具有池范围的自动用户身份运行任务Run a task as an auto-user with pool scope

预配节点后,将在池中的每个节点上创建两个池范围的自动用户帐户,其中一个帐户拥有提升的访问权限,另一个帐户没有提升的访问权限。When a node is provisioned, two pool-wide auto-user accounts are created on each node in the pool, one with elevated access, and one without elevated access. 如果将给定任务的自动用户范围设置为池范围,将在这两个池范围自动用户帐户中的一个帐户下运行该任务。Setting the auto-user's scope to pool scope for a given task runs the task under one of these two pool-wide auto-user accounts.

为自动用户指定池范围时,使用管理员访问权限运行的所有任务将在同一个池范围自动用户帐户下运行。When you specify pool scope for the auto-user, all tasks that run with administrator access run under the same pool-wide auto-user account. 同样,不使用管理员权限运行的任务也在单个池范围自动用户帐户下运行。Similarly, tasks that run without administrator permissions also run under a single pool-wide auto-user account.

备注

两个池范围自动用户帐户是独立的帐户。The two pool-wide auto-user accounts are separate accounts. 在池范围管理帐户下运行的任务不能与标准帐户下运行的任务共享数据,反之亦然。Tasks running under the pool-wide administrative account cannot share data with tasks running under the standard account, and vice versa.

在同一自动用户帐户下运行任务的优势在于,任务可与同一个节点上运行的其他任务共享数据。The advantage to running under the same auto-user account is that tasks are able to share data with other tasks running on the same node.

在任务之间共享机密就是一种有效的方案,这样可以在两个池范围自动用户帐户中的一个帐户下运行任务。Sharing secrets between tasks is one scenario where running tasks under one of the two pool-wide auto-user accounts is useful. 例如,假设某个启动任务需要在其他任务可以使用的节点上预配机密。For example, suppose a start task needs to provision a secret onto the node that other tasks can use. 可以使用 Windows 数据保护 API (DPAPI),但这需要管理员特权。You could use the Windows Data Protection API (DPAPI), but it requires administrator privileges. 不过,可以在用户级别保护机密。Instead, you can protect the secret at the user level. 在同一用户帐户下运行的任务无需提升的访问权限即可访问机密。Tasks running under the same user account can access the secret without elevated access.

你可能想要在具有池范围的自动用户帐户下运行任务的另一种情景是实现消息传递接口 (MPI) 文件共享。Another scenario where you may want to run tasks under an auto-user account with pool scope is a Message Passing Interface (MPI) file share. 如果 MPI 任务中的节点需要处理相同的文件数据,MPI 文件共享将非常有用。An MPI file share is useful when the nodes in the MPI task need to work on the same file data. 如果头节点和子节点在同一个自动用户帐户下运行,则头节点将创建可由子节点访问的文件共享。The head node creates a file share that the child nodes can access if they are running under the same auto-user account.

以下代码片段在 Batch .NET 中将自动用户的范围设置为任务的池范围。The following code snippet sets the auto-user's scope to pool scope for a task in Batch .NET. 已省略提升级别,因此,任务将在标准池范围自动用户帐户下运行。The elevation level is omitted, so the task runs under the standard pool-wide auto-user account.

task.UserIdentity = new UserIdentity(new AutoUserSpecification(scope: AutoUserScope.Pool));

命名用户帐户Named user accounts

创建池时,可以定义命名用户帐户。You can define named user accounts when you create a pool. 命名用户帐户具有你提供的名称和密码。A named user account has a name and password that you provide. 可为命名用户帐户指定提升级别。You can specify the elevation level for a named user account. 对于 Linux 节点,还可以提供 SSH 私钥。For Linux nodes, you can also provide an SSH private key.

命名用户帐户在池中的所有节点上存在,可供这些节点上运行的所有任务使用。A named user account exists on all nodes in the pool and is available to all tasks running on those nodes. 可为一个池定义任意数目的命名用户。You may define any number of named users for a pool. 添加任务或任务集合时,可以指定任务需在池中定义的某个命名用户帐户下运行。When you add a task or task collection, you can specify that the task runs under one of the named user accounts defined on the pool.

如果你要在同一个用户帐户下运行作业中的所有任务,但同时要将这些任务与其他作业中运行的任务区分开来,则命名用户帐户将非常有用。A named user account is useful when you want to run all tasks in a job under the same user account, but isolate them from tasks running in other jobs at the same time. 例如,可为每个作业创建一个命名用户,并在该命名用户帐户下运行每个作业的任务。For example, you can create a named user for each job, and run each job's tasks under that named user account. 然后,每个作业可与其自身的任务共享机密,但不能与其他作业中运行的任务共享机密。Each job can then share a secret with its own tasks, but not with tasks running in other jobs.

还可以使用命名用户帐户来运行可在外部资源(例如文件共享)上设置权限的任务。You can also use a named user account to run a task that sets permissions on external resources such as file shares. 使用命名用户帐户可以控制用户标识,并使用该用户标识来设置权限。With a named user account, you control the user identity and can use that user identity to set permissions.

命名用户帐户可在 Linux 节点之间启用无密码 SSH。Named user accounts enable password-less SSH between Linux nodes. 可以在需要运行多实例任务的 Linux 节点中使用命名用户帐户。You can use a named user account with Linux nodes that need to run multi-instance tasks. 池中的每个节点可以在整个池中定义的用户帐户下运行任务。Each node in the pool can run tasks under a user account defined on the whole pool. 有关多实例任务的详细信息,请参阅使用多实例任务运行 MPI 应用程序For more information about multi-instance tasks, see Use multi-instance tasks to run MPI applications.

创建命名用户帐户Create named user accounts

若要在 Batch 中创建命名用户帐户,请在池中添加一个用户帐户集合。To create named user accounts in Batch, add a collection of user accounts to the pool. 以下代码片段演示如何在 .NET、Java 和 Python 中创建命名用户帐户。The following code snippets show how to create named user accounts in .NET, Java, and Python. 这些代码片段演示如何在池中创建管理员和非管理员命名帐户。These code snippets show how to create both admin and non-admin named accounts on a pool. 这些示例使用云服务配置创建池,但你在使用虚拟机配置创建 Windows 或 Linux 池时,可以使用相同的方法。The examples create pools using the cloud service configuration, but you use the same approach when creating a Windows or Linux pool using the virtual machine configuration.

Batch .NET 示例 (Windows)Batch .NET example (Windows)

CloudPool pool = null;
Console.WriteLine("Creating pool [{0}]...", poolId);

// Create a pool using the cloud service configuration.
pool = batchClient.PoolOperations.CreatePool(
    poolId: poolId,
    targetDedicatedComputeNodes: 3,
    virtualMachineSize: "standard_d1_v2",
    cloudServiceConfiguration: new CloudServiceConfiguration(osFamily: "5"));   

// Add named user accounts.
pool.UserAccounts = new List<UserAccount>
{
    new UserAccount("adminUser", "xyz123", ElevationLevel.Admin),
    new UserAccount("nonAdminUser", "123xyz", ElevationLevel.NonAdmin),
};

// Commit the pool.
await pool.CommitAsync();

Batch .NET 示例 (Linux)Batch .NET example (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> isUbuntu1404 = imageRef =>
    imageRef.Publisher == "Canonical" &&
    imageRef.Offer == "UbuntuServer" &&
    imageRef.Sku.Contains("14.04");

// Obtain the first node agent SKU in the collection that matches
// Ubuntu Server 14.04. 
NodeAgentSku ubuntuAgentSku = nodeAgentSkus.First(sku =>
    sku.VerifiedImageReferences.Any(isUbuntu1404));

// Select an ImageReference from those available for node agent.
ImageReference imageReference =
    ubuntuAgentSku.VerifiedImageReferences.First(isUbuntu1404);

// 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: "xyz123",
        elevationLevel: ElevationLevel.Admin,
        linuxUserConfiguration: new LinuxUserConfiguration(
            uid: 12345,
            gid: 98765,
            sshPrivateKey: new Guid().ToString()
            )),
    new UserAccount(
        name: "nonAdminUser",
        password: "123xyz",
        elevationLevel: ElevationLevel.NonAdmin,
        linuxUserConfiguration: new LinuxUserConfiguration(
            uid: 45678,
            gid: 98765,
            sshPrivateKey: new Guid().ToString()
            )),
};

// Commit the pool.
await pool.CommitAsync();

Batch Java 示例Batch Java example

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)
        .withCloudServiceConfiguration(configuration)
        .withUserAccounts(userList);
batchClient.poolOperations().createPool(addParameter);

Batch Python 示例Batch Python example

users = [
    batchmodels.UserAccount(
        name='pool-admin',
        password='******',
        elevation_level=batchmodels.ElevationLevel.admin)
    batchmodels.UserAccount(
        name='pool-nonadmin',
        password='******',
        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)

在拥有提升的访问权限的命名用户帐户下运行任务Run a task under a named user account with elevated access

若要以提升权限的用户身份运行某个任务,请将该任务的 UserIdentity 属性设置为创建的命名用户帐户(该帐户的 ElevationLevel 属性已设置为 Admin)。To run a task as an elevated user, set the task's UserIdentity property to a named user account that was created with its ElevationLevel property set to Admin.

此代码片段指定任务应在命名用户帐户下运行。This code snippet specifies that the task should run under a named user account. 此命名用户帐户是在创建池时定义的。This named user account was defined on the pool when the pool was created. 在本例中,创建的命名用户帐户拥有管理员权限:In this case, the named user account was created with admin permissions:

CloudTask task = new CloudTask("1", "cmd.exe /c echo 1");
task.UserIdentity = new UserIdentity(AdminUserAccountName);

将代码更新到最新的 Batch 客户端库Update your code to the latest Batch client library

Batch 服务版本 2017-01-01.4.0 引入了一项重大更改,已将早期版本中的 runElevated 属性替换为 userIdentity 属性。The Batch service version 2017-01-01.4.0 introduces a breaking change, replacing the runElevated property available in earlier versions with the userIdentity property. 下表提供了从早期版本的客户端库更新代码时可以参考的简单更改对照。The following tables provide a simple mapping that you can use to update your code from earlier versions of the client libraries.

Batch .NETBatch .NET

如果代码使用...If your code uses... 请更新为...Update it to....
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 未指定CloudTask.RunElevated not specified 无需更新No update required

Batch JavaBatch Java

如果代码使用...If your code uses... 请更新为...Update it to....
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 未指定CloudTask.withRunElevated not specified 无需更新No update required

Batch PythonBatch Python

如果代码使用...If your code uses... 请更新为...Update it to....
run_elevated=True user_identity=user,其中user_identity=user, where
user = batchmodels.UserIdentity(
     auto_user=batchmodels.AutoUserSpecification(
          elevation_level=batchmodels.ElevationLevel.admin))
run_elevated=False user_identity=user,其中user_identity=user, where
user = batchmodels.UserIdentity(
     auto_user=batchmodels.AutoUserSpecification(
          elevation_level=batchmodels.ElevationLevel.non_admin))
run_elevated 未指定run_elevated not specified 无需更新No update required

后续步骤Next steps