Выполнение задач с учетными записями пользователей в пакетной службе

Примечание

Учетные записи пользователей, описанные в этой статье, отличаются от учетных записей пользователей, которые используются для протокола удаленного рабочего стола (RDP) или протокола Secure Shell (SSH), по соображениям безопасности.

Подключение к узлу с конфигурацией виртуальной машины Linux по протоколу SSH описано в статье Установка и настройка xrdp для использования удаленного рабочего стола с Ubuntu. Сведения о подключении к узлам под управлением Windows через RDP см. в статье Как подключиться к виртуальной машине Azure под управлением Windows и войти на нее.

Сведения о том, как подключиться к узлу по протоколу RDP, см. в разделе Включение подключения к удаленному рабочему столу для роли в облачных службах Azure.

Задача в пакетной службе Azure всегда выполняется с учетной записью пользователя. По умолчанию задачи выполняются со стандартными учетными записями пользователей без разрешений администратора. Тем не менее, в определенных ситуациях полезно настроить учетную запись пользователя для выполнения задачи. В этой статье рассматриваются типы учетных записей пользователей и их настройка для вашего сценария.

Типы учетных записей пользователей

В пакетной службе Azure доступны два типа учетных записей пользователей:

  • Автоматические учетные записи пользователей. Это встроенные учетные записи пользователей, создаваемые пакетной службой автоматически. По умолчанию задачи выполняются с автоматической учетной записью пользователя. Вы можете настроить спецификацию автоматических пользователей для задачи, чтобы указать, с какой учетной записью задача должна выполняться. Спецификация автоматических пользователей позволяет указать уровень прав и область автоматической учетной записи пользователя для выполнения задачи.

  • Именованная учетная запись пользователя. При создании пула можно указать одну или несколько именованных учетных записей пользователей. Каждая учетная запись пользователя создается на каждом узле кластера. Помимо имени учетной записи указывается ее пароль и уровень прав, а также закрытый ключ SSH для пулов Linux. При добавлении задачи можно указать именованную учетную запись пользователя, с которой должна выполняться эта задача.

Важно!

В пакетной службе версии 2017-01-01.4.0 введено критическое изменение, требующее обновления кода для вызова этой версии или более поздней. В разделе Обновление кода для использования последней версии клиентской библиотеки пакетной службы приведены краткие инструкции по обновлению кода для пакетной службы с более старой версии.

Доступ учетных записей пользователей к файлам и каталогам

Автоматические и именованные учетные записи пользователей имеют доступ на чтение и запись к рабочему каталогу задачи, общему каталогу и каталогу многоэкземплярных задач. Учетные записи обоих типов имеют доступ на чтение к каталогам запуска и подготовки заданий.

Если задача выполняется с учетной записью, которая использовалась для выполнения задачи запуска, то у этой задачи есть доступ на чтение и запись к каталогу задачи запуска. Аналогично, если задача выполняется с учетной записью, которая использовалась для выполнения задачи подготовки заданий, то у этой задачи есть доступ на чтение и запись к каталогу задачи подготовки заданий. Если задача выполняется с учетной записью, отличной от той, что использовалась для выполнения задачи запуска или задачи подготовки заданий, то у этой задачи есть доступ только для чтения к соответствующим каталогам.

Дополнительные сведения о доступе к файлам и каталогам из задачи см. в разделе Файлы и каталоги.

Повышенные права доступа для задач

Уровень прав учетной записи пользователя показывает, выполняется ли задача с повышенными правами доступа. Автоматическая и именованная учетная запись пользователя могут выполнять задачи с повышенными правами доступа. Ниже приведены два варианта уровня прав.

  • NonAdmin: задача выполняется от имени стандартного пользователя, без повышения прав доступа. Уровнем прав по умолчанию для учетной записи пользователя пакетной службы всегда является NonAdmin.
  • Admin: задача запускается от имени пользователя с повышенными правами доступа и получает все разрешения администратора.

Автоматические учетные записи пользователей

По умолчанию задачи выполняются в пакетной службе с автоматической учетной записью пользователя от имени стандартного пользователя без повышенных прав доступа и в области пула. Применение области пула означает, что задача выполняется с автоматической учетной записью пользователя, доступной для любой задачи в пуле. Дополнительные сведения об области пула см. в разделе Выполнение задачи от имени автоматического пользователя с областью пула.

