노트

노트

Windows 10 호스트의 Hyper-V에 Ubuntu 18.04를 설치하고 일부 포트에 기능을 노출했습니다. 이 http://vm-ip-number:port기능 은 액세스할 때 호스트에서 실행 중인 다른 프로그램에서 사용할 수 있습니다 http://192.168.0.1:12345. 아주 잘 작동합니다.

VM의 IP 번호 대신 이름을 사용하여 연결하고 싶습니다(모든 일반적인 이유는 구성 파일에 저장되기 때문입니다). 전체 Linux 또는 MacOS 서버의 경우 호스트가 zeroconf를 사용하여 자체적으로 알리도록 했지만 일부 검색에서는 이것이 VM 경계를 넘어 Windows 10에서는 제대로 작동하지 않는 것으로 나타났습니다.

또 다른 접근 방식은 Hyper-V에서 내가 제공한 이름을 VM에 할당하여 VM이 작동 중일 때 사용할 수 있도록 하는 것입니다. 하지만 이것이 가능한지 여부를 알 수 있을 만큼 Hyper-V에 익숙하지 않습니다. 이를 위해 게스트에 추가 도구를 설치하는 것은 허용되며 필요한 경우에만 호스트에 설치됩니다.

http://my-own-name내가 원하는 것은 어디에서나 IP 번호를 하드코딩하지 않고 실행할 때 VM에 액세스하는 데 사용할 수 있는 것입니다 .

제안?

답변1

다음 PowerShell 스크립트는 hosts실행 중인 모든 VM에 대한 IP 주소와 VM 이름을 포함하는 파일을 생성합니다.

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

참고할 사항:

  • 스크립트는 관리자 권한으로 실행되어야 합니다.

  • 그만큼세트컨텐츠hosts명령에는 현재 폴더의 파일을 덮어쓰므로 더 나은 Path 매개변수가 필요합니다 .

  • hosts파일을 덮어쓰지 않고 추가하려면 다음을 사용하세요 .콘텐츠 추가 대신 명령을 내리세요. 이렇게 하면 초기 hosts파일에서 시작하여 추가할 수 있습니다.

  • 그만큼 쓰기 출력 명령은 필드의 첫 번째 항목을 출력합니다 ipaddresses. IPv4와 IPv6가 모두 활성화된 경우 목록에는 두 개의 항목이 포함되며, 첫 번째 항목은 일반적으로 IPv4 항목입니다.

hosts이 스크립트를 통해 실행 중인 VM에 대해 생성된 예제 파일은 다음과 같습니다.

172.17.223.121 Windows10Test

(VM 이름에 공백을 두지 않는 것이 더 좋으며, 그렇지 않으면 스크립트에 더 많은 작업이 필요합니다.)

답변2

Windows HOSTS 파일에 IP 주소를 추가합니다. 전체 경로는 입니다 C:\Windows\System32\drivers\etc\hosts. 관리자 권한으로 메모장(또는 텍스트 편집기)을 실행하고 Ctrl+ 를 사용하여 해당 파일을 엽니다 O. 그런 다음 IP 주소를 추가합니다. 형식은 IP 주소, 게스트 이름 순입니다. 다음은 샘플입니다.

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

192.168.0.1 myguest

자세한 내용은 다음을 읽어보세요.Wikipedia: 호스트(파일).

답변3

다음과 같이 Hyper-V에서 자동으로 관리되는 이름을 사용하여 다른 게스트 VM 또는 호스트에서 게스트 VM에 이름으로 연결하는 방법을 찾았습니다.

  1. 게스트를 기본 스위치(새 VM의 기본값)에 연결합니다.
  2. 게스트의 IP 주소를 DHCP로 설정합니다(새 VM의 기본값).
  3. 게스트 OS 내의 컴퓨터 이름/호스트 이름을 고유한 것으로 설정합니다(예: myfirstvm. DNS 접미사는 중요하지 않습니다.
  4. 다른 VM이나 호스트에서 에 연결해 보십시오 <host_name>.mshome.net. 예를 들어 호스트 이름을 로 설정한 경우 호스트에서 myfirstvm핑을 시도해 보십시오 .myfirstvm.mshome.net

설명:

hosts내 시스템에서 .라는 파일 과 동일한 디렉터리에 있는 파일을 찾았습니다 hosts.ics. 여기에 첨부된 모든 손님에 대한 항목이 포함된 것 같습니다.Default Switch 기본 시스템에 대한 항목, 그러나 모두 접미사가 붙습니다 mshome.net. 기본 스위치에 연결된 네트워크 어댑터는 이 hosts.ics파일을 자동으로 생성하고 유지하는 인터넷 연결 공유 기능을 사용하는 것으로 생각됩니다. 게스트가 부팅되면 DHCP를 통해 IP 주소를 요청하고 Hyper-V에 내장된 DNS 서버에 등록을 시도합니다. 저는 Hyper-V가 게스트가 등록하려고 하는 이름을 가져와 이 hosts.ics파일 에 mshome.net. 게스트 VM 중 두 개가 모두 동일한 이름을 등록하려고 하면 이 프로세스가 중단됩니다.

이것이 새로운 기능인지 아니면 항상 여기에 있었던 것인지 확실하지 않습니다. Windows 11 Pro, Hyper-V 10.0.22000.1에서 발견됨

답변4

이 Powershell 스크립트는 다음을 기반으로 합니다.루크 슐레더님의 답변(https://superuser.com/a/1485949/280673) 이 질문에.

가장 중요한 차이점은 전체 호스트 파일을 VM IP 주소로 덮어쓰지 않고 대신 새 VM이 있는 경우 새 항목을 추가하고 기존 항목의 주소를 덮어쓴다는 것입니다. 이렇게 하면 백업을 만들 필요가 없어지고 로컬 개발이나 다른 목적으로 만든 호스트 파일의 다른 항목이 보존됩니다.

#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."
}

노트

VM에 따라 VM 내부에 추가 패키지를 설치해야 할 수도 있습니다.hyperv아치에서 HyperV 및 powershell에서 VM에 할당되는 IP를 알아내기 전에. 이는 운영 체제마다 다를 수 있으므로 호스트 측에서 주소를 확인할 수 없는 경우 시스템에 대한 가이드를 찾아보거나 새 질문을 게시해야 할 수 있습니다.

스크립트를 더 쉽게 실험하고 반복할 수 있도록 백업 섹션을 남겨두고 주석 처리했습니다. 또한 원하는 경우 보다 합리적인 장소에 백업을 쉽게 만들 수 있습니다(변경 사항이 없으면 백업할 필요가 없으므로 변경 사항이 기록되기 직전까지 백업하지 마세요).

또한 주소를 대체하는 정규식이 여기 외부가 아닌 코드에서 작동하는 방식에 대한 설명을 게시물 본문에 넣었습니다. 이는 복사하여 붙여넣은 후 이 게시물에 대한 참조가 손실된 경우 코드를 더 쉽게 따라갈 수 있도록 하기 위한 것이며, 누군가 코드를 변경하려는 경우 도움이 되기를 바랍니다.

관련 정보