为 Azure Cosmos 帐户配置 Azure 专用链接Configure Azure Private Link for an Azure Cosmos account

可以使用 Azure 专用链接通过专用终结点连接到 Azure Cosmos 帐户。By using Azure Private Link, you can connect to an Azure Cosmos account via a private endpoint. 专用终结点是虚拟网络中某个子网内的一组专用 IP 地址。The private endpoint is a set of private IP addresses in a subnet within your virtual network. 然后,可以通过专用 IP 地址限制对 Azure Cosmos 帐户的访问。You can then limit access to an Azure Cosmos account over private IP addresses. 将专用链接与受限制的 NSG 策略相结合有助于降低数据透露的风险。When Private Link is combined with restricted NSG policies, it helps reduce the risk of data exfiltration.

专用链接允许用户从虚拟网络内部或者从任何对等互连的虚拟网络访问 Azure Cosmos 帐户。Private Link allows users to access an Azure Cosmos account from within the virtual network or from any peered virtual network. 还可以在本地使用 VPN 或 Azure ExpressRoute 通过专用对等互连访问映射到专用链接的资源。Resources mapped to Private Link are also accessible on-premises over private peering through VPN or Azure ExpressRoute.

可以使用自动或手动批准方法连接到配置了专用链接的 Azure Cosmos 帐户。You can connect to an Azure Cosmos account configured with Private Link by using the automatic or manual approval method.

本文介绍了创建专用终结点的步骤。This article describes the steps to create a private endpoint. 它假设你使用的是自动审批方法。It assumes that you're using the automatic approval method.

使用 Azure 门户创建专用终结点Create a private endpoint by using the Azure portal

在 Azure 门户中使用以下步骤为现有的 Azure Cosmos 帐户创建专用终结点:Use the following steps to create a private endpoint for an existing Azure Cosmos account by using the Azure portal:

  1. 在“所有资源”窗格中,选择一个 Azure Cosmos 帐户。From the All resources pane, choose an Azure Cosmos account.

  2. 在设置列表中选择“专用终结点连接”,然后选择“专用终结点”: Select Private Endpoint Connections from the list of settings, and then select Private endpoint:

    用于在 Azure 门户中创建专用终结点的选项

  3. 在“创建专用终结点 - 基本信息”窗格中,输入或选择以下详细信息:In the Create a private endpoint - Basics pane, enter or select the following details:

    设置Setting ValueValue
    项目详细信息Project details
    订阅Subscription 选择订阅。Select your subscription.
    资源组Resource group 选一个择资源组。Select a resource group.
    实例详细信息Instance details
    名称Name 为专用终结点输入任意名称。Enter any name for your private endpoint. 如果此名称已被使用,请创建唯一的名称。If this name is taken, create a unique one.
    区域Region 选择要在其中部署专用链接的区域。Select the region where you want to deploy Private Link. 在虚拟网络所在的位置创建专用终结点。Create the private endpoint in the same location where your virtual network exists.
  4. 在完成时选择“下一步:资源”。Select Next: Resource.

  5. 在“创建专用终结点 - 资源”中,输入或选择以下信息:In Create a private endpoint - Resource, enter or select this information:

    设置Setting ValueValue
    连接方法Connection method 选择“连接到我的目录中的 Azure 资源”。Select Connect to an Azure resource in my directory.

    然后,可以选择一个资源来设置专用链接。You can then choose one of your resources to set up Private Link. 或者,可以使用他人与你共享的资源 ID 或别名连接到其资源。Or you can connect to someone else's resource by using a resource ID or alias that they've shared with you.
    订阅Subscription 选择订阅。Select your subscription.
    资源类型Resource type 选择“Microsoft.AzureCosmosDB/databaseAccounts”。Select Microsoft.AzureCosmosDB/databaseAccounts.
    资源Resource 选择你的 Azure Cosmos 帐户。Select your Azure Cosmos account.
    目标子资源Target sub-resource 选择要映射的 Azure Cosmos DB API 类型。Select the Azure Cosmos DB API type that you want to map. 默认情况下,此字段仅提供 SQL、MongoDB 和 Cassandra API 所对应的一个选项。This defaults to only one choice for the SQL, MongoDB, and Cassandra APIs. 对于 Gremlin 和表 API,还可以选择“SQL”,因为这些 API 可与 SQL API 互操作。For the Gremlin and Table APIs, you can also choose Sql because these APIs are interoperable with the SQL API.
  6. 在完成时选择“下一步:配置”。Select Next: Configuration.

  7. 在“创建专用终结点 - 配置”中,输入或选择以下信息:In Create a private endpoint - Configuration, enter or select this information:

    设置Setting ValueValue
    联网Networking
    虚拟网络Virtual network 选择虚拟网络。Select your virtual network.
    子网Subnet 选择你的子网。Select your subnet.
    专用 DNS 集成Private DNS Integration
    与专用 DNS 区域集成Integrate with private DNS zone 请选择“是”。Select Yes.

    若要以私密方式连接到专用终结点,需有一条 DNS 记录。To connect privately with your private endpoint, you need a DNS record. 建议将专用终结点与专用 DNS 区域集成。We recommend that you integrate your private endpoint with a private DNS zone. 你也可以使用自己的 DNS 服务器,或者使用虚拟机上的主机文件创建 DNS 记录。You can also use your own DNS servers or create DNS records by using the host files on your virtual machines.
    专用 DNS 区域Private DNS Zone 选择“privatelink.documents.azure.cn”。Select privatelink.documents.azure.cn.

    系统会自动确定专用 DNS 区域。The private DNS zone is determined automatically. 无法使用 Azure 门户更改此区域。You can't change it by using the Azure portal.
  8. 选择“查看 + 创建”。Select Review + create. 在“查看 + 创建”页上,Azure 会验证你的配置。On the Review + create page, Azure validates your configuration.

  9. 看到“验证通过”消息时,选择“创建” 。When you see the Validation passed message, select Create.

