Cách kết nối với bộ chứa docker từ bên ngoài máy chủ (cùng mạng) [Windows]


87

Tôi đã tạo vùng chứa docker đầu tiên của mình, nó đang chạy một máy chủ bằng Go nhưng tôi không thể truy cập nó từ bên ngoài máy tính chủ. Tôi chỉ mới bắt đầu với docker nên tôi hơi mất hứng ở đây.

Vì vậy, tôi có một mã Go rất đơn giản để khởi động một máy chủ, tôi đã xây dựng hình ảnh docker cài đặt Go và xây dựng mã trong một hình ảnh cơ sở Linux. Tôi đang chạy máy chủ trên cổng 8080 vì vậy tôi để lộ cổng đó cho máy chủ đang chạy vùng chứa như sau:

docker run -p 8080:8080 dockertest

Điều đó hoạt động và tôi có thể truy cập máy chủ thông qua IP máy của docker ( IP xuất hiện trên Docker Quickstart Terminal khi được khởi tạo), vấn đề là tôi không thể truy cập trang web mà tôi đang lưu trữ từ bên ngoài máy chủ, vì vậy nếu tôi thử để mở cùng một địa chỉ IP trên điện thoại của tôi, nó chỉ báo cho tôi một lỗi: Trang web này không khả dụng (ERR_CONNECTION_TIMED_OUT).

Tôi cũng đã thử chỉ định IP như thế này:

docker run -p 192.168.0.157:8080:8080 dockertest

Nhưng khi làm điều đó, tôi không thể truy cập trang web thông qua IP của máy docker cũng như IP được chỉ định trên dòng lệnh ở trên. Tôi cũng không chắc mình phải viết IP nào trong lệnh đó. Tôi đã sử dụng IP máy tính của mình, tôi cũng đã thử 127.0.0.1 (localhost) nhưng điều đó cho tôi kết quả tương tự: không thể truy cập trang web thông qua bất kỳ IP gì.

Tôi đã truy cập vấn đề này và tìm thấy nhiều câu hỏi về StackOverflow nhưng không giúp tôi giải quyết được vấn đề của mình, hầu hết chúng đều hướng đến Linux hoặc Mac nên giải pháp không áp dụng cho trường hợp của tôi.

Ngoài ra, tôi có thể chạy mã Go trên máy tính của mình và truy cập trang web từ một thiết bị khác trong cùng mạng thông qua IP máy tính của tôi. Tôi không hiểu tại sao tôi không thể truy cập nó khi tôi đang chạy nó trong máy docker, tôi chợt nhận ra rằng nó có thể liên quan đến chuyển tiếp IP hoặc điều gì đó nhưng tôi là một người hoàn toàn không thích kết nối mạng, tôi Tôi chủ yếu là một nhà phát triển web và hầu như không có kinh nghiệm về bản địa.


bạn đã sử dụng EXPOSE 8080 trong Dockerfile của mình cùng với tùy chọn -p chưa? Ngoài ra, hãy kiểm tra xem cổng 8080 trên hộp mà vùng chứa của bạn đang chạy có bị chặn bởi các quy tắc bảo mật của bạn hay không.
keda

@keda Có, Dockerfile có chứa EXPOSE 8080. Tôi đang chạy bộ chứa cục bộ trên máy tính của mình thông qua Quickstart Terminal của Docker, tôi cũng đã thử tắt tường lửa Windows nhưng cũng không hoạt động, tôi không biết có cài đặt nào không. 'm mất tích
redsalt

Câu trả lời:


90

TL; DR Kiểm tra chế độ mạng của máy chủ VirtualBox của bạn - đó là chế độ bridgednếu bạn muốn máy ảo (và vùng chứa Docker mà nó đang lưu trữ) có thể truy cập được trên mạng cục bộ của bạn.


Có vẻ như sự nhầm lẫn của bạn nằm ở chỗ nên kết nối với máy chủ nào để truy cập ứng dụng của bạn qua HTTP. Bạn chưa thực sự hiểu rõ cấu hình của mình là gì - tôi sẽ đưa ra một số phỏng đoán, dựa trên thực tế là bạn đã có "Windows" và "VirtualBox" trong thẻ của mình.

Tôi đoán rằng bạn có Docker chạy trên một số phiên bản Linux chạy trong VirtualBox trên máy chủ Windows. Tôi sẽ gắn nhãn các địa chỉ IP như sau:

D = địa chỉ IP của vùng chứa Docker

L = địa chỉ IP của máy chủ Linux đang chạy trong VirtualBox

W = địa chỉ IP của máy chủ Windows

