Wiązanie portu kontenera Windows w systemie Windows Server 2016 nie działa

5

Korzystam z kontenera Windows na hoście Windows (Windows Server 2016 TP4) .

Kontener powinien uruchamiać serwer internetowy IIS na porcie 80 wewnętrznie, a także chcę powiązać port 80 z hostem , aby móc do niego dotrzeć za pośrednictwem adresu IP / URL hosta.

Postępowałem zgodnie z instrukcjami Microsoft

Próbowałem obu metod przez Powershell i Docker, aw obu przypadkach powiązanie portu z hostem nie działa.

========================= Podejście Powershell ======================= ===

Wdrażanie hosta kontenera w istniejącym systemie (Windows Server 2016 TP4)

PS C:> wget -uri https://aka.ms/tp4/Install-ContainerHost -OutFile C:\Install-ContainerHost.ps1

PS C:> powershell.exe -NoProfile C:\Install-ContainerHost.ps1

Querying status of Windows feature: Containers...
Feature Containers is already enabled.
Waiting for Hyper-V Management...
Networking is already configured.  Confirming configuration...
Getting Container OS image (NanoServer) version 10.0.10586.0 from OneGet (this may take a few minutes)...
Container base image install complete.  Querying container images...
OS image (NanoServer) is already installed.
The following images are present on this machine:
    ContainerImage (Name = 'NanoServer') [Publisher = 'CN=Microsoft', Version = '10.0.10586.0']
    ContainerImage (Name = 'WindowsServerCore') [Publisher = 'CN=Microsoft', Version = '10.0.10586.0']

Docker is already installed.
Stopping Docker...
Starting Docker...
Tagging new base image (8572198a60f1)...
Base image is now tagged:
nanoserver          10.0.10586.0        8572198a60f1        5 months ago        0 B
nanoserver          latest              8572198a60f1        5 months ago        0 B
Script complete!

Przygotowywanie obrazu i kontenera z uruchomionymi usługami IIS (na podstawie obrazu WindowsServerCore)

Są to dokładne kroki opisane w dokumentacji Microsoft pod adresem https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/manage_powershell . Tworzę kontener z WindowsServerCore, instaluję na nim IIS i tworzę z niego nowy obraz, który mogę później wykorzystać ponownie.

PS C:> Get-ContainerImage

Name              Publisher    Version      IsOSImage
----              ---------    -------      ---------
NanoServer        CN=Microsoft 10.0.10586.0 True
WindowsServerCore CN=Microsoft 10.0.10586.0 True


PS C:\> New-Container -Name TP4Demo -ContainerImageName WindowsServerCore -SwitchName "Virtual Switch"

Name    State Uptime   ParentImageName
----    ----- ------   ---------------
TP4Demo Off   00:00:00 WindowsServerCore


PS C:\> Get-Container

Name    State Uptime   ParentImageName
----    ----- ------   ---------------
TP4Demo Off   00:00:00 WindowsServerCore


PS C:\> Start-Container -Name TP4Demo

PS C:\> Enter-PSSession -ContainerName TP4Demo -RunAsAdministrator
[TP4Demo]: PS C:\Windows\system32> Install-WindowsFeature web-server