如果已批准 Azure Cosmos 帐户的专用链接,则 Azure 门户上“防火墙和虚拟网络”窗格中的“所有网络”选项将不可用。 When you have approved Private Link for an Azure Cosmos account, in the Azure portal, the All networks option in the Firewall and virtual networks pane is unavailable.

下表显示了不同的 Azure Cosmos 帐户 API 类型、支持的子资源与相应的专用区域名称之间的映射。The following table shows the mapping between different Azure Cosmos account API types, supported sub-resources, and the corresponding private zone names. 还可以通过 SQL API 访问 Gremlin 和表 API 帐户,因此这些 API 有两个条目。You can also access the Gremlin and Table API accounts through the SQL API, so there are two entries for these APIs.

Azure Cosmos 帐户 API 类型Azure Cosmos account API type 支持的子资源(或组 ID)Supported sub-resources (or group IDs) 专用区域名称Private zone name
SqlSql SqlSql privatelink.documents.azure.cnprivatelink.documents.azure.cn
CassandraCassandra CassandraCassandra privatelink.cassandra.cosmos.azure.cnprivatelink.cassandra.cosmos.azure.cn
MongoMongo MongoDBMongoDB privatelink.mongo.cosmos.azure.cnprivatelink.mongo.cosmos.azure.cn
GremlinGremlin GremlinGremlin privatelink.gremlin.cosmos.azure.cnprivatelink.gremlin.cosmos.azure.cn
GremlinGremlin SqlSql privatelink.documents.azure.cnprivatelink.documents.azure.cn
Table Table privatelink.table.cosmos.azure.cnprivatelink.table.cosmos.azure.cn
Table SqlSql privatelink.documents.azure.cnprivatelink.documents.azure.cn

提取专用 IP 地址Fetch the private IP addresses

预配专用终结点后,可以查询 IP 地址。After the private endpoint is provisioned, you can query the IP addresses. 若要在 Azure 门户中查看 IP 地址,请执行以下操作:To view the IP addresses from the Azure portal:

  1. 选择“所有资源”,Select All resources.
  2. 搜索前面创建的专用终结点。Search for the private endpoint that you created earlier. 在本例中,该终结点为 cdbPrivateEndpoint3。In this case, it's cdbPrivateEndpoint3.
  3. 选择“概览”选项卡,查看 DNS 设置和 IP 地址。Select the Overview tab to see the DNS settings and IP addresses.

Azure 门户中的专用 IP 地址

可为每个专用终结点创建多个 IP 地址:Multiple IP addresses are created per private endpoint:

  • 一个 IP 地址用于 Azure Cosmos 帐户的多区域(与区域无关)终结点One for the multiple-regional (region-agnostic) endpoint of the Azure Cosmos account
  • 一个 IP 地址用于 Azure Cosmos 帐户所部署到的每个区域。One for each region where the Azure Cosmos account is deployed

使用 Azure PowerShell 创建专用终结点Create a private endpoint by using Azure PowerShell

运行以下 PowerShell 脚本,为现有 Azure Cosmos 帐户创建名为“MyPrivateEndpoint”的专用终结点。Run the following PowerShell script to create a private endpoint named "MyPrivateEndpoint" for an existing Azure Cosmos account. 请将变量值替换为你的环境的详细信息。Replace the variable values with the details for your environment.

$SubscriptionId = "<your Azure subscription ID>"
# Resource group where the Azure Cosmos account and virtual network resources are located
$ResourceGroupName = "myResourceGroup"
# Name of the Azure Cosmos account
$CosmosDbAccountName = "mycosmosaccount"

# API type of the Azure Cosmos account: Sql, MongoDB, Cassandra, Gremlin, or Table
$CosmosDbApiType = "Sql"
# Name of the existing virtual network
$VNetName = "myVnet"
# Name of the target subnet in the virtual network
$SubnetName = "mySubnet"
# Name of the private endpoint to create
$PrivateEndpointName = "MyPrivateEndpoint"
# Location where the private endpoint can be created. The private endpoint should be created in the same location where your subnet or the virtual network exists
$Location = "chinaeast2"

$cosmosDbResourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.DocumentDB/databaseAccounts/$($CosmosDbAccountName)"

$privateEndpointConnection = New-AzPrivateLinkServiceConnection -Name "myConnectionPS" -PrivateLinkServiceId $cosmosDbResourceId -GroupId $CosmosDbApiType

$virtualNetwork = Get-AzVirtualNetwork -ResourceGroupName  $ResourceGroupName -Name $VNetName  

$subnet = $virtualNetwork | Select -ExpandProperty subnets | Where-Object  {$_.Name -eq $SubnetName}  

$privateEndpoint = New-AzPrivateEndpoint -ResourceGroupName $ResourceGroupName -Name $PrivateEndpointName -Location "chinaeast2" -Subnet  $subnet -PrivateLinkServiceConnection $privateEndpointConnection

将专用终结点与专用 DNS 区域集成Integrate the private endpoint with a private DNS zone

创建专用终结点后,可以使用以下 PowerShell 脚本将其与专用 DNS 区域集成:After you create the private endpoint, you can integrate it with a private DNS zone by using the following PowerShell script:

Import-Module Az.PrivateDns
$zoneName = "privatelink.documents.azure.cn"
$zone = New-AzPrivateDnsZone -ResourceGroupName $ResourceGroupName `
  -Name $zoneName

$link  = New-AzPrivateDnsVirtualNetworkLink -ResourceGroupName $ResourceGroupName `
  -ZoneName $zoneName `
  -Name "myzonelink" `
  -VirtualNetworkId $virtualNetwork.Id  

$pe = Get-AzPrivateEndpoint -Name $PrivateEndpointName `
  -ResourceGroupName $ResourceGroupName

$networkInterface = Get-AzResource -ResourceId $pe.NetworkInterfaces[0].Id `
  -ApiVersion "2019-04-01"

foreach ($ipconfig in $networkInterface.properties.ipConfigurations) { 
foreach ($fqdn in $ipconfig.properties.privateLinkConnectionProperties.fqdns) { 
Write-Host "$($ipconfig.properties.privateIPAddress) $($fqdn)"  
$recordName = $fqdn.split('.',2)[0] 
$dnsZone = $fqdn.split('.',2)[1] 
New-AzPrivateDnsRecordSet -Name $recordName `
  -RecordType A -ZoneName $zoneName  `
  -ResourceGroupName $ResourceGroupName -Ttl 600 `
  -PrivateDnsRecords (New-AzPrivateDnsRecordConfig `
  -IPv4Address $ipconfig.properties.privateIPAddress)  
}
}

提取专用 IP 地址Fetch the private IP addresses

预配专用终结点后,可以使用以下 PowerShell 脚本查询 IP 地址和 FQDN 映射:After the private endpoint is provisioned, you can query the IP addresses and the FQDN mapping by using the following PowerShell script:

$pe = Get-AzPrivateEndpoint -Name MyPrivateEndpoint -ResourceGroupName myResourceGroup
$networkInterface = Get-AzNetworkInterface -ResourceId $pe.NetworkInterfaces[0].Id
foreach ($IPConfiguration in $networkInterface.IpConfigurations)
{
    Write-Host $IPConfiguration.PrivateIpAddress ":" $IPConfiguration.PrivateLinkConnectionProperties.Fqdns
}

使用 Azure CLI 创建专用终结点Create a private endpoint by using Azure CLI

运行以下 Azure CLI 脚本,为现有 Azure Cosmos 帐户创建名为“myPrivateEndpoint”的专用终结点。Run the following Azure CLI script to create a private endpoint named "myPrivateEndpoint" for an existing Azure Cosmos account. 请将变量值替换为你的环境的详细信息。Replace the variable values with the details for your environment.

# Resource group where the Azure Cosmos account and virtual network resources are located
ResourceGroupName="myResourceGroup"

# Subscription ID where the Azure Cosmos account and virtual network resources are located
SubscriptionId="<your Azure subscription ID>"

# Name of the existing Azure Cosmos account
CosmosDbAccountName="mycosmosaccount"

# API type of your Azure Cosmos account: Sql, MongoDB, Cassandra, Gremlin, or Table
CosmosDbApiType="Sql"

# Name of the virtual network to create
VNetName="myVnet"

# Name of the subnet to create
SubnetName="mySubnet"

# Name of the private endpoint to create
PrivateEndpointName="myPrivateEndpoint"

# Name of the private endpoint connection to create
PrivateConnectionName="myConnection"

az network vnet create \
 --name $VNetName \
 --resource-group $ResourceGroupName \
 --subnet-name $SubnetName

az network vnet subnet update \
 --name $SubnetName \
 --resource-group $ResourceGroupName \
 --vnet-name $VNetName \
 --disable-private-endpoint-network-policies true

