教程:了解如何使用 Azure CLI 管理 Linux 虚拟机

将资源部署到 Azure 时,可以灵活选择想要部署的资源类型、资源的位置以及对它们的设置方式。 但是,除了你想要在组织中允许的选项,这种灵活性可能还会开放更多其他选项。 在考虑将资源部署到 Azure 时,你可能想知道以下问题:

  • 如何满足特定国家/地区针对数据所有权制定的法规要求?
  • 如何控制成本?
  • 如何确保用户不会无意中更改关键系统?
  • 如何跟踪资源成本并准确地进行计费?

本文会为你解答这些问题。 具体而言,你需要:

  • 将用户分配到角色并分配角色对应的作用域,这样用户就能具备执行预期操作所需的权限,同时并不会涉及其他操作。
  • 应用策略来对订阅中的资源进行约定。
  • 锁定系统中的关键资源。
  • 标记资源,以便按它们对组织的价值进行跟踪。

本文重点介绍实现管理需要完成的任务。

Note

在 Azure 中国区使用 Azure CLI 之前,请先运行 az cloud set -n AzureChinaCloud 来改变云环境。如果想切回国际版 Azure,请再次运行 az cloud set -n AzureCloud

如果选择在本地安装并使用 CLI,本教程要求运行 Azure CLI 2.0.30 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

了解范围

在创建任何项之前,让我们复习一下作用域的概念。 Azure 提供四个级别的管理:管理组、订阅、资源组和资源。 下图显示了一个这些层的示例。

作用域

将在上述任何级别的作用域中应用管理设置。 所选的级别确定应用设置的广泛程度。 较低级别继承较高级别的设置。 将设置应用到订阅时,该设置将应用于订阅中的所有资源组和资源。 将设置应用到资源组时,该设置将应用到资源组及其所有资源。 但是,其他资源组不具有该设置。

通常情况下,最好在较高级别应用关键设置,在较低级别应用特定于项目的要求。 例如,可能想要确保组织的所有资源均已部署到特定区域。 若要完成此要求,请将策略应用到指定允许位置的订阅。 当组织中的其他用户添加新资源组和资源时,会自动强制实施允许的位置。

在本教程中,你将所有管理设置应用于一个资源组,以便在完成后可以轻松地删除这些设置。

让我们创建该资源组。

az group create --name myResourceGroup --location "China East"

目前,资源组为空。

基于角色的访问控制

你希望确保你的组织中的用户对这些资源具有合适级别的访问权限。 你不希望向用户授予不受限的访问权限,但还需要确保他们可以执行其工作。 使用基于角色的访问控制,你可以管理哪些用户有权在某个范围内完成特定操作。