Success Restart Needed Exit Code      Feature Result
------- -------------- ---------      --------------
True    No             Success        {Common HTTP Features, Default Document, D...


[TP4Demo]: PS C:\Windows\system32> exit
PS C:\> Stop-Container -Name TP4Demo

PS C:\> New-ContainerImage -ContainerName TP4Demo -Name WindowsServerCoreIIS -Publisher Demo -Version 1.0

Name                 Publisher Version IsOSImage
----                 --------- ------- ---------
WindowsServerCoreIIS CN=Demo   1.0.0.0 False


PS C:\> Remove-Container -Name TP4Demo -Force

Teraz mam gotowy kontener IIS, który łączę z „przełącznikiem wirtualnym”.

PS C:\> New-Container -Name IIS -ContainerImageName WindowsServerCoreIIS -SwitchName "Virtual Switch"

Name State Uptime   ParentImageName
---- ----- ------   ---------------
IIS  Off   00:00:00 WindowsServerCoreIIS


PS C:\> Start-Container -Name IIS

PS C:\> Invoke-Command -ContainerName IIS {ipconfig}

Windows IP Configuration

Ethernet adapter vEthernet (Virtual Switch-30179F35-A9BD-4231-B264-BDD2994BD956-0):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::24f4:c726:ed9b:e603%28
   IPv4 Address. . . . . . . . . . . : 172.16.0.2
   Subnet Mask . . . . . . . . . . . : 255.240.0.0
   Default Gateway . . . . . . . . . : 172.16.0.1

Dodanie reguły mapowania portów i zapory:

PS C:\> if (!(Get-NetNatStaticMapping | where {$_.ExternalPort -eq 80})) {Add-NetNatStaticMapping -NatName "ContainerNat" -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 172.16.0.2 -InternalPort 80 -ExternalPort 80}

PS C:\> if (!(Get-NetFirewallRule | where {$_.Name -eq "TCP80"})) {New-NetFirewallRule -Name "TCP80" -DisplayName "HTTP on TCP/80" -Protocol tcp -LocalPort 80 -Action Allow -Enabled True}

Teraz, gdy dodałem mapowanie portów (i regułę zapory ogniowej), powinienem być w stanie uzyskać dostęp do IIS przez mojego hosta. (Dla pewności całkowicie wyłączyłem zaporę na hoście).

Ale powiązanie portu hosta nie działa. Nie mogę dotrzeć do IIS przez adresy IP hosta i związany port przez http: // localhost: 80 / ani http://172.16.0.1:80/, ani http://10.10.0.79:80/

PS C:\> wget http://10.10.0.79:80/
wget : Unable to connect to the remote server
At line:1 char:1
+ wget http://10.10.0.79:80/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

PS C:\> wget http://172.16.0.1:80/
wget : Unable to connect to the remote server
At line:1 char:1
+ wget http://172.16.0.1:80/
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Mogę dotrzeć do domyślnej strony IIS tylko przez adres IP kontenera ( http://172.16.0.2:80 ).

========================= Podejście do dokera ======================= ===

Oto moje podejście do zarządzania kontenerem za pomocą Dockera :

C:\> docker run --name iisbase -it windowsservercore cmd
C:\> powershell.exe Install-WindowsFeature web-server
C:\> exit
PS C:\Windows\system32> docker commit iisbase windowsservercoreiis
64271b60a1c4af29ce37ebcee45b00d824883eb67c717d4cee765d9f696867bb
C:\> powershell.exe "if(!(Get-NetFirewallRule | where {$_.Name -eq 'TCP80'})) { New-NetFirewallRule -Name 'TCP80' -DisplayName 'HTTP on TCP/80' -Protocol tcp -LocalPort 80 -Action Allow -Enabled True }"
C:\> docker run --name iisdemo -it -p 80:80 windowsservercoreiis cmd

Na koniec mogę uzyskać dostęp do IIS tylko przez adres IP kontenera, a nie przez adres IP hosta.

Korzystam z Docker w wersji 1.10.0-dev, kompilacja 18c9fe0.

Mathias Conradt
źródło
Bilety utworzone na Docker github.com/docker/docker/issues/21558 oraz dokumentacja Microsoft Virtualization: github.com/Microsoft/Virtualization-Documentation/issues/181
Mathias

Odpowiedzi:

1

Wygląda na problem z Windows Server TP4.

Stefan Scherer z zespołu Docker odpowiedział na mój zgłoszony problem: https://github.com/docker/docker/issues/21558#issuecomment-202536462

Mogę odtworzyć problemy @mathiasconradt. Grałem z aplikacją do głosowania w zeszłym tygodniu z TP4, mam takie samo obejście: otwieranie portów zapory na hoście, otwieranie adresu URL serwera WWW z adresami IP kontenera. Nie mogę się doczekać, aby przetestować aplikację do głosowania na TP5.

Oczekiwanie na TP5 ... tymczasem używam Apache httpd na hoście do obsługi przekierowania portów.

Mathias Conradt
źródło
TP5 powinno być dostępne za około 7 godzin, prawda?
Falco Alexander
@FalcoAlexander Nie wiem, skąd masz te informacje? Zainteresowany także datą wydania. Poszukałem go, zobaczyłem twitter.com/wzornet/status/701532616839847937, który jest już przekazany.
Mathias Conradt
1
Konferencja Build 2016 (w SF) rozpocznie się za 7 godzin. zwykle jest to wydarzenie mające na celu rozpowszechnianie nowych wydań. Chyba: VisualStudio i TFS 2015 Update 2, nowy Windows 10 Release 1603 i Server 2016 TP5.
Falco Alexander,
moje złe ... błędne spekulacje ...: /
Falco Alexander
0

Uwaga: w końcu stwierdzono, że jest to błąd w systemie Windows Server 2016 TP4, który powoduje zachowanie opisane poniżej (patrz komentarze). Mimo że podobno zainstalowano demona dokującego, wydaje się, że klient jest używany ze wszystkimi ograniczeniami opisanymi poniżej. Ten błąd można naprawić w przyszłym TP5.


Jest to ograniczenie implementacji Dockera w systemie Windows, gdzie nie można połączyć się z kontenerem za pośrednictwem hosta.

To jest odpowiedź na to samo pytanie dotyczące raportu o błędzie # 15740: ekspozycja portu w systemie Windows =? :

Powodem tego jest to, że w systemie Linux demon dokera (i twoje kontenery) działa na samym komputerze z systemem Linux, więc „localhost” jest również hostem, na którym działa kontener, a porty są mapowane.

W systemie Windows (i OS X) demon dokera i kontenery nie mogą działać natywnie, więc tylko klient dokera działa na komputerze z systemem Windows, ale demon (i kontenery) działają na maszynie wirtualnej VirtualBox, na której działa system Linux.

Aby połączyć się z kontenerem, musisz połączyć się z adresem IP maszyny wirtualnej, a nie komputera z systemem Windows.

Wszystko to opisano w dokumentacji instalacyjnej systemu Windows, która znajduje się tutaj; http://docs.docker.com/installation/windows/ .

Maszyna wirtualna jest opisana w tej sekcji;
http://docs.docker.com/installation/windows/#learn-the-key-concepts-before-installing

Wyjaśniono tutaj, w jaki sposób mapować porty i łączyć się z nimi;
http://docs.docker.com/installation/windows/#container-port-redirection

Zamierzam zamknąć ten problem, ponieważ nie jest to błąd i wyjaśniono go w dokumentacji. Mam nadzieję, że powyższe wyjaśnienie ci pomoże.

harrymc
źródło
1
Dzięki za łącze, ale połączony bilet github odnosi się do systemu Windows 7 (lub dowolnego systemu Windows Server wcześniejszego niż Windows 2016), a odpowiedź biletu mówi: „W systemie Windows (i OS X) demon dokera i kontenery nie mogą działać natywnie , więc tylko klient dokera działa na komputerze z systemem Windows, ale demon (i kontenery) działają na maszynie wirtualnej VirtualBox, na której jest uruchomiony system Linux. "; dotyczy to Windows7, ale nie powinno tak być w przypadku Windows 2016, w którym kontenery mogą działać natywnie.
Mathias Conradt
1
Zwróć również uwagę na komentarz ThaJeztaha na stronie github, do której linkujesz: „Trwają prace nad uruchomieniem Docker Engine natywnie w Windows Server 2016, ale ten silnik będzie uruchamiał tylko aplikacje Windows, a nie Linux” <- właśnie to próbuję robić i używać.
Mathias Conradt
Ale pytasz o Docker, który nie został opracowany przez Microsoft. Aby zapewnić bezproblemową integrację z Windows, powinieneś używać technologii Windows, która jest kontenerami Windows i kontenerami Hyper-V, a nie Dockerem.
harrymc
Wiem, że Docker nie jest rozwijany przez MS, używam go bez problemu do kontenerów Linux. Zgodnie z dokumentacją Microsoft Docker powinien działać na Win2016 w taki sam sposób jak kontenery Windows. Wyraźnie unikam funkcji Hyper-V, aby nie mieć między nimi maszyny wirtualnej. Spróbuję podejść do Windows Containers, ale wolałbym używać Dockera, ponieważ jest to również to, czego używam poza światem Windows.
Mathias Conradt
Różnice z pewnością znikną w przyszłości. Obecną sytuację można znaleźć na przykład w tym artykule: Docker Engine for Windows Server 2016 . Domyślam się, że Microsoft powinien dążyć do całkowitej integracji z Dockerem, może nawet w wydanej wersji WS2016.
harrymc