通过 Python SDK 获取规模集中 VM 的私有 IP 地址(规模集中没有 public IP 地址)

Get private IP addresses for VMs in a Scale Set via Python SDK (no public IP addresses in Scale Set)

我正在尝试获取规模集中所有 VM 的专用 IP 地址列表(none 个 VM 故意具有任何 public 个 IP 地址)。我已经找到了如何从 az cli 获取它,如下所示:

az vmss nic list -g ResourceGroup --vmss-name ScaleSetName --query [].{ip:ipConfigurations[0].privateIpAddress} -o tsv

但是我无法使用 Python SDK 获得相同的输出。我正在使用以下基本代码:

from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.compute import ComputeManagementClient

credentials = ServicePrincipalCredentials(client_id = CLIENT, secret = KEY, tenant = TENANT)

compute_client = ComputeManagementClient(credentials, SUBSCRIPTION)

vmss = compute_client.virtual_machine_scale_sets.get(RG, SC)
print(vmss.virtual_machine_profile.network_profile.network_interface_configurations[0].ip_configurations[0])

这是在 SDK 对象模型中查找它们的正确位置吗?据我了解,网络属性应该处于比例集级别,这是 API 中我看到任何与网络相关的唯一地方。但是,我在后续属性中只看到 'private IP version',并且由于没有 public IP,因此该部分属性为空白。

很遗憾,恐怕您无法获取虚拟机规模集实例的私有 IP。虚拟机规模集的网络接口不是 Azure 中的资源,您无法获取它们。目前,Azure python SDK 不支持通过 python SDK 获取 VMSS 私有 IP。

您可以尝试使用 REST API 来达到目的,并通过 CLI 命令 debug 获取 REST API,如下所示:

az vmss nic list -g ResourceGroup --vmss-name ScaleSetName --query [].{ip:ipConfigurations[0].privateIpAddress} -o tsv --debug

它将显示进度和 REST API:

如果您已经在使用 Python azure sdk,您可以从 azure.identity 凭证中提取 Bearer 令牌,这使得此 REST API 调用更容易执行:

credentials = ClientSecretCredential(
    client_id=os.environ['AZURE_CLIENT_ID'],
    client_secret=os.environ['AZURE_CLIENT_SECRET'],
    tenant_id=os.environ['AZURE_TENANT_ID']
)  

# Grab the bearer token from the existing azure credential,
# and use it to AUTH the REST api call:
rest_token = credentials._request_token('https://management.core.windows.net//.default')
vmss_nic_json = vmss_rest_api_list_nics(rest_token.token, subscription_id, resource_group, vmss_name)

# REST API call:
def vmss_rest_api_list_nics(token, subscription_id, resource_group, vmss_name, api_version='2018-10-01'):
    
    url = f"https://management.azure.com/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/microsoft.Compute/virtualMachineScaleSets/{vmss_name}/networkInterfaces"
    params = {'api-version': api_version}
    request = requests.Request('GET', url, params=params)
    prepped = request.prepare()
    prepped.headers['Authorization'] = f'Bearer {token}'

    with requests.Session() as session:
        response = session.send(prepped )

        if( response.status_code == 200 ):
            return json.loads(response.text)
        else:
            logger.error(f"Failed to communicate with api service: HTTP {response.status_code} - {response.text}")
            return None