Windows 10 和 Windows 11 Hyper-V 允许虚拟网络的本机网络地址转换(NAT)。
本指南将指导你完成作方法:
- 创建 NAT 网络
- 将现有虚拟机连接到新网络
- 确认虚拟机已正确连接
要求:
- Windows 10 周年更新或更高版本
- 已启用 Hyper-V。 按照说明 启用 Hyper-V
注释
目前,每个主机只能有一个 NAT 网络。 有关 Windows NAT(WinNAT)实现、功能和限制的其他详细信息,请参阅 WinNAT 功能和限制博客
NAT 概述
NAT 使用主机的 IP 地址和端口通过内部 Hyper-V 虚拟交换机授予虚拟机对网络资源的访问权限。
网络地址转换(NAT)是一种网络模式,旨在通过将外部 IP 地址和端口映射到更大的内部 IP 地址集来节省 IP 地址。 基本上,NAT 使用流表将流量从外部(主机)IP 地址和端口号路由到与网络(虚拟机、计算机、容器等)上的终结点关联的正确内部 IP 地址。
此外,NAT 允许多个虚拟机通过将这些端口映射到唯一的外部端口来托管需要相同(内部)通信端口的应用程序。
出于所有这些原因,NAT 网络对于容器技术非常常见(请参阅 容器网络)。
创建 NAT 虚拟网络
让我们逐步介绍如何设置新的 NAT 网络。
以管理员身份打开 PowerShell 控制台。
创建内部交换机。
New-VMSwitch -SwitchName "SwitchName" -SwitchType Internal查找刚创建的虚拟交换机的接口索引。
PS C:\> Get-NetAdapter Name InterfaceDescription ifIndex Status MacAddress LinkSpeed ---- -------------------- ------- ------ ---------- --------- vEthernet (intSwitch) Hyper-V Virtual Ethernet Adapter 24 Up 00-15-5D-00-6A-01 10 Gbps Wi-Fi Marvell AVASTAR Wireless-AC Net... 18 Up 98-5F-D3-34-0C-D3 300 Mbps Bluetooth Network ... Bluetooth Device ... 21 Disconnected 98-5F-D3-34-0C-D4 3 Mbps内部开关的名称类似于
vEthernet (SwitchName)和接口说明Hyper-V Virtual Ethernet Adapter。 记下其ifIndex在下一步中使用。使用 New-NetIPAddress 配置 NAT 网关。
下面是泛型命令:
New-NetIPAddress -IPAddress <NAT Gateway IP> -PrefixLength <NAT Subnet Prefix Length> -InterfaceIndex <ifIndex>若要配置网关,需要一些有关网络的信息:
- IPAddress -- NAT 网关 IP 指定要用作 NAT 网关 IP 的 IPv4 或 IPv6 地址。
泛型形式为 a.b.c.1(例如 172.16.0.1)。 虽然最终位置不必为 .1,但它通常是(基于前缀长度)。 此 IP 地址位于来宾虚拟机使用的地址范围内。 例如,如果来宾 VM 使用 IP 范围 172.16.0.0,则可以使用 IP 地址 172.16.0.100 作为 NAT 网关。 通用网关 IP 为 192.168.0.1
PrefixLength -- NAT 子网前缀长度定义 NAT 本地子网大小(子网掩码)。 子网前缀长度是介于 0 和 32 之间的整数值。
0 将映射整个 Internet,32 只允许一个映射的 IP。 常见值的范围从 24 到 12,具体取决于需要附加到 NAT 的 IP 数量。
常见的 PrefixLength 为 24 -- 这是子网掩码 255.255.255.0
InterfaceIndex -- ifIndex 是虚拟交换机的接口索引,在上一步中确定。
运行以下命令以创建 NAT 网关:
New-NetIPAddress -IPAddress 192.168.0.1 -PrefixLength 24 -InterfaceIndex 24使用 New-NetNat 配置 NAT 网络。
下面是泛型命令:
New-NetNat -Name <NATOutsideName> -InternalIPInterfaceAddressPrefix <NAT subnet prefix>若要配置网关,需要提供有关网络和 NAT 网关的信息:
名称 -- NATOutsideName 描述 NAT 网络的名称。 你将使用它来删除 NAT 网络。
InternalIPInterfaceAddressPrefix -- NAT 子网前缀描述 NAT 网关 IP 前缀和 NAT 子网前缀长度。
泛型形式为 a.b.c.0/NAT 子网前缀长度
对于此示例,我们将使用 192.168.0.0/24
运行以下命令以设置 NAT 网络:
New-NetNat -Name MyNATnetwork -InternalIPInterfaceAddressPrefix 192.168.0.0/24
祝贺! 现在已拥有虚拟网络 NAT 网络!
连接虚拟机
若要将虚拟机连接到新的 NAT 网络,请使用“VM 设置”菜单将本文第一步中创建的内部交换机连接到虚拟机。
由于 WinNAT 本身不会分配 IP 地址并将 IP 地址分配给终结点(例如 VM),因此需要从 VM 本身内部手动执行此作,即在 NAT 内部前缀范围内设置 IP 地址、设置默认网关 IP 地址、设置 DNS 服务器信息。 唯一需要注意的是,终结点附加到容器时。 在这种情况下,主机网络服务(HNS)分配并使用主机计算服务(HCS)将 IP 地址、网关 IP 和 DNS 信息直接分配给容器。
配置示例:将 VM 和容器附加到 NAT 网络
如果需要将多个 VM 和容器附加到单个 NAT,则需要确保 NAT 内部子网前缀足够大,以包含不同应用程序或服务分配的 IP 范围(例如适用于 Windows 和 Windows 容器的 Docker – HNS)。 这需要 IP 和网络配置的应用程序级分配或管理员必须完成的手动配置,并保证不要在同一主机上重复使用现有 IP 分配。
适用于 Windows 的 Docker(Linux VM)和 Windows 容器
按照本节中的说明作,允许用于 Windows 的 Docker、(运行 Linux 容器的 Linux VM)和 Windows 容器使用单独的内部 vSwitch 共享同一 WinNAT 实例。 Linux 和 Windows 容器之间的连接工作。
用户已通过名为“VMNAT”的内部 vSwitch 将 VM 连接到 NAT 网络,现在想要通过 docker 引擎安装 Windows 容器功能:
PS C:\> Get-NetNat “VMNAT”| Remove-NetNat (this removes the NAT but keep the internal vSwitch).
Install Windows Container Feature
DO NOT START Docker Service (daemon)
Edit the arguments passed to the docker daemon (dockerd) by adding –fixed-cidr=<container prefix> parameter. This tells docker to create a default nat network with the IP subnet <container prefix> (e.g. 192.168.1.0/24) so that HNS can allocate IPs from this prefix.
PS C:\> Start-Service Docker; Stop-Service Docker
PS C:\> Get-NetNat | Remove-NetNAT (again, this removes the NAT but keep the internal vSwitch)
PS C:\> New-NetNat -Name SharedNAT -InternalIPInterfaceAddressPrefix <shared prefix>
PS C:\> Start-Service docker
Docker/HNS 将 IP 分配给 Windows 容器,管理员将 IP 从两者的不同集分配给 VM。
用户已安装运行 Docker 引擎的 Windows 容器功能,现在想要将 VM 连接到 NAT 网络:
PS C:\> Stop-Service docker
PS C:\> Get-ContainerNetwork | Remove-ContainerNetwork -force
PS C:\> Get-NetNat | Remove-NetNat (this will remove the NAT but keep the internal vSwitch)
Edit the arguments passed to the docker daemon (dockerd) by adding -b “none” option to the end of docker daemon (dockerd) command to tell docker not to create a default NAT network.
PS C:\> New-ContainerNetwork –name nat –Mode NAT –subnetprefix <container prefix> (create a new NAT and internal vSwitch – HNS will allocate IPs to container endpoints attached to this network from the <container prefix>)
PS C:\> Get-Netnat | Remove-NetNAT (again, this will remove the NAT but keep the internal vSwitch)
PS C:\> New-NetNat -Name SharedNAT -InternalIPInterfaceAddressPrefix <shared prefix>
PS C:\> New-VirtualSwitch -Type internal (attach VMs to this new vSwitch)
PS C:\> Start-Service docker
Docker/HNS 将 IP 分配给 Windows 容器,管理员将 IP 从两者的不同集分配给 VM。
最后,你将有两个内部 VM 交换机,一个 NetNat 在它们之间共享。
使用同一 NAT 的多个应用程序
某些方案要求多个应用程序或服务使用相同的 NAT。 在这种情况下,必须遵循以下工作流,以便多个应用程序/服务可以使用更大的 NAT 内部子网前缀
我们将详细介绍 Docker 4 Windows - Docker Beta - Linux VM 与同一主机上的 Windows 容器功能共同存在,例如。此工作流可能会更改
-
net stop docker -
Stop Docker4Windows MobyLinux VM -
Get-ContainerNetwork | Remove-ContainerNetwork -force 删除任何以前存在的容器网络(即删除 vSwitch、删除 NetNat、清理)。
Get-NetNat | Remove-NetNat创建名为 nat 的内部 vSwitch 和 IP 前缀为 10.0.76.0/24 的 NAT 网络。
New-ContainerNetwork -Name nat -Mode NAT –subnetprefix 10.0.76.0/24删除 DockerNAT 和 nat NAT 网络(保留内部 vSwitch)。
Remove-NetNAT为要共享的 D4W 和容器创建名为 DockerNAT 的 NAT 网络,其前缀为 10.0.0.0/17。
New-NetNat -Name DockerNAT -InternalIPInterfaceAddressPrefix 10.0.0.0/17运行 Docker4Windows (MobyLinux.ps1)
使用用户定义的 NAT 网络作为默认连接 Windows 容器。
Net start docker
最后,有两个内部 vSwitch - 一个名为 DockerNAT ,另一个名为 nat。 只有一个 NAT 网络(10.0.0.0/17)通过运行 Get-NetNat 进行确认。 Windows 容器的 IP 地址由 Windows 主机网络服务 (HNS) 从 10.0.76.0/24 子网分配。 根据现有的 MobyLinux.ps1 脚本,从 10.0.75.0/24 子网分配 Docker 4 Windows 的 IP 地址。
Troubleshooting
不支持多个 NAT 网络
本指南假定主机上没有其他 NAT。 但是,应用程序或服务需要使用 NAT,并且可以在设置过程中创建一个。 由于 Windows (WinNAT) 仅支持一个内部 NAT 子网前缀,所以尝试创建多个 NAT 会将系统置于未知状态。
若要查看这是否是问题,请确保只有一个 NAT:
Get-NetNat
如果 NAT 已存在,请将其删除:
Get-NetNat | Remove-NetNat
确保只有一个应用程序或功能的“内部”vmSwitch(例如 Windows 容器)。 记录 vSwitch 的名称:
Get-VMSwitch
检查是否存在专用 IP 地址(例如 NAT 默认网关 IP 地址 – 通常 为 x)。y.z.1) 仍然分配给适配器的旧 NAT:
Get-NetIPAddress -InterfaceAlias "vEthernet (<name of vSwitch>)"
如果使用旧的专用 IP 地址,请将其删除:
Remove-NetIPAddress -InterfaceAlias "vEthernet (<name of vSwitch>)" -IPAddress <IPAddress>
删除多个 NAT 我们无意中看到了多个 NAT 网络的报告。 如果在运行 docker 网络 ls 或 Get-ContainerNetwork 后看到多个 NAT 网络,请从提升的 PowerShell 执行以下作:
$keys = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services\vmsmp\parameters\SwitchList"
foreach($key in $keys)
{
if ($key.GetValue("FriendlyName") -eq 'nat')
{
$newKeyPath = $KeyPath+"\"+$key.PSChildName
Remove-Item -Path $newKeyPath -Recurse
}
}
Remove-NetNat -Confirm:$false
Get-ContainerNetwork | Remove-ContainerNetwork
Get-VmSwitch -Name nat | Remove-VmSwitch # failure is expected
Stop-Service docker
Set-Service docker -StartupType Disabled
在执行后续命令之前重新启动作系统 (Restart-Computer)
Get-NetNat | Remove-NetNat
Set-Service docker -StartupType Automatic
Start-Service docker