Альтернативой области пула является область задачи. Если для области задачи настроена спецификация автоматических пользователей, пакетная служба создает автоматическую учетную запись пользователя для выполнения только этой задачи.

Существуют четыре возможные конфигурации для спецификации автоматических пользователей, каждая из которых соответствует уникальной автоматической учетной записи пользователя.

  • Доступ от имени стандартного пользователя с областью задачи.
  • Доступ от имени администратора (с повышенными правами) с областью задачи.
  • Доступ от имени стандартного пользователя с областью пула.
  • Доступ от имени администратора с областью пула.

Важно!

Задачи, выполняемые в области задачи, фактически не имеют доступа к другим задачам на узле. Тем не менее пользователь-злоумышленник, имеющий доступ к учетной записи, может обойти это ограничение, отправив задачу, которая запускается с привилегиями администратора и обращается к каталогам других задач. Пользователь-злоумышленник может также использовать протокол RDP или SSH для подключения к узлу. Очень важно защитить доступ к ключам учетной записи пакетной службы, чтобы предотвратить подобную ситуацию. Если вы подозреваете, что ключ учетной записи был скомпрометирован, обязательно повторно создайте свои ключи.

Выполнение задачи от имени автоматического пользователя с повышенными правами доступа

При необходимости выполнить задачу с повышенным уровнем доступа можно настроить спецификацию автоматических пользователей с привилегиями администратора. Например, задаче запуска может потребоваться повышенный уровень доступа для установки программного обеспечения на узле.

Примечание

Используйте повышенный доступ только при необходимости. Рекомендуется предоставлять минимальные привилегии, необходимые для достижения желаемого результата. Например, если задача запуска устанавливает программное обеспечение для текущего пользователя, а не для всех пользователей, можно избежать предоставления задачам повышенных прав доступа. Вы можете настроить спецификацию автоматических пользователей для области пула и доступа от имени стандартного пользователя для всех задач, которые должны выполняться с одной и той же учетной записью, включая задачу запуска.

В следующих фрагментах кода показано, как настроить спецификацию автоматических пользователей. В примерах задается уровень прав Admin и область Task.

.NET для пакетной службы

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

Java для пакетной службы

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

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)

Выполнение задачи от имени автоматического пользователя с областью пула

При подготовке каждого узла в пуле на нем создаются две автоматические учетные записи пользователей, действующие во всем пуле: одна с повышенными правами доступа, а вторая — без повышенных прав доступа. Если для выполнения задачи от имени автоматического пользователя указать область пула, то эта задача будет выполняться с одной из этих двух автоматических учетных записей пользователей пула.

Если указать область пула для автоматического пользователя, то все задачи, которые выполняются с правами администратора, выполняются с одной и той же автоматической учетной записью пользователя пула. Аналогичным образом задачи, которые выполняются без разрешений администратора, также выполняются с одной автоматической учетной записью пользователя пула.

Примечание

Две автоматические учетные записи пользователей пула — это отдельные учетные записи. Задачи, которые выполняются с учетной записью с правами администратора во всем пуле, не могут обмениваться данными с задачами, выполняемыми со стандартной учетной записью.

Преимущество выполнения с одной автоматической учетной записью заключается в возможности обмениваться данными с другими задачами, выполняющимися на одном узле.

Совместное использование секретов задачами — один из сценариев, в которых удобно выполнять задачи в одной из двух автоматически учетных записей пользователей пула. Для примера предположим, что задаче запуска необходимо подготовить секрет на узле, который могут использовать другие задачи. Можно использовать API защиты данных Windows (DPAPI), но это требует привилегий администратора. Вместо этого вы можете защитить секрет на уровне пользователя. Задачи, которые выполняются с одной учетной записью пользователя, могут обращаться к этому секрету без повышенных прав доступа.

Еще один сценарий, в котором требуется выполнять задачи с автоматической учетной записью пользователя с областью пула, — использование файлового ресурса MPI. Файловый ресурс MPI удобно использовать, когда узлам в задаче MPI нужно работать с одними и теми же данными. Головной узел создает файловый ресурс, доступ к которому дочерние узлы могут получить, если они работают с той же автоматической учетной записью пользователя.