az network private-endpoint create \
    --name $PrivateEndpointName \
    --resource-group $ResourceGroupName \
    --vnet-name $VNetName  \
    --subnet $SubnetName \
    --private-connection-resource-id "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.DocumentDB/databaseAccounts/$CosmosDbAccountName" \
    --group-ids $CosmosDbApiType \
    --connection-name $PrivateConnectionName

将专用终结点与专用 DNS 区域集成Integrate the private endpoint with a private DNS zone

创建专用终结点后,可以使用以下 Azure CLI 脚本将其与专用 DNS 区域集成:After you create the private endpoint, you can integrate it with a private DNS zone by using the following Azure CLI script:

zoneName="privatelink.documents.azure.cn"

az network private-dns zone create --resource-group $ResourceGroupName \
   --name  $zoneName

az network private-dns link vnet create --resource-group $ResourceGroupName \
   --zone-name  $zoneName\
   --name myzonelink \
   --virtual-network $VNetName \
   --registration-enabled false 

#Query for the network interface ID  
networkInterfaceId=$(az network private-endpoint show --name $PrivateEndpointName --resource-group $ResourceGroupName --query 'networkInterfaces[0].id' -o tsv)

# Copy the content for privateIPAddress and FQDN matching the Azure Cosmos account 
az resource show --ids $networkInterfaceId --api-version 2019-04-01 -o json 

#Create DNS records 
az network private-dns record-set a create --name recordSet1 --zone-name privatelink.documents.azure.cn --resource-group $ResourceGroupName
az network private-dns record-set a add-record --record-set-name recordSet2 --zone-name privatelink.documents.azure.cn --resource-group $ResourceGroupName -a <Private IP Address>

使用资源管理器模板创建专用终结点Create a private endpoint by using a Resource Manager template

可以通过在虚拟网络子网中创建专用终结点来设置专用链接。You can set up Private Link by creating a private endpoint in a virtual network subnet. 使用 Azure 资源管理器模板可以实现此目的。You achieve this by using an Azure Resource Manager template.