Khi bạn chạy ứng dụng Go trên máy chủ Windows của mình, bạn có thể kết nối với nó http://W:8080/từ bất kỳ đâu trên mạng cục bộ của mình. Điều này hoạt động vì ứng dụng Go liên kết cổng 8080 trên máy Windows và bất kỳ ai cố gắng truy cập cổng 8080 tại địa chỉ IP Wsẽ được kết nối.

Và đây là nơi mà nó trở nên phức tạp hơn:

VirtualBox, khi nó thiết lập một máy ảo (VM), có thể cấu hình mạng ở một trong một số chế độ khác nhau. Tôi không nhớ tất cả các tùy chọn khác nhau là gì, nhưng tùy chọn bạn muốn là gì bridged. Trong chế độ này, VirtualBox kết nối máy ảo với mạng cục bộ của bạn như thể nó là một máy độc lập trên mạng, giống như bất kỳ máy nào khác đã được cắm vào mạng của bạn. Ở bridgedchế độ, máy ảo xuất hiện trên mạng của bạn giống như bất kỳ máy nào khác. Các chế độ khác thiết lập mọi thứ theo cách khác và máy sẽ không hiển thị trên mạng của bạn.

Vì vậy, giả sử bạn thiết lập mạng chính xác cho máy chủ Linux ( bridged), máy chủ Linux sẽ có địa chỉ IP trên mạng cục bộ của bạn (chẳng hạn như 192.168.0.x) và bạn sẽ có thể truy cập vùng chứa Docker của mình tại http://L:8080/.

Nếu máy chủ Linux được đặt ở một số chế độ khác bridged, bạn thể truy cập từ máy chủ Windows, nhưng điều này sẽ phụ thuộc vào chính xác chế độ của nó.

CHỈNH SỬA - dựa trên các nhận xét bên dưới, có vẻ như tình huống tôi mô tả ở trên là đúng.

Hãy sao lưu một chút: đây là cách Docker hoạt động trên máy tính của tôi (Ubuntu Linux).

Hãy tưởng tượng tôi chạy lệnh tương tự bạn có: docker run -p 8080:8080 dockertest. Điều này làm là bắt đầu một vùng chứa mới dựa trên dockertesthình ảnh và chuyển tiếp (kết nối) cổng 8080 trên máy chủ Linux (PC của tôi) đến cổng 8080 trên vùng chứa. Docker thiết lập mạng nội bộ của riêng nó (với bộ địa chỉ IP riêng) để cho phép Docker daemon giao tiếp và cho phép các vùng chứa giao tiếp với nhau. Vì vậy, về cơ bản những gì bạn đang làm với đó -p 8080:8080là kết nối mạng nội bộ của Docker với mạng "bên ngoài" - tức là. bộ điều hợp mạng của máy chủ - trên một cổng cụ thể.

Với tôi cho đến nay? OK, bây giờ hãy lùi lại một bước và xem xét hệ thống của bạn. Máy của bạn đang chạy Windows - Docker (hiện tại) không chạy trên Windows, vì vậy công cụ bạn đang sử dụng đã thiết lập máy chủ Linux trong máy ảo VirtualBox. Khi bạn thực hiện điều này docker runtrong môi trường của mình, điều tương tự cũng đang xảy ra - cổng 8080 trên máy chủ Linux được kết nối với cổng 8080 trên vùng chứa. Sự khác biệt lớn ở đây là máy chủ Windows của bạn không phải là máy chủ Linux mà vùng chứa đang chạy, vì vậy có một lớp khác ở đây và giao tiếp qua lớp này nơi bạn đang gặp sự cố.

Những gì bạn cần là một trong hai thứ:

  1. để kết nối cổng 8080 trên máy ảo VirtualBox với cổng 8080 trên máy chủ Windows, giống như bạn kết nối vùng chứa Docker với cổng máy chủ.

  2. để kết nối trực tiếp máy ảo VirtualBox với mạng cục bộ của bạn bằng bridgedchế độ mạng mà tôi đã mô tả ở trên.

Nếu bạn đi cho tùy chọn đầu tiên, bạn sẽ có thể truy cập vào container tại http://W:8080nơi Wlà địa chỉ IP hoặc hostname của các máy chủ Windows. Nếu bạn lựa chọn thứ hai, bạn sẽ có thể truy cập vào container tại http://L:8080nơi Llà địa chỉ IP hoặc hostname của máy ảo Linux.

Vì vậy, đó là tất cả lời giải thích cấp cao hơn - bây giờ bạn cần tìm ra cách thay đổi cấu hình của VirtualBox VM. Và đây là nơi tôi thực sự không thể giúp bạn - tôi không biết bạn đang sử dụng công cụ nào để thực hiện tất cả việc này trên máy Windows của mình và tôi cũng không quen với việc sử dụng Docker trên Windows.

