사용자 고유의 통합 서비스 만들기
Windows 10 1주년 업데이트부터는 누구나 Hyper-V 소켓을 사용하여 Hyper-V 호스트와 가상 머신 간에 통신하는 애플리케이션(새 주소 패밀리가 있는 Windows 소켓 및 가상 머신을 대상으로 하는 특수 엔드포인트)을 만들 수 있습니다. Hyper-V 소켓을 통한 모든 통신은 네트워킹을 사용하지 않고 실행되며 모든 데이터는 동일한 실제 메모리에 유지됩니다. Hyper-V 소켓을 사용하는 애플리케이션은 Hyper-V의 통합 서비스와 유사합니다.
이 문서에서는 Hyper-V 소켓을 기반으로 하는 간단한 프로그램을 만드는 방법에 대해 설명합니다.
지원되는 호스트 OS
- Windows 10 이상
- Windows Server 2016 이상
지원되는 게스트 OS
- Windows 10 이상
- Windows Server 2016 이상
- Linux Integration Services를 사용하는 Linux 게스트. Windows에서 Hyper-V에 대해 지원되는 Linux 및 FreeBSD 가상 머신을 참조하세요 .
참고 항목
지원되는 Linux 게스트는 다음에 대해 커널을 지원해야 합니다.
CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y
기능 및 제한 사항
- 커널 모드 또는 사용자 모드 작업을 지원합니다.
- 데이터 스트림만
- 블록 메모리 없음(백업/비디오에 최적이 아님)
시작
요구 사항:
- C/C++ 컴파일러. 없는 경우 Visual Studio 커뮤니티를 체크 아웃 합니다.
- Windows SDK - 업데이트 3 이상과 함께 Visual Studio 2015에 미리 설치됩니다.
- 하나 이상의 가상 머신으로 지정된 호스트 운영 체제 중 하나를 실행하는 컴퓨터입니다. -- 애플리케이션을 테스트하기 위한 것입니다.
참고: Hyper-V 소켓용 API는 Windows 10 1주년 업데이트에서 공개되었습니다. HVSocket을 사용하는 애플리케이션은 Windows 10 호스트와 게스트에서 실행되지만 빌드 14290 이후의 Windows SDK로만 개발할 수 있습니다.
새 애플리케이션 등록
Hyper-V 소켓을 사용하려면 애플리케이션을 Hyper-V 호스트의 레지스트리에 등록해야 합니다.
레지스트리에 서비스를 등록하면 다음을 얻을 수 있습니다.
- 사용 가능한 서비스를 사용, 사용 안 함 및 나열하기 위한 WMI 관리
- 가상 머신과 직접 통신할 수 있는 권한
다음 PowerShell은 "HV 소켓 데모"라는 새 애플리케이션을 등록합니다. 관리자 권한으로 실행해야 합니다. 아래의 수동 지침입니다.
$friendlyName = "HV Socket Demo"
# Create a new random GUID. Add it to the services list
$service = New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices" -Name ((New-Guid).Guid)
# Set a friendly name
$service.SetValue("ElementName", $friendlyName)
# Copy GUID to clipboard for later use
$service.PSChildName | clip.exe
레지스트리 위치 및 정보:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\
이 레지스트리 위치에는 여러 GUID가 표시됩니다. 이러한 서비스는 기본 제공 서비스입니다.
서비스당 레지스트리의 정보:
Service GUID
ElementName (REG_SZ)
-- 서비스의 친숙한 이름입니다.
사용자 고유의 서비스를 등록하려면 고유한 GUID 및 친숙한 이름을 사용하여 새 레지스트리 키를 만듭니다.
친숙한 이름이 새 애플리케이션과 연결됩니다. 성능 카운터 및 GUID가 적절하지 않은 다른 위치에 표시됩니다.
레지스트리 항목은 다음과 같습니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\
999E53D4-3D5C-4C3E-8779-BED06EC056E1\
ElementName REG_SZ VM Session Service
YourGUID\
ElementName REG_SZ Your Service Friendly Name
참고 항목
Linux 게스트용 서비스 GUID는 GUID가 아니라 svm_cid
및 svm_port
를 통해 주소 지정이 되는 VSOCK 프로토콜을 사용합니다. Windows에서 이러한 비일관성을 해결하기 위해 잘 알려진 GUID가 호스트의 서비스 플랫폼으로 사용되고, 이후에 게스트에서 포트로 변환됩니다. 서비스 GUID를 사용자 지정하려면 첫 번째 "00000000"을 원하는 포트 번호로 변경하면 됩니다. 예를 들어 "00000ac9"는 2761 포트입니다.
// Hyper-V Socket Linux guest VSOCK template GUID
struct __declspec(uuid("00000000-facb-11e6-bd58-64006a7986d3")) VSockTemplate{};
/*
* GUID example = __uuidof(VSockTemplate);
* example.Data1 = 2761; // 0x00000AC9
*/
팁: PowerShell에서 GUID를 생성하고 클립보드에 복사하려면 다음을 실행합니다.
(New-Guid).Guid | clip.exe
Hyper-V 소켓 만들기
가장 기본적인 경우 소켓을 정의하려면 주소 패밀리, 연결 유형 및 프로토콜이 필요합니다.
다음은 간단한 소켓 정의입니다.
// Windows
SOCKET WSAAPI socket(
_In_ int af,
_In_ int type,
_In_ int protocol
);
// Linux guest
int socket(int domain, int type, int protocol);
Hyper-V 소켓의 경우:
- 주소 패밀리 -
AF_HYPERV
(Windows) 또는AF_VSOCK
(Linux 게스트) - 형-
SOCK_STREAM
- 프로토콜 -
HV_PROTOCOL_RAW
(Windows) 또는0
(Linux 게스트)
다음은 선언/인스턴스화 예제입니다.
// Windows
SOCKET sock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);
// Linux guest
int sock = socket(AF_VSOCK, SOCK_STREAM, 0);
Hyper-V 소켓에 바인딩
바인딩은 소켓을 연결 정보와 연결합니다.
함수 정의는 아래와 같이 복사되어 있습니다. 여기에서 바인딩에 대해 자세히 알아보세요.
// Windows
int bind(
_In_ SOCKET s,
_In_ const struct sockaddr *name,
_In_ int namelen
);
// Linux guest
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
호스트 컴퓨터의 IP 주소와 해당 호스트의 포트 번호로 구성된 표준 인터넷 프로토콜 주소 패밀리()의 소켓 주소(AF_INET
sockaddr)와는 달리, 소켓 주소 AF_HYPERV
는 가상 머신의 ID와 위에서 정의한 애플리케이션 ID를 사용하여 연결을 설정합니다. Linux 게스트 AF_VSOCK
의 바인딩에서 svm_cid
및 svm_port
를 사용하는 경우.
Hyper-V 소켓은 네트워킹 스택, TCP/IP, DNS 등에 종속되지 않으므로 소켓 엔드포인트에는 연결을 명확하게 설명하는 호스트 이름이 아닌 IP가 아닌 형식이 필요했습니다.
Hyper-V 소켓의 소켓 주소에 대한 정의는 다음과 같습니다.
// Windows
struct SOCKADDR_HV
{
ADDRESS_FAMILY Family;
USHORT Reserved;
GUID VmId;
GUID ServiceId;
};
// Linux guest
// See include/uapi/linux/vm_sockets.h for more information.
struct sockaddr_vm {
__kernel_sa_family_t svm_family;
unsigned short svm_reserved1;
unsigned int svm_port;
unsigned int svm_cid;
unsigned char svm_zero[sizeof(struct sockaddr) -
sizeof(sa_family_t) -
sizeof(unsigned short) -
sizeof(unsigned int) - sizeof(unsigned int)];
};
IP 또는 호스트 이름 대신 AF_HYPERV 엔드포인트는 두 GUID에 크게 의존합니다.
VM ID – VM당 할당된 고유 ID입니다. 다음 PowerShell 코드 조각을 사용하여 VM의 ID를 찾을 수 있습니다.
(Get-VM -Name $VMName).Id
서비스 ID – 위에서 설명한 GUID로, Hyper-V 호스트 레지스트리에 애플리케이션이 등록됩니다.
특정 가상 머신에 연결하지 않을 때 사용할 수 있는 VMID 와일드카드 집합도 있습니다.
VMID 와일드카드
속성 | GUID | 설명 |
---|---|---|
HV_GUID_ZERO | 00000000-0000-0000-0000-000000000000 | 수신기는 이 VmId에 바인딩하여 모든 파티션의 연결을 허용해야 합니다. |
HV_GUID_WILDCARD | 00000000-0000-0000-0000-000000000000 | 수신기는 이 VmId에 바인딩하여 모든 파티션의 연결을 허용해야 합니다. |
HV_GUID_BROADCAST | FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFF | |
HV_GUID_CHILDREN | 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd | 자식에 대한 와일드카드 주소입니다. 수신기는 자식으로부터의 연결을 허용하려면 이 VmId에 바인딩해야 합니다. |
HV_GUID_LOOPBACK | e0e16197-dd56-4a10-9195-5ee7a155a838 | 루프백 주소입니다. 이 VmId를 사용하면 커넥터와 동일한 파티션에 연결됩니다. |
HV_GUID_PARENT | a42e7cda-d03f-480c-9cc2-a4de20abb878 | 부모 주소입니다. 이 VmId를 사용하면 커넥터의 부모 파티션에 연결됩니다.* |
* HV_GUID_PARENT
가상 머신의 부모는 해당 호스트입니다. 컨테이너의 부모는 컨테이너의 호스트입니다.
가상 머신에서 실행되는 컨테이너에서 연결하면 컨테이너를 호스팅하는 VM에 연결됩니다.
이 VmId에서 수신 대기하면 다음(컨테이너 내부): 컨테이너 호스트에서 연결을 허용합니다.
(VM 내부: 컨테이너 호스트/컨테이너 없음): VM 호스트.
(VM 내부에 없음: 컨테이너 호스트/컨테이너 없음): 지원되지 않습니다.
지원되는 소켓 명령
Socket() Bind() Connect() Send() Listen() Accept()
HvSocket 소켓 옵션
속성 | 형식 | 설명 |
---|---|---|
HVSOCKET_CONNECTED_SUSPEND | ULONG | 이 소켓 옵션이 0이 아닌 값 소켓으로 설정된 경우 가상 머신이 일시 중지될 때 연결이 끊어지지 않습니다. |