В следующем фрагменте кода для выполнения задачи от имени автоматического пользователя задается область пула с помощью .NET пакетной службы. Уровень прав пропущен, поэтому задача выполняется со стандартной автоматической учетной записью пользователя пула.

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

Именованные учетные записи пользователей

При создании пула можно определить именованные учетные записи пользователей. Для именованной учетной записи пользователя указываются имя и пароль. Кроме того, для нее можно уровень прав. Для узлов Linux можно также предоставить закрытый ключ SSH.

Именованная учетная запись пользователя существует на всех узлах в пуле и доступна для всех задач на этих узлах. Для пула можно определить любое число именованных пользователей. При добавлении задачи или коллекции задач можно указать, что она выполняется с одной из именованных учетных записей пользователя, определенных в пуле.

Именованную учетную запись пользователя удобно использовать, если нужно выполнить все задачи в задании с одной учетной записью, но изолировать их от задач, параллельно выполняемых в других заданиях. Например, можно создать именованного пользователя для каждого задания и выполнять задачи каждого задания с этой именованной учетной записью пользователя. В этом случае каждое задание сможет передать секрет своим задачам, но не задачам, выполняемым в других заданиях.

Кроме того, именованную учетную запись пользователя можно использовать для выполнения задачи, которая устанавливает разрешения для внешних ресурсов, например файловых ресурсов. С помощью именованной учетной записи пользователя можно контролировать удостоверение пользователя и использовать его для задания разрешений.

Применяя именованные учетные записи пользователей, можно обеспечить SSH-подключение без пароля между узлами Linux. Именованную учетную запись пользователя можно использовать на узлах Linux, на которых требуется выполнять многоэкземплярные задачи. Каждый узел в пуле может выполнять задачи с учетной записью пользователя, определенной для всего пула. Дополнительные сведения о многоэкземплярных задачах см. в статье Использование задач с несколькими экземплярами для выполнения приложений MPI с помощью пакетной службы Azure.

Создание именованных учетных записей пользователей

Чтобы создать именованные учетные записи пользователей в пакетной службе, добавьте коллекцию учетных записей пользователей в пул. В следующих фрагментах кода показано создание именованных учетных записей пользователей на языках .NET, Java и Python. Эти фрагменты кода демонстрируют создание именованной учетной записи администратора и стандартной именованной учетной записи в пуле.

Пример использования .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", "xyz123", ElevationLevel.Admin),
    new UserAccount("nonAdminUser", "123xyz", ElevationLevel.NonAdmin),
};

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

Пример использования .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: "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();

Пример на Java для пакетной службы

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

Пример на Python для пакетной службы

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)

Выполнение задачи с именованной учетной записью пользователя с повышенными правами доступа

Чтобы выполнить задачу от имени пользователя с повышенными правами, в ее свойстве UserIdentity укажите именованную учетную запись пользователя, при создании которой ее свойству ElevationLevel было присвоено значение Admin.

Этот фрагмент кода указывает, что задание должно выполняться с именованной учетной записью пользователя. Эта именованная учетная запись пользователя была определен в пуле во время его создания. В данном случае именованная учетная запись пользователя была создана с разрешениями администратора.

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

Обновление кода для использования последней версии клиентской библиотеки пакетной службы

В пакетной службе версии 2017-01-01.4.0 введено критическое изменение: свойство runElevated, доступное в предыдущих версиях, заменено свойством userIdentity. В следующих таблицах представлено простое сопоставление, которое можно использовать для обновления кода, использующего более ранние версии клиентских библиотек.

.NET для пакетной службы

Если в коде используется… Замените его на…
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 не указано Обновление не требуется.

Java для пакетной службы

Если в коде используется… Замените его на…
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 не указано Обновление не требуется.

Python для пакетной службы

Если в коде используется… Замените его на…
run_elevated=True user_identity=user, where
user = batchmodels.UserIdentity(
     auto_user=batchmodels.AutoUserSpecification(
          elevation_level=batchmodels.ElevationLevel.admin))
run_elevated=False user_identity=user, where
user = batchmodels.UserIdentity(
     auto_user=batchmodels.AutoUserSpecification(
          elevation_level=batchmodels.ElevationLevel.non_admin))
Свойство run_elevated не указано Обновление не требуется.

Дальнейшие действия