Nếu bạn có thể truy cập cửa sổ cấu hình VirtualBox, bạn có thể thực hiện các thay đổi được mô tả bên dưới. Cũng có một ứng dụng khách dòng lệnh sẽ sửa đổi các máy ảo, nhưng tôi không quen với điều đó.

Đối với bridgedchế độ (và đây thực sự là lựa chọn đơn giản nhất), hãy tắt máy ảo của bạn, nhấp vào nút "Cài đặt" ở trên cùng và thay đổi chế độ mạng thành bridged, sau đó khởi động lại máy ảo và bạn đã sẵn sàng. Máy ảo sẽ nhận một địa chỉ IP trên mạng cục bộ của bạn thông qua DHCP và sẽ được hiển thị cho các máy tính khác trong mạng tại địa chỉ IP đó.


1
Tôi chỉ có thể tìm thấy 2 IP, IP mà Docker hiển thị khi tôi mở Quickstart Terminal (192.168.99.100) và IP mà máy tính của tôi có (192.168.0.157), bằng cách sử dụng, docker run -p 8080:8080 dockertesttôi có thể truy cập trang web của mình http://192.168.99.100:8080nhưng chỉ từ máy tính Windows của mình ( máy chủ) và không phải từ điện thoại của tôi. Nếu tôi sử dụng, docker run -p 192.168.0.157:8080:8080 dockertesttôi không thể truy cập trang web bằng bất kỳ IP nào từ bất kỳ đâu. Tôi không chắc chắn về cách thiết lập mạng, tôi đã thử sử dụng --net=bridgenhưng không hiệu quả. Tôi có muốn mở VirtualBox không? Tôi không thể làm điều đó bằng cách sử dụng thiết bị đầu cuối của Docker?
redsalt

Vấn đề không phải ở Docker, vì vậy không, Docker không thể giúp bạn. Tôi sẽ thêm một số chỉnh sửa để minh họa những gì tôi nghĩ đang diễn ra.
Kryten

Ok, cảm ơn bạn! Giờ thì tôi đã hiểu, tôi đã bối rối bởi toàn bộ phần máy ảo Linux. Tôi có ấn tượng rằng Docker đang sử dụng Hộp ảo cho những thứ bên trong mà tôi không cho là chạm vào. Nó thực sự rất dễ dàng, tôi chỉ cần đổi sang bridgedVirtual Box và bây giờ nó hoạt động thật kỳ diệu, cảm ơn bạn rất nhiều.
redsalt

Không có cách nào để có các cửa sổ và bộ chứa docker trong cùng một mạng, vì vậy chúng ta có thể truy cập các vùng chứa trực tiếp mà không cần chuyển tiếp cổng?
Vituel

Tình cờ gặp điều này khi tìm kiếm máy chủ Jupyter đang chạy trong docker và cố gắng truy cập nó qua mạng LAN. Có cách nào tôi có thể tìm ra L là gì sau khi chuyển chế độ sang bắc cầu không?
PaulDong

121
  1. Mở Oracle VM VirtualBox Manager
  2. Chọn máy ảo được Docker sử dụng
  3. Nhấp vào Cài đặt -> Mạng
  4. Bộ điều hợp 1 phải (mặc định?) Là "Được đính kèm với: NAT"
  5. Nhấp vào Nâng cao -> Chuyển tiếp cổng
  6. Thêm quy tắc: Giao thức TCP, Cổng Máy chủ 8080, Cổng Khách 8080 (để trống IP Máy chủ và IP Khách)
  7. Khách là bộ chứa docker của bạn và Máy chủ là máy của bạn

Bây giờ bạn có thể duyệt đến vùng chứa của mình qua localhost: 8080 và your-internal-ip: 8080.


10
Xác nhận, tốt đẹp và dễ dàng.
Dirk

2
Câu trả lời tốt nhất, không có mô tả khổng lồ như một lựa chọn
Amir Khan Qayyum

2
cho người dùng lang thang thêm này trong vagrantfile: config.vm.network "forwarded_port", quý khách: 8080, chủ nhà: 8080, giao thức: "tcp"
Vince Verhoeven

3
Yo! Điều này hoạt động như một sự quyến rũ! Cảm ơn!!!! Tôi dành hàng giờ để tìm ra điều này.
Joseph Freeman

2
Đây là một giải pháp tuyệt vời cho bất kỳ ai chạy Docker thông qua VBox!
Mirodinho

7