使用以下代码创建名为“PrivateEndpoint_template.json”的资源管理器模板。Use the following code to create a Resource Manager template named "PrivateEndpoint_template.json." 此模板在现有虚拟网络中为现有的 Azure Cosmos SQL API 帐户创建专用终结点。This template creates a private endpoint for an existing Azure Cosmos SQL API account in an existing virtual network.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Location for all resources."
          }
        },
        "privateEndpointName": {
            "type": "string"
        },
        "resourceId": {
            "type": "string"
        },
        "groupId": {
            "type": "string"
        },
        "subnetId": {
            "type": "string"
        }
    },
    "resources": [
        {
            "name": "[parameters('privateEndpointName')]",
            "type": "Microsoft.Network/privateEndpoints",
            "apiVersion": "2019-04-01",
            "location": "[parameters('location')]",
            "properties": {
                "subnet": {
                    "id": "[parameters('subnetId')]"
                },
                "privateLinkServiceConnections": [
                    {
                        "name": "MyConnection",
                        "properties": {
                            "privateLinkServiceId": "[parameters('resourceId')]",
                            "groupIds": [ "[parameters('groupId')]" ],
                            "requestMessage": ""
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {
        "privateEndpointNetworkInterface": {
          "type": "string",
          "value": "[reference(concat('Microsoft.Network/privateEndpoints/', parameters('privateEndpointName'))).networkInterfaces[0].id]"
        }
    }
}

定义模板的参数文件Define the parameters file for the template

为该模板创建一个参数文件,并将其命名为“PrivateEndpoint_parameters json”。Create a parameters file for the template, and name it "PrivateEndpoint_parameters.json." 将以下代码添加到参数文件:Add the following code to the parameters file:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateEndpointName": {
            "value": ""
        },
        "resourceId": {
            "value": ""
        },
        "groupId": {
            "value": ""
        },
        "subnetId": {
            "value": ""
        }
    }
}

使用 PowerShell 脚本部署模板Deploy the template by using a PowerShell script

使用以下代码创建 PowerShell 脚本。Create a PowerShell script by using the following code. 在运行该脚本之前,请将订阅 ID、资源组名称和其他变量值替换为你的环境的详细信息。Before you run the script, replace the subscription ID, resource group name, and other variable values with the details for your environment.

### This script creates a private endpoint for an existing Azure Cosmos account in an existing virtual network

## Step 1: Fill in these details. Replace the variable values with the details for your environment.
$SubscriptionId = "<your Azure subscription ID>"
# Resource group where the Azure Cosmos account and virtual network resources are located
$ResourceGroupName = "myResourceGroup"
# Name of the Azure Cosmos account
$CosmosDbAccountName = "mycosmosaccount"
# API type of the Azure Cosmos account. It can be one of the following: "Sql", "MongoDB", "Cassandra", "Gremlin", "Table"
$CosmosDbApiType = "Sql"
# Name of the existing virtual network
$VNetName = "myVnet"
# Name of the target subnet in the virtual network
$SubnetName = "mySubnet"
# Name of the private endpoint to create
$PrivateEndpointName = "myPrivateEndpoint"

$cosmosDbResourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.DocumentDB/databaseAccounts/$($CosmosDbAccountName)"
$VNetResourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($VNetName)"
$SubnetResourceId = "$($VNetResourceId)/subnets/$($SubnetName)"
$PrivateEndpointTemplateFilePath = "PrivateEndpoint_template.json"
$PrivateEndpointParametersFilePath = "PrivateEndpoint_parameters.json"

## Step 2: Sign in to your Azure account and select the target subscription.
Connect-AzAccount -Environment AzureChinaCloud
Select-AzSubscription -SubscriptionId $subscriptionId

## Step 3: Make sure private endpoint network policies are disabled in the subnet.
$VirtualNetwork= Get-AzVirtualNetwork -Name "$VNetName" -ResourceGroupName "$ResourceGroupName"
($virtualNetwork | Select -ExpandProperty subnets | Where-Object  {$_.Name -eq "$SubnetName"} ).PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork | Set-AzVirtualNetwork

## Step 4: Create the private endpoint.
Write-Output "Deploying private endpoint on $($resourceGroupName)"
$deploymentOutput = New-AzResourceGroupDeployment -Name "PrivateCosmosDbEndpointDeployment" `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile $PrivateEndpointTemplateFilePath `
    -TemplateParameterFile $PrivateEndpointParametersFilePath `
    -SubnetId $SubnetResourceId `
    -ResourceId $CosmosDbResourceId `
    -GroupId $CosmosDbApiType `
    -PrivateEndpointName $PrivateEndpointName

$deploymentOutput

在该 PowerShell 脚本中,GroupId 变量只能包含一个值。In the PowerShell script, the GroupId variable can contain only one value. 该值是帐户的 API 类型。That value is the API type of the account. 允许的值为:SqlMongoDBCassandraGremlinTableAllowed values are: Sql, MongoDB, Cassandra, Gremlin, and Table. 可通过多个 API 访问某些 Azure Cosmos 帐户类型。Some Azure Cosmos account types are accessible through multiple APIs. 例如:For example:

  • 可以从 Gremlin API 帐户和 SQL API 帐户访问 Gremlin API 帐户。A Gremlin API account can be accessed from both Gremlin and SQL API accounts.
  • 可以从表 API 帐户和 SQL API 帐户访问表 API 帐户。A Table API account can be accessed from both Table and SQL API accounts.

对于这些帐户,必须为每个 API 类型创建一个专用终结点。For those accounts, you must create one private endpoint for each API type. 相应的 API 类型在 GroupId 数组中指定。The corresponding API type is specified in the GroupId array.

成功部署模板后,可以看到类似于下图所示的输出。After the template is deployed successfully, you can see an output similar to what the following image shows. 如果正确设置了专用终结点,则 provisioningState 值为 SucceededThe provisioningState value is Succeeded if the private endpoints are set up correctly.

资源管理器模板的部署输出

部署模板后,专用 IP 地址会保留在子网中。After the template is deployed, the private IP addresses are reserved within the subnet. Azure Cosmos 帐户的防火墙规则配置为仅接受来自专用终结点的连接。The firewall rule of the Azure Cosmos account is configured to accept connections from the private endpoint only.

将专用终结点与专用 DNS 区域集成Integrate the private endpoint with a Private DNS Zone

使用以下代码创建名为“PrivateZone_template.json”的资源管理器模板。Use the following code to create a Resource Manager template named "PrivateZone_template.json." 此模板在现有虚拟网络中为现有的 Azure Cosmos SQL API 帐户创建专用 DNS 区域。This template creates a private DNS zone for an existing Azure Cosmos SQL API account in an existing virtual network.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateZoneName": {
            "type": "string"
        },
        "VNetId": {
            "type": "string"
        }        
    },
    "resources": [
        {
            "name": "[parameters('privateZoneName')]",
            "type": "Microsoft.Network/privateDnsZones",
            "apiVersion": "2018-09-01",
            "location": "global",
            "properties": {                
            }
        },
        {
            "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
            "apiVersion": "2018-09-01",
            "name": "[concat(parameters('privateZoneName'), '/myvnetlink')]",
            "location": "global",
            "dependsOn": [
                "[resourceId('Microsoft.Network/privateDnsZones', parameters('privateZoneName'))]"
            ],
            "properties": {
                "registrationEnabled": false,
                "virtualNetwork": {
                    "id": "[parameters('VNetId')]"
                }
            }
        }        
    ]
}

使用以下代码创建名为“PrivateZoneRecords_template.json”的资源管理器模板。Use the following code to create a Resource Manager template named "PrivateZoneRecords_template.json."

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "DNSRecordName": {
            "type": "string"
        },
        "IPAddress": {
            "type":"string"
        }        
    },
    "resources": [
         {
            "type": "Microsoft.Network/privateDnsZones/A",
            "apiVersion": "2018-09-01",
            "name": "[parameters('DNSRecordName')]",
            "properties": {
                "ttl": 300,
                "aRecords": [
                    {
                        "ipv4Address": "[parameters('IPAddress')]"
                    }
                ]
            }
        }    
    ]
}