若要创建和删除角色分配,用户必须具有 Microsoft.Authorization/roleAssignments/* 访问权限。 此访问权限是通过“所有者”或“用户访问”管理员角色授权的。

若要管理虚拟机解决方案,可以使用三种特定于资源的角色来进行通常所需的访问:

通常情况下,与其向单个用户分配角色,不如使用其用户需要执行类似操作的 Azure Active Directory 组, 然后向该组分配相应的角色。 就本文来说,请使用现有的组来管理虚拟机,或者使用门户来创建 Azure Active Directory 组

创建新组或找到现有组以后,请使用 az role assignment create 命令将新的 Azure Active Directory 组分配到资源组的“虚拟机参与者”角色。

adgroupId=$(az ad group show --group <your-group-name> --query objectId --output tsv)

az role assignment create --assignee-object-id $adgroupId --role "Virtual Machine Contributor" --resource-group myResourceGroup

如果收到一条错误,指出主体 不存在于目录中,则表明新组未在 Azure Active Directory 中完成传播。 请尝试再次运行命令。

通常情况下,请对网络参与者存储帐户参与者重复执行此过程,确保分配用户来管理已部署的资源。 在本文中,可以跳过这些步骤。

Azure Policy

Azure Policy 可帮助确保订阅中的所有资源符合企业标准。 订阅已经有多个策略定义。 若要查看可用的策略定义,请使用 az policy definition list 命令:

az policy definition list --query "[].[displayName, policyType, name]" --output table

可以看到现有的策略定义。 策略类型为“内置”或“自定义”。 在这些定义中查找所述条件正是你要分配的条件的定义。 在本文中,分配的策略要符合以下条件:

  • 限制所有资源的位置。
  • 限制虚拟机的 SKU。
  • 审核不使用托管磁盘的虚拟机。

在下面的示例中,你将基于显示名称检索三个策略定义。 并且使用 az policy assignment create 命令将这些定义分配到资源组。 对于某些策略,你将提供参数值来指定允许的值。

# Get policy definitions for allowed locations, allowed SKUs, and auditing VMs that don't use managed disks
locationDefinition=$(az policy definition list --query "[?displayName=='Allowed locations'].name | [0]" --output tsv)
skuDefinition=$(az policy definition list --query "[?displayName=='Allowed virtual machine SKUs'].name | [0]" --output tsv)
auditDefinition=$(az policy definition list --query "[?displayName=='Audit VMs that do not use managed disks'].name | [0]" --output tsv)

# Assign policy for allowed locations
az policy assignment create --name "Set permitted locations" \
  --resource-group myResourceGroup \
  --policy $locationDefinition \
  --params '{ 
      "listOfAllowedLocations": {
        "value": [
          "chinaeast", 
          "chinaeast2"
        ]
      }
    }'

# Assign policy for allowed SKUs
az policy assignment create --name "Set permitted VM SKUs" \
  --resource-group myResourceGroup \
  --policy $skuDefinition \
  --params '{ 
      "listOfAllowedSKUs": {
        "value": [
          "Standard_DS1_v2", 
          "Standard_E2s_v2"
        ]
      }
    }'

# Assign policy for auditing unmanaged disks
az policy assignment create --name "Audit unmanaged disks" \
  --resource-group myResourceGroup \
  --policy $auditDefinition

前面的示例假定你已知道了策略的参数。 如果需要查看参数,请使用:

az policy definition show --name $locationDefinition --query parameters

部署虚拟机

分配角色和策略以后,即可部署解决方案。 默认大小为 Standard_DS1_v2,这是允许的 SKU 之一。 如果默认位置中不存在 SSH 密钥,则此命令会创建这些密钥。

az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --generate-ssh-keys

部署完成后,可以对解决方案应用更多的管理设置。

锁定资源

资源锁可以防止组织中的用户意外删除或修改重要资源。 与基于角色的访问控制不同,资源锁对所有用户和角色应用限制。 可以将锁定级别设置为 CanNotDeleteReadOnly

若要创建或删除管理锁,必须有权执行 Microsoft.Authorization/locks/* 操作。 在内置角色中,只有“所有者”和“用户访问管理员”有权执行这些操作。

若要锁定虚拟机和网络安全组,请使用 az lock create 命令:

# Add CanNotDelete lock to the VM
az lock create --name LockVM \
  --lock-type CanNotDelete \
  --resource-group myResourceGroup \
  --resource-name myVM \
  --resource-type Microsoft.Compute/virtualMachines

# Add CanNotDelete lock to the network security group
az lock create --name LockNSG \
  --lock-type CanNotDelete \
  --resource-group myResourceGroup \
  --resource-name myVMNSG \
  --resource-type Microsoft.Network/networkSecurityGroups

若要测试锁,请尝试运行以下命令:

az group delete --name myResourceGroup

将会显示一个错误,指出删除操作由于某个锁而无法完成。 只有在明确删除锁以后,才能删除资源组。 该步骤显示在清理资源中。

标记资源

可以将标记应用于 Azure 资源,以逻辑方式按类别对其进行组织。 每个标记包含一个名称和一个值。 例如,可以对生产中的所有资源应用名称“Environment”和值“Production”。

若要为资源组添加两个标记,请使用 az group update 命令:

az group update -n myResourceGroup --set tags.Environment=Test tags.Dept=IT

让我们假设要添加第三个标记。 在包含新标记的情况下再次运行该命令。 它将追加到现有的标记后。

az group update -n myResourceGroup --set tags.Project=Documentation

资源不从资源组继承标记。 目前,资源组有三个标记,但资源没有任何标记。 若要将来自资源组的所有标记应用于其资源,并且保留资源上的现有标记,请使用以下脚本:

# Get the tags for the resource group
jsontag=$(az group show -n myResourceGroup --query tags)

# Reformat from JSON to space-delimited and equals sign
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')

# Get the resource IDs for all resources in the resource group
r=$(az resource list -g myResourceGroup --query [].id --output tsv)

# Loop through each resource ID
for resid in $r
do
  # Get the tags for this resource
  jsonrtag=$(az resource show --id $resid --query tags)

  # Reformat from JSON to space-delimited and equals sign
  rt=$(echo $jsonrtag | tr -d '"{},' | sed 's/: /=/g')

  # Reapply the updated tags to this resource
  az resource tag --tags $t$rt --id $resid
done

或者,可以将来自资源组的标记应用于资源而不保留现有标记:

# Get the tags for the resource group
jsontag=$(az group show -n myResourceGroup --query tags)

# Reformat from JSON to space-delimited and equals sign
t=$(echo $jsontag | tr -d '"{},' | sed 's/: /=/g')

# Get the resource IDs for all resources in the resource group
r=$(az resource list -g myResourceGroup --query [].id --output tsv)

# Loop through each resource ID
for resid in $r
do
  # Apply tags from resource group to this resource
  az resource tag --tags $t --id $resid
done

若要将几个值组合到单个标记中,请使用 JSON 字符串。

az group update -n myResourceGroup --set tags.CostCenter='{"Dept":"IT","Environment":"Test"}'

若要删除资源组上的所有标记,请使用:

az group update -n myResourceGroup --remove tags

若要将标记应用于虚拟机,请使用 az resource tag 命令。 资源上的任何现有标记都不会保留。

az resource tag -n myVM \
  -g myResourceGroup \
  --tags Dept=IT Environment=Test Project=Documentation \
  --resource-type "Microsoft.Compute/virtualMachines"

按标记查找资源

若要通过标记名称和值查找资源,请使用 az resource list 命令:

az resource list --tag Environment=Test --query [].name

可以将返回的值用于管理任务,例如停止带有某个标记值的所有虚拟机。

az vm stop --ids $(az resource list --tag Environment=Test --query "[?type=='Microsoft.Compute/virtualMachines'].id" --output tsv)

清理资源

在解除锁定之前,不能删除锁定的网络安全组。 若要删除锁,请检索锁的 ID,并将其提供给 az lock delete 命令:

vmlock=$(az lock show --name LockVM \
  --resource-group myResourceGroup \
  --resource-type Microsoft.Compute/virtualMachines \
  --resource-name myVM --output tsv --query id)
nsglock=$(az lock show --name LockNSG \
  --resource-group myResourceGroup \
  --resource-type Microsoft.Network/networkSecurityGroups \
  --resource-name myVMNSG --output tsv --query id)
az lock delete --ids $vmlock $nsglock

如果不再需要资源组、VM 和所有相关的资源,可以使用 az group delete 命令将其删除。 退出 SSH 会话,返回 VM,然后删除资源,如下所示:

az group delete --name myResourceGroup

后续步骤

在本教程中,你已创建了一个自定义 VM 映像。 你已了解如何:

  • 为用户分配角色
  • 应用强制实施标准的策略
  • 使用锁保护重要资源
  • 标记用于计费和管理的资源

请转到下一教程,了解如何创建高度可用的虚拟机。