호스트 외부 (동일 네트워크)에서 도커 컨테이너에 연결하는 방법 [Windows]
첫 번째 도커 컨테이너를 만들었는데 Go를 사용하여 서버를 실행하고 있지만 호스트 컴퓨터 외부에서 액세스 할 수 없습니다. 방금 도커로 시작 했으므로 여기서 조금 길을 잃었습니다.
그래서 서버를 시작하는 매우 간단한 Go 코드가 있고 Go를 설치하고 Linux 기본 이미지에서 코드를 빌드하는 도커 이미지를 빌드했습니다. 포트 8080에서 서버를 실행 중이므로 다음과 같이 컨테이너를 실행하는 호스트에 해당 포트를 노출합니다.
docker run -p 8080:8080 dockertest
작동하고 도커의 컴퓨터 IP ( 시작될 때 Docker 빠른 시작 터미널 에 표시되는 IP)를 통해 서버에 액세스 할 수 있습니다 . 문제는 호스트 외부에서 호스팅하는 웹 사이트에 액세스 할 수 없다는 것입니다. 내 휴대 전화에서 동일한 IP 주소를 열면 오류 메시지가 표시됩니다.이 웹 페이지를 사용할 수 없습니다 (ERR_CONNECTION_TIMED_OUT).
또한 다음과 같이 IP를 지정해 보았습니다.
docker run -p 192.168.0.157:8080:8080 dockertest
하지만 그렇게하면 도커 머신의 IP 나 위의 명령 줄에 지정된 IP를 통해 웹 사이트에 액세스 할 수 없습니다. 또한 내 컴퓨터의 IP를 사용한 명령에 어떤 IP를 작성해야하는지 잘 모르겠습니다. 127.0.0.1 (localhost)도 시도했지만 동일한 결과를 얻었습니다. 어떤 IP를 통해 웹 사이트에 액세스 할 수 없습니다. IP는 무엇이든.
나는이 문제를 검색하고 많은 StackOverflow 질문을 찾았지만 내 문제를 해결하는 데 도움이되지 않았습니다. 대부분이 Linux 또는 Mac을 지향했기 때문에 솔루션이 내 상황에 적용되지 않았습니다.
또한 내 컴퓨터에서 Go 코드를 실행하고 내 컴퓨터의 IP를 통해 동일한 네트워크에있는 다른 장치에서 웹 사이트에 액세스 할 수 있습니다. 도커 머신에서 실행할 때 액세스 할 수없는 이유를 이해하지 못합니다. IP 전달과 관련이있을 수 있지만 네트워킹에서는 완전히 멍청한 사람입니다. 대부분 웹 개발자이며 네이티브 경험이 거의 없습니다.
TL; DR VirtualBox 호스트의 네트워크 모드를 확인합니다 bridged
. 로컬 네트워크에서 가상 머신 (및 호스팅하는 Docker 컨테이너)에 액세스 할 수 있는지 확인해야합니다.
HTTP를 통해 애플리케이션에 액세스하기 위해 연결할 호스트에 혼란이있는 것 같습니다. 구성이 무엇인지 실제로 설명하지 않았습니다. 태그에 "Windows"와 "VirtualBox"가 있다는 사실을 기반으로 몇 가지 추측을 할 것입니다.
Windows 호스트의 VirtualBox에서 실행되는 Linux의 일부 버전에서 Docker를 실행하고 있다고 생각합니다. 다음과 같이 IP 주소에 레이블을 지정하겠습니다.
D
= Docker 컨테이너의 IP 주소
L
= VirtualBox에서 실행중인 Linux 호스트의 IP 주소
W
= Windows 호스트의 IP 주소
Windows 호스트에서 Go 애플리케이션을 실행하면 http://W:8080/
로컬 네트워크의 어디에서나 Go 애플리케이션에 연결할 수 있습니다 . 이것은 Go 응용 프로그램이 Windows 시스템의 포트 8080을 바인딩하고 IP 주소에서 포트 8080에 액세스하려는 모든 사람이 연결되기 때문에 작동합니다 W
.
그리고 여기가 더 복잡해집니다.
VirtualBox는 VM (가상 머신)을 설정할 때 여러 다른 모드 중 하나로 네트워크를 구성 할 수 있습니다. 모든 다른 옵션이 무엇인지 기억이 나지 않지만 원하는 옵션은입니다 bridged
. 이 모드에서 VirtualBox는 네트워크에 연결된 다른 컴퓨터와 마찬가지로 네트워크의 독립 실행 형 컴퓨터 인 것처럼 가상 컴퓨터를 로컬 네트워크에 연결합니다. 에서 bridged
모드, 가상 컴퓨터가 다른 컴퓨터와 같은 네트워크에 나타납니다. 다른 모드에서는 설정이 다르게 설정되며 네트워크에서 기기가 표시되지 않습니다.
따라서 Linux 호스트 ( bridged
)에 대해 네트워킹을 올바르게 설정했다고 가정하면 Linux 호스트는 로컬 네트워크에 IP 주소 (예 : 192.168.0.x)를 갖게되며에서 Docker 컨테이너에 액세스 할 수 있습니다 http://L:8080/
.
리눅스 호스트가 아닌 다른 모드로 설정되어있는 경우 bridged
, 당신은 할 수 Windows 호스트에서 액세스 할 수 있지만, 그것은에 정확히 어떤 모드에 의존하는 것입니다.
편집 -아래 설명에 따르면 위에서 설명한 상황이 옳은 것처럼 들립니다.
약간 백업 해 보겠습니다. 여기 내 컴퓨터 (Ubuntu Linux)에서 Docker가 작동하는 방식이 있습니다.
내가 가지고있는 것과 동일한 명령을 실행한다고 상상해보십시오 docker run -p 8080:8080 dockertest
.. 이것이하는 일은 dockertest
이미지를 기반으로 새 컨테이너를 시작 하고 Linux 호스트 (내 PC)의 포트 8080을 컨테이너의 포트 8080으로 전달 (연결)하는 것입니다. Docker는 Docker 데몬이 통신하고 컨테이너가 서로 통신 할 수 있도록 자체 내부 네트워킹 (자체 IP 주소 집합 포함)을 설정합니다. 그래서 기본적으로 당신이하는 일은 -p 8080:8080
Docker의 내부 네트워킹을 "외부"네트워크와 연결 하는 것 입니다. 호스트의 네트워크 어댑터-특정 포트
지금까지 나와? 이제 한 걸음 물러서서 시스템을 살펴 보겠습니다. 컴퓨터가 Windows를 실행 중입니다. Docker는 (현재) Windows에서 실행되지 않으므로 사용중인 도구가 VirtualBox 가상 컴퓨터에 Linux 호스트를 설정했습니다. docker run
환경에서 작업을 수행하면 똑같은 일이 발생합니다. Linux 호스트의 포트 8080이 컨테이너의 포트 8080에 연결됩니다. 여기서 큰 차이점은 Windows 호스트가 컨테이너가 실행되는 Linux 호스트가 아니므로 여기에 다른 계층이 있으며 문제가 발생하는이 계층을 가로 질러 통신한다는 것입니다.
필요한 것은 다음 두 가지 중 하나입니다.
Docker 컨테이너를 호스트 포트에 연결하는 것처럼 VirtualBox VM의 포트 8080을 Windows 호스트의 포트 8080에 연결합니다.
bridged
위에서 설명한 네트워크 모드 를 사용하여 VirtualBox VM을 로컬 네트워크에 직접 연결합니다 .
첫 번째 옵션에 갈 경우에 컨테이너에 액세스 할 수 있습니다 http://W:8080
경우 W
Windows 호스트의 IP 주소 나 호스트 이름입니다. 두 번째를 선택하는 경우에 컨테이너에 액세스 할 수 있습니다 http://L:8080
곳 L
리눅스 VM의 IP 주소 또는 호스트 이름입니다.
이것이 모두 상위 수준의 설명입니다. 이제 VirtualBox VM의 구성을 변경하는 방법을 알아 내야합니다. 그리고 여기에서 제가 정말로 당신을 도울 수없는 부분이 있습니다. Windows 컴퓨터에서이 모든 작업을 수행하는 데 어떤 도구를 사용하는지 모르겠고 Windows에서 Docker를 사용하는 데 전혀 익숙하지 않습니다.
VirtualBox 구성 창에 액세스 할 수 있으면 아래에 설명 된대로 변경할 수 있습니다. VM을 수정하는 명령 줄 클라이언트도 있지만 잘 모르겠습니다.
들어 bridged
모드 (이 정말 간단한 선택), 당신의 VM을 종료 상단에있는 "설정"버튼을 클릭의 네트워크 모드를 변경 bridged
한 후 VM을 다시 시작하고 넌 좋은 이동합니다. VM은 DHCP를 통해 로컬 네트워크에서 IP 주소를 선택해야하며 해당 IP 주소에서 네트워크의 다른 컴퓨터에 표시되어야합니다.
- Oracle VM VirtualBox Manager를 엽니 다.
- Docker에서 사용하는 VM 선택
- 설정-> 네트워크를 클릭하십시오.
- 어댑터 1 (기본값?)은 "Attached to : NAT"여야합니다.
- 고급-> 포트 전달을 클릭하십시오.
- 규칙 추가 : 프로토콜 TCP, 호스트 포트 8080, 게스트 포트 8080 (호스트 IP 및 게스트 IP는 비워 두십시오)
- Guest is your docker container and Host is your machine
You should now be able to browse to your container via localhost:8080 and your-internal-ip:8080.
After trying several things, this worked for me:
- use the --publish=0.0.0.0:8080:8080 docker flag
- set the virtualbox network mode to NAT, and don't use any port forwarding
With addresses other than 0.0.0.0
I had no success.
This is the most common issue faced by Windows users for running Docker Containers. IMO this is the "million dollar question on Docker"; @"Rocco Smit" has rightly pointed out "inbound traffic for it was disabled by default on my host machine's firewall"; in my case, my McAfee Anti Virus software. I added additional ports to be allowed for inbound traffic from other computers on the same Wifi LAN in the Firewall Settings of McAfee; then it was magic. I had struggled for more than a week browsing all over internet, SO, Docker documentations, Tutorials after Tutorials related to the Networking of Docker, and the many illustrations of "not supported on Windows" for "macvlan", "ipvlan", "user defined bridge" and even this same SO thread couple of times. I even started browsing google with "anybody using Docker in Production?", (yes I know Linux is more popular for Prod workloads compared to Windows servers) as I was not able to access (from my mobile in the same Home wifi) an nginx app deployed in Docker Container on Windows. After all, what good it is, if you cannot access the application (deployed on a Docker Container) from other computers / devices in the same LAN at-least; Ultimately in my case, the issue was just with a firewall blocking inbound traffic;
TLDR: If you have Windows Firewall enabled, make sure that there is an exception for "vpnkit" on private networks.
For my particular case, I discovered that Windows Firewall was blocking my connection when I tried visiting my container's published port from another machine on my local network, because disabling it made everything work.
However, I didn't want to disable the firewall entirely just so I could access my container's service. This begged the question of which "app" was listening on behalf of my container's service. After finding another SO thread that taught me to use netstat -a -b
to discover the apps behind the listening sockets on my machine, I learned that it was vpnkit.exe
, which already had an entry in my Windows Firewall settings: but "private networks" was disabled on it, and once I enabled it, I was able to visit my container's service from another machine without having to completely disable the firewall.
I found that along with setting the -p port values, Docker for Windows uses vpnkit and inbound traffic for it was disabled by default on my host machine's firewall. After enabling the inbound TCP rules for vpnkit I was able to access my containers from other machines on the local network.
'Development Tip' 카테고리의 다른 글
모의 및 단위 테스트에 필요할 때 SqlException을 던지는 방법은 무엇입니까? (0) | 2020.10.25 |
---|---|
Node.js : ImageMagick없이 이미지 크기 조정 (0) | 2020.10.25 |
nil / NULL 블록이 실행될 때 버스 오류를 일으키는 이유는 무엇입니까? (0) | 2020.10.25 |
Wikipedia 페이지 ID는 무엇입니까? (0) | 2020.10.25 |
DateTime을 24 시간 형식으로 지정하는 방법은 무엇입니까? (0) | 2020.10.25 |