定义模板的参数文件Define the parameters file for the template

为该模板创建以下两个参数文件。Create the following two parameters file for the template. 创建“PrivateZone_parameters.json”,为此请Create the "PrivateZone_parameters.json." 使用以下代码:with the following code:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "privateZoneName": {
            "value": ""
        },
        "VNetId": {
            "value": ""
        }
    }
}

创建“PrivateZoneRecords_parameters.json”,为此请Create the "PrivateZoneRecords_parameters.json." 使用以下代码:with the following code:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "DNSRecordName": {
            "value": ""
        },
        "IPAddress": {
            "type":"object"
        }
    }
}

使用 PowerShell 脚本部署模板Deploy the template by using a PowerShell script

使用以下代码创建 PowerShell 脚本。Create a PowerShell script by using the following code. 在运行该脚本之前,请将订阅 ID、资源组名称和其他变量值替换为你的环境的详细信息。Before you run the script, replace the subscription ID, resource group name, and other variable values with the details for your environment.

### This script:
### - creates a private zone
### - creates a private endpoint for an existing Cosmos DB account in an existing VNet
### - maps the private endpoint to the private zone

## Step 1: Fill in these details. Replace the variable values with the details for your environment.
$SubscriptionId = "<your Azure subscription ID>"
# Resource group where the Azure Cosmos account and virtual network resources are located
$ResourceGroupName = "myResourceGroup"
# Name of the Azure Cosmos account
$CosmosDbAccountName = "mycosmosaccount"
# API type of the Azure Cosmos account. It can be one of the following: "Sql", "MongoDB", "Cassandra", "Gremlin", "Table"
$CosmosDbApiType = "Sql"
# Name of the existing virtual network
$VNetName = "myVnet"
# Name of the target subnet in the virtual network
$SubnetName = "mySubnet"
# Name of the private zone to create
$PrivateZoneName = "myPrivateZone.documents.azure.cn"
# Name of the private endpoint to create
$PrivateEndpointName = "myPrivateEndpoint"

$cosmosDbResourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.DocumentDB/databaseAccounts/$($CosmosDbAccountName)"
$VNetResourceId = "/subscriptions/$($SubscriptionId)/resourceGroups/$($ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($VNetName)"
$SubnetResourceId = "$($VNetResourceId)/subnets/$($SubnetName)"
$PrivateZoneTemplateFilePath = "PrivateZone_template.json"
$PrivateZoneParametersFilePath = "PrivateZone_parameters.json"
$PrivateZoneRecordsTemplateFilePath = "PrivateZoneRecords_template.json"
$PrivateZoneRecordsParametersFilePath = "PrivateZoneRecords_parameters.json"
$PrivateEndpointTemplateFilePath = "PrivateEndpoint_template.json"
$PrivateEndpointParametersFilePath = "PrivateEndpoint_parameters.json"

## Step 2: Login your Azure account and select the target subscription
Connect-AzAccount -Environment AzureChinaCloud 
Select-AzSubscription -SubscriptionId $subscriptionId

## Step 3: Make sure private endpoint network policies are disabled in the subnet
$VirtualNetwork= Get-AzVirtualNetwork -Name "$VNetName" -ResourceGroupName "$ResourceGroupName"
($virtualNetwork | Select -ExpandProperty subnets | Where-Object  {$_.Name -eq "$SubnetName"} ).PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork | Set-AzVirtualNetwork

## Step 4: Create the private zone
New-AzResourceGroupDeployment -Name "PrivateZoneDeployment" `
    -ResourceGroupName $ResourceGroupName `
    -TemplateFile $PrivateZoneTemplateFilePath `
    -TemplateParameterFile $PrivateZoneParametersFilePath `
    -PrivateZoneName $PrivateZoneName `
    -VNetId $VNetResourceId

## Step 5: Create the private endpoint
Write-Output "Deploying private endpoint on $($resourceGroupName)"
$deploymentOutput = New-AzResourceGroupDeployment -Name "PrivateCosmosDbEndpointDeployment" `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile $PrivateEndpointTemplateFilePath `
    -TemplateParameterFile $PrivateEndpointParametersFilePath `
    -SubnetId $SubnetResourceId `
    -ResourceId $CosmosDbResourceId `
    -GroupId $CosmosDbApiType `
    -PrivateEndpointName $PrivateEndpointName
$deploymentOutput

## Step 6: Map the private endpoint to the private zone
$networkInterface = Get-AzResource -ResourceId $deploymentOutput.Outputs.privateEndpointNetworkInterface.Value -ApiVersion "2019-04-01"
foreach ($ipconfig in $networkInterface.properties.ipConfigurations) {
    foreach ($fqdn in $ipconfig.properties.privateLinkConnectionProperties.fqdns) {
        $recordName = $fqdn.split('.',2)[0]
        $dnsZone = $fqdn.split('.',2)[1]
        Write-Output "Deploying PrivateEndpoint DNS Record $($PrivateZoneName)/$($recordName) Template on $($resourceGroupName)"
        New-AzResourceGroupDeployment -Name "PrivateEndpointDNSDeployment" `
            -ResourceGroupName $ResourceGroupName `
            -TemplateFile $PrivateZoneRecordsTemplateFilePath `
            -TemplateParameterFile $PrivateZoneRecordsParametersFilePath `
            -DNSRecordName "$($PrivateZoneName)/$($RecordName)" `
            -IPAddress $ipconfig.properties.privateIPAddress
    }
}

