Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Począwszy od rocznicowej aktualizacji systemu Windows 10 każdy może tworzyć aplikacje komunikujące się między hostem Hyper-V a maszynami wirtualnymi przy użyciu gniazd Hyper-V — gniazda systemu Windows z nową rodziną adresów i wyspecjalizowanym punktem końcowym przeznaczonym dla maszyn wirtualnych. Cała komunikacja przez gniazda Hyper-V działa bez korzystania z sieci, a wszystkie dane pozostają w tej samej pamięci fizycznej. Aplikacje korzystające z gniazd Hyper-V są podobne do usług integracji funkcji Hyper-V.
W tym dokumencie opisano tworzenie prostego programu opartego na gniazdach Hyper-V.
Obsługiwany system operacyjny hosta
- Windows 10 lub nowszy
- Windows Server 2016 i nowsze
Obsługiwany system operacyjny gościa
- Windows 10 lub nowszy
- Windows Server 2016 i nowsze
- Goście systemu Linux z usługami Integracji z systemem Linux. Zobacz Obsługiwane maszyny wirtualne z systemami Linux i FreeBSD dla Hyper-V na Windows
Uwaga / Notatka
Obsługiwany gość systemu Linux musi mieć obsługę jądra dla:
CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y
Możliwości i ograniczenia
- Obsługuje akcje trybu jądra lub trybu użytkownika
- Tylko strumień danych
- Brak pamięci blokowej (nie jest to najlepsze rozwiązanie do tworzenia kopii zapasowej/wideo)
Wprowadzenie
Wymagania:
- Kompilator C/C++. Jeśli go nie masz, sprawdź Visual Studio Community
- Zestaw Windows SDK — wstępnie zainstalowany w programie Visual Studio 2015 z aktualizacją Update 3 lub nowszą.
- Komputer z jednym z określonych systemów operacyjnych hosta z co najmniej jedną maszyną wirtualną. — jest to przeznaczone do testowania aplikacji.
Nuta: Interfejs API dla gniazd Hyper-V stał się publicznie dostępny w rocznicowej aktualizacji systemu Windows 10. Aplikacje korzystające z protokołu HVSocket będą działać na dowolnym hoście i gościu systemu Windows 10, ale mogą być opracowywane tylko przy użyciu zestawu Windows SDK później niż kompilacja 14290.
Rejestrowanie nowej aplikacji
Aby można było używać gniazd Hyper-V, aplikacja musi być zarejestrowana w rejestrze hosta Hyper-V.
Rejestrując usługę w rejestrze, uzyskujesz następujące informacje:
- Zarządzanie usługami WMI na potrzeby włączania, wyłączania i wyświetlania dostępnych usług
- Uprawnienie do bezpośredniej komunikacji z maszynami wirtualnymi
Poniższy skrypt PowerShell zarejestruje nową aplikację pod nazwą "HV Socket Demo". Musi to być uruchomione jako administrator. Instrukcje ręczne poniżej.
$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
Lokalizacja rejestru i informacje:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\
W tej lokalizacji rejestru zobaczysz kilka identyfikatorów GUID (Global Unique Identifier). Są to nasze usługi w pakiecie.
Informacje w rejestrze dla każdej usługi:
Service GUID
-
ElementName (REG_SZ)
— jest to przyjazna nazwa usługi
-
Aby zarejestrować własną usługę, utwórz nowy klucz rejestru przy użyciu własnego identyfikatora GUID i przyjaznej nazwy.
Przyjazna nazwa zostanie skojarzona z nową aplikacją. Pojawi się on w licznikach wydajności i innych miejscach, w których identyfikator GUID nie jest odpowiedni.
Wpis rejestru wygląda następująco:
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
Uwaga / Notatka
Identyfikator GUID usługi dla gościa systemu Linux używa protokołu VSOCK, który adresuje się za pośrednictwem elementu svm_cid
i svm_port
zamiast identyfikatorów GUID. W celu pokonania tej niespójności z systemem Windows, znany identyfikator GUID jest używany jako szablon usługi na hoście, co przekłada się na port w maszynie wirtualnej. Aby dostosować identyfikator GUID usługi, wystarczy zamienić pierwszą część "00000000" na żądany numer portu. Przykładowo, "00000ac9" jest portem 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
*/
Porada: Aby wygenerować identyfikator GUID w PowerShell i skopiować go do schowka, uruchom:
(New-Guid).Guid | clip.exe
Utwórz gniazdo Hyper-V
W najbardziej podstawowym przypadku definiowanie gniazda wymaga rodziny adresów, typu połączenia i protokołu.
Oto prosta definicja gniazda
// Windows
SOCKET WSAAPI socket(
_In_ int af,
_In_ int type,
_In_ int protocol
);
// Linux guest
int socket(int domain, int type, int protocol);
W przypadku gniazda Hyper-V:
- Rodzina adresów —
AF_HYPERV
(Windows) lubAF_VSOCK
(gość systemu Linux) - typ -
SOCK_STREAM
- protocol —
HV_PROTOCOL_RAW
(Windows) lub0
(gość systemu Linux)
Oto przykładowa deklaracja/wystąpienie:
// Windows
SOCKET sock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);
// Linux guest
int sock = socket(AF_VSOCK, SOCK_STREAM, 0);
Powiązanie do gniazda Hyper-V
Powiązanie kojarzy gniazdo z informacjami o połączeniu.
Definicja funkcji jest kopiowana poniżej w celu uzyskania zbieżności, przeczytaj więcej na temat powiązania tutaj.
// 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);
W przeciwieństwie do adresu gniazda (sockaddr) dla standardowej rodziny adresów internetowych (AF_INET
), który składa się z adresu IP maszyny hosta i numeru portu na tym hoście, adres gniazda dla AF_HYPERV
używa identyfikatora maszyny wirtualnej oraz identyfikatora aplikacji zdefiniowanych powyżej w celu nawiązania połączenia. Jeśli powiązanie z gościa AF_VSOCK
systemu Linux używa elementu svm_cid
i svm_port
.
Ponieważ gniazda Hyper-V nie zależą od stosu sieciowego, protokołu TCP/IP, serwera DNS itp., punkt końcowy gniazda potrzebuje formatu, który nie jest ani adresem IP, ani nazwą hosta, ale wciąż jednoznacznie opisuje połączenie.
Oto definicja adresu gniazda 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)];
};
Zamiast adresu IP lub nazwy hosta punkty końcowe AF_HYPERV w dużym stopniu polegają na dwóch identyfikatorach GUID.
Identyfikator maszyny wirtualnej — jest to unikatowy identyfikator przypisany na maszynę wirtualną. Identyfikator maszyny wirtualnej można znaleźć przy użyciu następującego fragmentu kodu programu PowerShell.
(Get-VM -Name $VMName).Id
Identyfikator usługi — identyfikator GUID opisany powyżej, z którym aplikacja jest zarejestrowana w rejestrze hostów Hyper-V.
Istnieje również zestaw symboli wieloznacznych VMID dostępnych, gdy połączenie nie dotyczy określonej maszyny wirtualnej.
Symbole wieloznaczne VMID
Nazwa | GUID (Globalny Unikalny Identyfikator) | Opis |
---|---|---|
HV_GUID_ZERO | 00000000-0000-0000-0000-000000000000 | Odbiorniki powinny być powiązane z tym identyfikatorem VmId, aby akceptowały połączenie ze wszystkich partycji. |
HV_GUID_WILDCARD | 00000000-0000-0000-0000-000000000000 | Odbiorniki powinny być powiązane z tym identyfikatorem VmId, aby akceptowały połączenie ze wszystkich partycji. |
HV_GUID_BROADCAST | FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF | |
HV_GUID_CHILDREN | 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd | Adres ogólny dla dzieci. Słuchacze powinni wiązać się z tym identyfikatorem VmId, aby akceptować połączenia od jego elementów podrzędnych. |
HV_GUID_LOOPBACK | e0e16197-dd56-4a10-9195-5ee7a15a838 | Adres pętli zwrotnej. Za pomocą tego VmId nawiązuje się połączenie z tą samą partycją co łącznik. |
HV_GUID_PARENT | a42e7cda-d03f-480c-9cc2-a4de20abb878 | Adres rodzica. Użycie tego VmId łączy z partycją nadrzędną łącznika.* |
*
HV_GUID_PARENT
Rodzic maszyny wirtualnej to jej host. Elementem nadrzędnym kontenera jest host kontenera.
Nawiązywanie połączenia z kontenera uruchomionego na maszynie wirtualnej spowoduje nawiązanie połączenia z maszyną wirtualną hostująca kontener.
Nasłuchiwanie na tym identyfikatorze VM akceptuje połączenia z: (wewnątrz kontenerów): Host kontenera.
(Wewnątrz maszyny wirtualnej: host kontenera/ brak kontenera): host maszyny wirtualnej.
(Nie wewnątrz maszyny wirtualnej: host kontenera/ brak kontenera): nieobsługiwane.
Obsługiwane polecenia gniazda
Socket() Bind() Connect() Send() Listen() Accept()
Opcje gniazda HvSocket
Nazwa | Typ | Opis |
---|---|---|
HVSOCKET_CONNECTED_SUSPEND | ULONG | Gdy ta opcja gniazda jest ustawiona na wartość inną niż zero, gniazda nie rozłączają się po wstrzymaniu maszyny wirtualnej. |