Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
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
- System Windows 10 lub nowszy
- Windows Server 2016 lub nowszy
Obsługiwany system operacyjny gościa
- System Windows 10 lub nowszy
- Windows Server 2016 lub nowszy
- Goście systemu Linux z usługami Integracji z systemem Linux. Zobacz Obsługiwane maszyny wirtualne z systemami Linux i FreeBSD, aby uzyskać Hyper-V w systemie 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, wyewidencjonuj program Visual Studio Community
- Zestaw Windows SDK — wstępnie zainstalowany w programie Visual Studio 2015 z aktualizacją Update 3 lub nowszą.
- Komputer z systemem operacyjnym hosta określonym z co najmniej jedną maszyną vitual. — 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 program PowerShell zarejestruje nową aplikację o nazwie "Pokaz gniazda HV". 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. Są to nasze usługi w pudełku.
Informacje w rejestrze na usługę:
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. Aby połączyć tę niespójność z systemem Windows, znany identyfikator GUID jest używany jako szablon usługi na hoście, który przekłada się na port w gościu. Aby dostosować identyfikator GUID usługi, wystarczy zmienić pierwszy numer portu "000000000". Np. "00000ac9" to port 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
*/
Napiwek: Aby wygenerować identyfikator GUID w programie PowerShell i skopiować go do schowka, uruchom polecenie:
(New-Guid).Guid | clip.exe
Tworzenie gniazda 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);
Wiązanie z gniazdem 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óra składa się z adresu IP maszyny hosta i numeru portu na tym hoście, adres gniazda na AF_HYPERV potrzeby użycia identyfikatora maszyny wirtualnej i identyfikatora aplikacji zdefiniowanej 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 adresu innego niż IP, a nie nazwy hosta, format, który nadal jednoznacznie opisuje połączenie.
Oto definicja adresu gniazda Hyper-V gniazda:
// 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 AF_HYPERV punkty końcowe bazują w dużym stopniu 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).IdIdentyfikator 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 jest określoną maszyną wirtualną.
Symbole wieloznaczne VMID
| Name | GUID | Description |
|---|---|---|
| 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 wieloznaczny dla elementów podrzędnych. Odbiorniki powinny wiązać się z tym identyfikatorem VmId, aby akceptowały połączenie ze swoich elementów podrzędnych. |
| HV_GUID_LOOPBACK | e0e16197-dd56-4a10-9195-5ee7a15a838 | Adres sprzężenia zwrotnego. Za pomocą tego identyfikatora vmId łączy się z tą samą partycją co łącznik. |
| HV_GUID_PARENT | a42e7cda-d03f-480c-9cc2-a4de20abb878 | Adres nadrzędny. Za pomocą tego identyfikatora vmId łączy się z partycją nadrzędną łącznika.* |
*
HV_GUID_PARENT Element nadrzędny maszyny wirtualnej jest jego hostem. 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 vmId akceptuje połączenie 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
| Name | Typ | Description |
|---|---|---|
| HVSOCKET_CONNECTED_SUSPEND | ULONG | Gdy ta opcja gniazda jest ustawiona na gniazda wartości inne niż zero, nie rozłączają się po wstrzymaniu maszyny wirtualnej. |