配置自定义 DNSConfigure custom DNS

应在创建了专用终结点的子网中使用专用 DNS 区域。You should use a private DNS zone within the subnet where you've created the private endpoint. 配置终结点,以便将每个专用 IP 地址映射到某个 DNS 条目。Configure the endpoints so that each private IP address is mapped to a DNS entry. (请参阅前面所示响应中的 fqdns 属性。)(See the fqdns property in the response shown earlier.)

创建专用终结点时,可将其与 Azure 中的专用 DNS 区域集成。When you're creating the private endpoint, you can integrate it with a private DNS zone in Azure. 如果选择改用自定义 DNS 区域,则必须对其进行配置,以便为保留给专用终结点使用的所有专用 IP 地址添加 DNS 记录。If you choose to instead use a custom DNS zone, you have to configure it to add DNS records for all private IP addresses reserved for the private endpoint.

将专用链接与防火墙规则结合使用时,可能会出现以下情况和结果:The following situations and outcomes are possible when you use Private Link in combination with firewall rules:

  • 如果不配置任何防火墙规则,则默认情况下,所有流量都可以访问 Azure Cosmos 帐户。If you don't configure any firewall rules, then by default, all traffic can access an Azure Cosmos account.

  • 如果配置公共流量或服务终结点并创建专用终结点,则不同类型的传入流量将由相应类型的防火墙规则授权。If you configure public traffic or a service endpoint and you create private endpoints, then different types of incoming traffic are authorized by the corresponding type of firewall rule. 如果配置了服务终结点的子网中还配置了专用终结点:If a private endpoint is configured in a subnet where service endpoint is also configured:

    • 流向由专用终结点映射的数据库帐户的流量通过专用终结点进行路由,traffic to the database account mapped by the private endpoint is routed via private endpoint,
    • 从子网流向其他数据库帐户的流量通过服务终结点进行路由。traffic to other database accounts from the subnet is routed via service endpoint.
  • 如果在不配置任何公共流量或服务终结点的情况下创建专用终结点,则只能通过专用终结点访问 Azure Cosmos 帐户。If you don't configure any public traffic or service endpoint and you create private endpoints, then the Azure Cosmos account is accessible only through the private endpoints. 如果不配置公共流量或服务终结点,则在拒绝或删除所有已批准的专用终结点后,帐户将向整个网络开放,除非 PublicNetworkAccess 设置为“已禁用”(请参见以下部分)。If you don't configure public traffic or a service endpoint, after all approved private endpoints are rejected or deleted, the account is open to the entire network unless PublicNetworkAccess is set to Disabled (see section below).

在创建帐户期间阻止公共网络访问Blocking public network access during account creation

如前一部分所述,除非已设置特定的防火墙规则,否则添加专用终结点将使 Azure Cosmos 帐户仅可通过专用终结点访问。As described in the previous section, and unless specific firewall rules have been set, adding a private endpoint makes your Azure Cosmos account accessible through private endpoints only. 这意味着,在创建 Azure Cosmos 帐户之后、添加专用终结点之前,可以通过公共流量访问该帐户。This means that the Azure Cosmos account could be reached from public traffic after it is created and before a private endpoint gets added. 若要确保在创建专用终结点之前禁用公共网络访问,可以在创建帐户期间将 publicNetworkAccess 标志设置为 DisabledTo make sure that public network access is disabled even before the creation of private endpoints, you can set the publicNetworkAccess flag to Disabled during account creation. 有关演示如何使用此标志的示例,请参阅此 Azure 资源管理器模板See this Azure Resource Manager template for an example showing how to use this flag.

使用直接模式时的端口范围Port range when using direct mode

通过直接模式连接对 Azure Cosmos 帐户使用专用链接时,需要确保打开 TCP 端口的完整范围 (0 - 65535)。When you're using Private Link with an Azure Cosmos account through a direct mode connection, you need to ensure that the full range of TCP ports (0 - 65535) is open.

在添加或删除区域时更新专用终结点Update a private endpoint when you add or remove a region

在 Azure Cosmos 帐户中添加或删除区域需要添加或删除该帐户的 DNS 条目。Adding or removing regions to an Azure Cosmos account requires you to add or remove DNS entries for that account. 添加或删除区域后,可以更新子网的专用 DNS 区域,使之反映已添加或删除的 DNS 条目及其相应的专用 IP 地址。After regions have been added or removed, you can update the subnet's private DNS zone to reflect the added or removed DNS entries and their corresponding private IP addresses.