Sau khi thử một số điều, điều này đã hiệu quả với tôi:

  • sử dụng cờ --publish = 0.0.0.0: 8080: 8080 docker
  • đặt chế độ mạng virtualbox thành NAT và không sử dụng bất kỳ chuyển tiếp cổng nào

Với những địa chỉ khác 0.0.0.0tôi đã không thành công.


4

TLDR: Nếu bạn đã bật Tường lửa của Windows, hãy đảm bảo rằng có một ngoại lệ cho "vpnkit" trên các mạng riêng.

Đối với trường hợp cụ thể của tôi, tôi phát hiện ra rằng Tường lửa của Windows đang chặn kết nối của tôi khi tôi cố gắng truy cập cổng đã xuất bản của vùng chứa từ một máy khác trên mạng cục bộ của mình, vì việc tắt nó sẽ khiến mọi thứ hoạt động.

Tuy nhiên, tôi không muốn tắt hoàn toàn tường lửa chỉ để tôi có thể truy cập dịch vụ của vùng chứa của mình. Điều này đặt ra câu hỏi rằng "ứng dụng" nào đang lắng nghe thay mặt cho dịch vụ vùng chứa của tôi. Sau khi tìm thấy một chuỗi SO khác dạy tôi sử dụng netstat -a -bđể khám phá các ứng dụng đằng sau các ổ cắm nghe trên máy của mình, tôi biết rằng đó là vpnkit.exe, đã có một mục trong cài đặt Tường lửa Windows của tôi: nhưng "mạng riêng" đã bị tắt trên đó và khi tôi bật nó, tôi có thể truy cập dịch vụ vùng chứa của mình từ một máy khác mà không cần phải tắt hoàn toàn tường lửa.


Thưa ông, ông đã cứu tôi khỏi hàng giờ thất vọng. Cảm ơn.
Behdad

2

Đây là vấn đề phổ biến nhất mà người dùng Windows phải đối mặt khi chạy Docker Containers. IMO đây là "câu hỏi triệu đô trên Docker"; @ "Rocco Smit" đã chỉ ra đúng "lưu lượng truy cập vào cho nó đã bị tắt theo mặc định trên tường lửa của máy chủ của tôi"; trong trường hợp của tôi, phần mềm McAfee Anti Virus của tôi. Tôi đã thêm các cổng bổ sung được phép cho lưu lượng đến từ các máy tính khác trên cùng một mạng LAN Wifi trong Cài đặt Tường lửa của McAfee; thì đó là phép thuật. Tôi đã vật lộn trong hơn một tuần duyệt qua internet, SO, tài liệu Docker, Hướng dẫn sau Hướng dẫn liên quan đến Mạng của Docker và nhiều hình ảnh minh họa về "không được hỗ trợ trên Windows" cho người dùng "macvlan", "ipvlan", " cầu được xác định "và thậm chí cùng một chủ đề SO này vài lần. Tôi thậm chí đã bắt đầu duyệt google với "có ai sử dụng Docker trong Sản xuất không?", (Vâng, tôi biết Linux phổ biến hơn cho khối lượng công việc Sản phẩm so với máy chủ Windows) vì tôi không thể truy cập (từ điện thoại di động của tôi trong cùng một Wi-Fi tại nhà) một nginx ứng dụng được triển khai trong Docker Container trên Windows. Rốt cuộc, sẽ tốt gì nếu bạn không thể truy cập ứng dụng (được triển khai trên Docker Container) từ các máy tính / thiết bị khác trong cùng một mạng LAN ít nhất; Cuối cùng trong trường hợp của tôi, vấn đề chỉ là do tường lửa chặn lưu lượng truy cập vào; ít nhất nếu bạn không thể truy cập ứng dụng (được triển khai trên Docker Container) từ các máy tính / thiết bị khác trong cùng một mạng LAN; Cuối cùng trong trường hợp của tôi, vấn đề chỉ là do tường lửa chặn lưu lượng truy cập vào; ít nhất nếu bạn không thể truy cập ứng dụng (được triển khai trên Docker Container) từ các máy tính / thiết bị khác trong cùng một mạng LAN; Cuối cùng trong trường hợp của tôi, vấn đề chỉ là do tường lửa chặn lưu lượng truy cập vào;


0

Tôi nhận thấy rằng cùng với việc đặt giá trị cổng -p, Docker cho Windows sử dụng vpnkit và lưu lượng truy cập vào cho nó đã bị tắt theo mặc định trên tường lửa của máy chủ của tôi. Sau khi bật các quy tắc TCP gửi đến cho vpnkit, tôi có thể truy cập vùng chứa của mình từ các máy khác trên mạng cục bộ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.