Notas

Notas

Instalé Ubuntu 18.04 en Hyper-V en un host de Windows 10 y expuse la funcionalidad en algunos puertos, que están disponibles para otros programas que se ejecutan en el host al acceder http://vm-ip-number:port(es decir http://192.168.0.1:12345). Funciona muy bien.

Me gustaría usar un nombre en lugar del número de IP de la VM para conectarme a ella (por todas las razones habituales, ya que esto irá en los archivos de configuración). Para servidores Linux o MacOS completos, dejaría que el host se anunciara usando zeroconf, pero algunas búsquedas indicaron que esto no funciona bien para Windows 10 a través de los límites de las VM.

Otro enfoque podría ser hacer que Hyper-V asigne a la VM un nombre proporcionado por mí que luego esté disponible cuando la VM esté activa, pero no estoy lo suficientemente familiarizado con Hyper-V para saber si esto es posible o no. Es aceptable instalar herramientas adicionales solo para esto en el huésped, en el anfitrión solo si es necesario.

Todo lo que quiero es poder http://my-own-nameacceder a la VM cuando se ejecuta sin codificar el número de IP en ningún lugar.

¿Sugerencias?

Respuesta1

El siguiente script de PowerShell generará un hostsarchivo que contiene las direcciones IP y los nombres de VM para todas las VM en ejecución:

get-vm | Get-VMNetworkAdapter | ? IPAddresses -ne $null | % {Write-Output "$($_.ipaddresses[0]) $($_.VMName)"} | Set-Content -Path ".\hosts"

Algunos puntos a tener en cuenta:

  • El script debe ejecutarse como administrador.

  • ElContenido del conjunto El comando necesita un mejor parámetro de ruta, ya que actualmente sobrescribirá el hostsarchivo en la carpeta actual.

  • Si no desea que el hostsarchivo se sobrescriba, sino que se agregue, utilice Agregar contenido comando en su lugar. De esta manera, puede comenzar desde un hostsarchivo inicial y simplemente agregarlo.

  • El Salida de escritura El comando genera la primera entrada en el ipaddressescampo. Si tanto IPv4 como IPv6 están habilitados, la lista contendrá dos entradas, donde la primera entrada suele ser la de IPv4.

Un hostsarchivo de ejemplo que se generó para mi máquina virtual en ejecución mediante este script:

172.17.223.121 Windows10Test

(Probablemente sea mejor evitar espacios en blanco en los nombres de las máquinas virtuales, o será necesario trabajar más en el script).

Respuesta2

Agregue la dirección IP en el archivo HOSTS de Windows. El camino completo es C:\Windows\System32\drivers\etc\hosts. Ejecute el Bloc de notas (o cualquier editor de texto) como administrador y abra ese archivo con Ctrl+ O. Luego agregue la dirección IP. El formato será la dirección IP y luego el nombre del invitado. Aquí hay una muestra:

# This is a comment
# 127.0.0.1 localhost loopback
# ::1 localhost

192.168.0.1 myguest

Para más información, leaWikipedia: hosts (archivo).

Respuesta3

Encontré una manera de conectarme por nombre a las máquinas virtuales invitadas desde otras máquinas virtuales invitadas o el host, usando nombres que Hyper-V administra automáticamente, de la siguiente manera:

  1. Conecte el invitado al conmutador predeterminado (este es el valor predeterminado para una nueva máquina virtual).
  2. Configure la dirección IP en DHCP en el invitado (este es el valor predeterminado para una nueva máquina virtual).
  3. Establezca el nombre de la computadora/nombre de host dentro del sistema operativo invitado en algo único, por ejemplo myfirstvm. El sufijo DNS no importa.
  4. Desde otra máquina virtual o el host, intente comunicarse con <host_name>.mshome.net, por ejemplo, si configura el nombre de host en myfirstvm, intente hacer ping myfirstvm.mshome.netdesde el host.

Explicación:

En mi sistema encontré un archivo en el mismo directorio que el hostsarchivo llamado hosts.ics. Parecía contener entradas para todos mis invitados adjuntos aDefault Switch y una entrada para el sistema base, pero todos con el sufijo mshome.net. Creo que los adaptadores de red conectados al conmutador predeterminado utilizan la función Conexión compartida a Internet, que crea y mantiene automáticamente este hosts.icsarchivo. Cuando su invitado arranca, solicita una dirección IP mediante DHCP e intenta registrarse en el servidor DNS integrado en Hyper-V. Creo que Hyper-V toma el nombre que el invitado intenta registrar y lo almacena en este hosts.icsarchivo con un nuevo sufijo mshome.net. Si dos de sus máquinas virtuales invitadas intentan registrar el mismo nombre, este proceso se interrumpirá.

No estoy seguro si se trata de una característica nueva o si siempre ha estado aquí. Encontrado en Windows 11 Pro, Hyper-V 10.0.22000.1

Respuesta4

Este script de PowerShell se basa enLucas Schlatherla respuesta de (https://superuser.com/a/1485949/280673) a esta pregunta.

La diferencia más importante es que no sobrescribe todo el archivo de hosts con las direcciones IP de sus VM, sino que agrega nuevas entradas si hay nuevas VM y sobrescribe las direcciones de las entradas preexistentes. Esto debería eliminar la necesidad de realizar copias de seguridad y preservar otras entradas en el archivo de hosts que pueda haber creado para el desarrollo local u otros fines.

#Requires -RunAsAdministrator

# Based on: https://superuser.com/a/1485949

Write-Host "Fix entries for local HyperV VMs in hosts file."

Set-StrictMode -Version 3.0
$ErrorActionPreference = "Stop"
$hostsFile = "${env:SystemRoot}/System32/drivers/etc/hosts"

$hostsFileContentOriginal = (Get-Content $hostsFile)
$hostsFileContent = $hostsFileContentOriginal

Write-Debug "Original hosts file content:"
Write-Debug ($hostsFileContent | Out-String)
Write-Debug "`n`n"

foreach ($vm in (Get-VM | Get-VMNetworkAdapter))
{
   $vmName = $($vm.VMName)
   $vmNameSanitized = $vm.VMName.ToLower() -replace '[. ]',''
   $hostName = "${vmNameSanitized}.local"
   Write-Verbose "Porcessing $vm."
   if (0 -lt $vm.IPAddresses.Length)
   {
      Write-Verbose "VM ${vmname} has IP addresses, updating hosts file."
      $address = $vm.IPAddresses[0]
      Write-Verbose "Selected IP Address for ${vmname}: $address."
      Write-Debug "All IP Addresses for ${vmname}: $($vm.IPAddresses)."

      $vmPreviouslyAddedToHostsFile = $hostsFileContent -match ".*$hostName.*"
      if($vmPreviouslyAddedToHostsFile)
      {
         Write-Verbose "VM $vmName already present in hosts, updating entry."
         # # Regex explanation
         # - `([^\d]*)` is a grouping `()` of 0 or more of the character group `[]*` that contains no digits `^\d`.
         # - `(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})` is a grouping `()` of 4 collections of 1 to 3 digits `\d{1,3}`, separated by a dot `\.`, which should match an ipv4 address.
         # - `(\s+$hostName.*)` is a grouping `()` that matches 1 or more spaces `\s+`, followed by the content of the hostname variable `$hostName`, followed by 0 or more of any characters `.*`.
         # # Substitution expression explanation
         # `${n}` is used to access the n-th (1 indexed) grouping from the regex.
         # Because we want to access the `$address` variable we can't use literal strings `''` but have to use normal strings instead `""`.
         # This results in having to escape the `$` character when doing the group substitution access.
         # # Caveat emptor
         # This only works for ipv4 addresses as written.
         # If you want to support ipv6 addresses, consider using `([a-f0-9:]+:+)+[a-f0-9]+` from https://stackoverflow.com/a/37355379 .
         # It will fail in interesting ways if the entry is commented out and there are digits in the comment in a position preceding the address.
         $hostsFileContent = $hostsFileContent -replace "([^\d]*)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\s+$hostName.*)","`${1}$address`${3}" -join "`r`n"
      }
      else
      {
         Write-Verbose "VM $vmName not previously in hosts, appending entry."
         $hostsFileContent += "$address $hostName" -join "`r`n"
      }
   }
   else
   {
      Write-Verbose "VM ${vmname} doesn't have IP addresses, skipping."
   }
}

$originalAsString = ($hostsFileContentOriginal | Out-String)
$updatedAsString = ($hostsFileContent | Out-String)

Write-Debug "`n`nUpdated hosts file content:"
Write-Debug "$updatedAsString"

if($originalAsString -ne $updatedAsString)
{
   Write-Host "There are new addresses for VMs, updtating hosts file."

   # $datestring = (Get-Date -Format "o") -replace '[:\-]','-'
   # $backupHostsFile = "$hostsFile.${datestring}.bak"
   # Write-Verbose "Backing up hosts file to $backupHostsFile."
   # Copy-Item $hostsFile $backupHostsFile

   # Write-Verbose "Setting new hosts file content."

   Set-Content -Path $hostsfile -Value $hostsFileContent -Encoding UTF8
}
else
{
   Write-Host "No new VMs or addresses, exiting."
}

Notas

Dependiendo de su VM, es posible que deba instalar paquetes adicionales dentro de la VM, por ejemplohyperven arch, antes de que pueda desenterrar la IP que se asigna a la VM desde HyperV y PowerShell. Es probable que esto varíe entre diferentes sistemas operativos, por lo que probablemente tendrá que buscar una guía para su sistema (o publicar una nueva pregunta) si no puede obtener la dirección del lado del host.

Dejé la sección de respaldo y simplemente la comenté para que sea más fácil experimentar e iterar con el script. También para que sea más fácil realizar copias de seguridad si se desean en un lugar más sensato (no es necesario realizar copias de seguridad si no se realizan cambios, así que no las haga hasta justo antes de que se escriban los cambios).

También puse el comentario sobre cómo funciona la expresión regular para sustituir la dirección en el código, en lugar de afuera aquí en el cuerpo de la publicación. Esto es para que sea más fácil seguir el código en caso de que la referencia a esta publicación se pierda después de copiar y pegar, y con suerte será de ayuda si alguien quiera hacerle cambios.

información relacionada