例如,假设你要在以下三个区域中部署 Azure Cosmos 帐户:“中国东部 2”、“中国北部”和“中国北部 2”。For example, imagine that you deploy an Azure Cosmos account in three regions: "China East 2", "China North", and "China North 2". 为帐户创建专用终结点时,子网中会保留四个专用 IP。When you create a private endpoint for your account, four private IPs are reserved in the subnet. 这三个区域中的每个区域都有一个 IP,而全局终结点/与区域无关的终结点有一个 IP。There's one IP for each of the three regions, and there's one IP for the global/region-agnostic endpoint.

以后,可将新的区域(例如“中国东部”)添加到 Azure Cosmos 帐户。Later, you might add a new region (for example, "China East") to the Azure Cosmos account. 添加新区域后,需要将相应的 DNS 记录添加到专用 DNS 区域或自定义 DNS。After adding the new region, you need to add a corresponding DNS record to either your private DNS zone or your custom DNS.

删除区域时可以使用相同的步骤。You can use the same steps when you remove a region. 删除区域后,需要从专用 DNS 区域或自定义 DNS 中删除相应的 DNS 记录。After removing the region, you need to remove the corresponding DNS record from either your private DNS zone or your custom DNS.

当前限制Current limitations

对 Azure Cosmos 帐户使用专用链接时存在以下限制:The following limitations apply when you're using Private Link with an Azure Cosmos account:

  • 一个 Azure Cosmos 帐户上最多只能有 200 个专用终结点。You can't have more than 200 private endpoints on a single Azure Cosmos account.

  • 通过直接模式连接对 Azure Cosmos 帐户使用专用链接时,只能使用 TCP 协议。When you're using Private Link with an Azure Cosmos account through a direct mode connection, you can use only the TCP protocol. HTTP 协议目前不受支持。The HTTP protocol is not currently supported.

  • 当你使用 Azure Cosmos DB 的用于 MongoDB 的 API 帐户时,仅服务器版本 3.6 上的帐户支持专用终结点(即使用 *.mongo.cosmos.azure.cn 格式的终结点的帐户)。When you're using Azure Cosmos DB's API for MongoDB accounts, a private endpoint is supported for accounts on server version 3.6 only (that is, accounts using the endpoint in the format *.mongo.cosmos.azure.cn). 服务器版本 3.2 上的帐户(即,使用格式为 *.documents.azure.cn 的终结点的帐户)不支持专用链接。Private Link is not supported for accounts on server version 3.2 (that is, accounts using the endpoint in the format *.documents.azure.cn). 若要使用专用链接,应将旧帐户迁移到新版本。To use Private Link, you should migrate old accounts to the new version.

  • 当你使用具有专用链接的 Azure Cosmos DB 的用于 MongoDB 的 API 帐户时,某些工具或库可能无法工作,因为它们会自动从连接字符串中去掉 appName 参数。When you're using an Azure Cosmos DB's API for MongoDB account that has Private Link, some tools or libraries may not work as they automatically strip out the appName parameter from the connection string. 此参数是通过专用终结点连接到帐户所必需的。This parameter is required to connect to the account over a private endpoint. 某些工具(如 Visual Studio Code)不会从连接字符串中删除此参数,因此它们是兼容的。Some tools, like Visual Studio Code, do not remove this parameter from the connection string and are therefore compatible.

  • 应在 Azure Cosmos 帐户范围内向网络管理员至少授予 Microsoft.DocumentDB/databaseAccounts/PrivateEndpointConnectionsApproval/action 权限,以创建自动批准的专用终结点。A network administrator should be granted at least the Microsoft.DocumentDB/databaseAccounts/PrivateEndpointConnectionsApproval/action permission at the Azure Cosmos account scope to create automatically approved private endpoints.

专用 DNS 区域集成的限制Limitations to private DNS zone integration

删除专用终结点或者从 Azure Cosmos 帐户中删除某个区域时,不会自动删除专用 DNS 区域中的 DNS 记录。DNS records in the private DNS zone are not removed automatically when you delete a private endpoint or you remove a region from the Azure Cosmos account. 在执行以下操作之前,必须先手动删除 DNS 记录:You must manually remove the DNS records before:

  • 添加链接到此专用 DNS 区域的新专用终结点。Adding a new private endpoint linked to this private DNS zone.
  • 将新区域添加到包含已链接到此专用 DNS 区域的专用终结点的任何数据库帐户。Adding a new region to any database account that has private endpoints linked to this private DNS zone.

如果不清理 DNS 记录,可能会发生意外的数据平面问题。If you don't clean up the DNS records, unexpected data plane issues might happen. 这些问题中的一个就是,在删除专用终结点或删除区域后添加的区域发生数据中断。These issues include data outage to regions added after private endpoint removal or region removal.

后续步骤Next steps

若要详细了解 Azure Cosmos DB 安全功能,请参阅以下文章:To learn more about Azure Cosmos DB security features, see the following articles: