一个网络接口 (NIC) :在指定的虚拟网络/子网中保留专用 IP 地址的网络接口。 此网络接口是部署虚拟机 (VM) 时部署的同一个资源,但它不会分配到 VM,而是由专用终结点拥有。
一个专用 DNS 区域:如果你以前从未为此虚拟网络部署过专用终结点,系统将为虚拟网络部署新的专用 DNS 区域。 此外,将为此 DNS 区域中的 Azure 资源创建 DNS A 记录。 如果已在此虚拟网络中部署了专用终结点,则会将 Azure 资源的新 A 记录添加到现有 DNS 区域。 部署 DNS 区域是可选操作,但强烈建议执行此操以来简化所需的 DNS 管理。
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account.
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageAccountName-Connection" `
-PrivateLinkServiceId $storageAccount.Id `
-GroupId "file" `
-ErrorAction Stop
# Create a new private endpoint.
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageAccountResourceGroupName `
-Name "$storageAccountName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
创建 Azure 专用 DNS 区域可将存储帐户的原始名称(例如 storageaccount.file.core.windows.net)解析为虚拟网络内部的专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果直接使用 AD 用户主体装载或通过 REST API 访问 Azure 文件共享,则此操作肯定是必需的。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$storageAccountSuffix = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty StorageEndpointSuffix
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
$dnsZoneName = "privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
创建 Azure 专用 DNS 区域可将存储帐户的原始名称(例如 storageaccount.file.core.windows.net)解析为虚拟网络内部的专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果使用 AD 用户主体装载或通过 REST API 访问 Azure 文件共享,则此操作肯定是必需的。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
storageAccountSuffix=$(az cloud show \
--query "suffixes.storageEndpoint" | \
tr -d '"')
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
dnsZoneName="privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
获取对专用 DNS 区域的引用后,接下来必须创建存储帐户的 A 记录。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateEndpointIP=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[0].privateIPAddress" | \
tr -d '"')
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name $storageAccountName \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name $storageAccountName \
--ipv4-address $privateEndpointIP \
--output none
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account.
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageSyncServiceName-Connection" `
-PrivateLinkServiceId $storageSyncService.ResourceId `
-GroupId "Afs" `
-ErrorAction Stop
# Create a new private endpoint.
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name "$storageSyncServiceName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
通过创建 Azure 专用 DNS 区域,存储同步服务的主机名(如 mysssmanagement.westus2.afs.azure.net)可解析为虚拟网络内的存储同步服务的正确专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果 Azure 文件同步代理要访问存储同步服务,则此操作肯定是必需的。
# Get the desired Storage Sync Service suffix (afs.azure.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$azureEnvironment = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty Name
switch($azureEnvironment) {
"AzureCloud" {
$storageSyncSuffix = "afs.azure.net"
}
"AzureUSGovernment" {
$storageSyncSuffix = "afs.azure.us"
}
"AzureChinaCloud" {
$storageSyncSuffix = "afs.azure.cn"
}
default {
Write-Error
-Message "The Azure environment $_ is not currently supported by Azure File Sync." `
-ErrorAction Stop
}
}
# For public cloud, this will generate the following DNS suffix:
# privatelink.afs.azure.net
$dnsZoneName = "privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
通过创建 Azure 专用 DNS 区域,存储同步服务的主机名(如 mysssmanagement.westus2.afs.azure.net)可解析为虚拟网络内的存储同步服务的正确专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果 Azure 文件同步代理要访问存储同步服务,则此操作肯定是必需的。
# Get the desired storage account suffix (afs.azure.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
azureEnvironment=$(az cloud show \
--query "name" |
tr -d '"')
storageSyncSuffix=""
if [ $azureEnvironment == "AzureCloud" ]
then
storageSyncSuffix="afs.azure.net"
elif [ $azureEnvironment == "AzureUSGovernment" ]
then
storageSyncSuffix="afs.azure.us"
else
echo "Unsupported Azure environment $azureEnvironment."
fi
# For public cloud, this will generate the following DNS suffix:
# privatelinke.afs.azure.net.
dnsZoneName="privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
获取对专用 DNS 区域的引用后,接下来必须创建存储同步服务的 A 记录。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateIpAddresses=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateIpAddress" \
--output tsv)
hostNames=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateLinkConnectionProperties.fqdns[]" \
--output tsv)
i=0
for privateIpAddress in $privateIpAddresses
do
j=0
targetHostName=""
for hostName in $hostNames
do
if [ $i == $j ]
then
targetHostName=$hostName
break
fi
j=$(expr $j + 1)
done
endpointName=$(echo $targetHostName | \
cut -c1-$(expr $(expr index $targetHostName ".") - 1))
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name "$endpointName.$storageSyncServiceRegion" \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name "$endpointName.$storageSyncServiceRegion" \
--ipv4-address $privateIpAddress \
--output none
i=$(expr $i + 1)
done
# This assumes $storageAccount is still defined from the beginning of this of this guide.
$storageAccount | Update-AzStorageAccountNetworkRuleSet `
-DefaultAction Deny `
-Bypass AzureServices `
-WarningAction SilentlyContinue `
-ErrorAction Stop | `
Out-Null
# This assumes $storageAccountResourceGroupName and $storageAccountName
# are still defined from the beginning of this guide.
az storage account update \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--bypass "AzureServices" \
--default-action "Deny" \
--output none
serviceEndpoints=$(az network vnet subnet show \
--resource-group $restrictToVirtualNetworkResourceGroupName \
--vnet-name $restrictToVirtualNetworkName \
--name $subnetName \
--query "serviceEndpoints[].service" \
--output tsv)
foundStorageServiceEndpoint=false
for serviceEndpoint in $serviceEndpoints
do
if [ $serviceEndpoint = "Microsoft.Storage" ]
then
foundStorageServiceEndpoint=true
fi
done
if [ $foundStorageServiceEndpoint = false ]
then
serviceEndpointList=""
for serviceEndpoint in $serviceEndpoints
do
serviceEndpointList+=$serviceEndpoint
serviceEndpointList+=" "
done
serviceEndpointList+="Microsoft.Storage"
az network vnet subnet update \
--ids $subnet \
--service-endpoints $serviceEndpointList \
--output none
fi