Câu trả lời:
Theo tài liệu tham khảo soạn thảo docker ,
Các cổng tiếp xúc . Hoặc chỉ định cả hai cổng (HOST: CONTAINER) hoặc chỉ cổng container (một cổng máy chủ ngẫu nhiên sẽ được chọn).
Hình của tôi docker-compose.yml
như:
mysql:
image: mysql:5.7
ports:
- "3306"
Nếu tôi làm docker-compose ps
, nó sẽ giống như:
Name Command State Ports
-------------------------------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:32769->3306/tcp
Đưa ra các cổng mà không xuất bản chúng cho máy chủ - chúng sẽ chỉ có thể truy cập được với các dịch vụ được liên kết. Chỉ có thể chỉ định cổng nội bộ.
Các cổng không được tiếp xúc với máy chủ, chỉ tiếp xúc với các dịch vụ khác.
mysql:
image: mysql:5.7
expose:
- "3306"
Nếu tôi làm docker-compose ps
, nó sẽ giống như:
Name Command State Ports
---------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp
expose
trong Dockerfiles: "Lệnh EXPOSE không thực sự xuất bản cổng. Nó hoạt động như một loại tài liệu ..." docs.docker.com/engine/reference/builder/#expose
docker-compose run
, định nghĩa cổng trong docker-compose.yml
được bỏ qua theo mặc định. Sử dụng docker-compose up
hoặc cung cấp tham số--service-ports
cổng :
phơi bày :
Cổng Phần này được sử dụng để xác định ánh xạ giữa máy chủ lưu trữ và bộ chứa Docker.
ports:
- 10005:80
Nó có nghĩa là ứng dụng chạy bên trong container được hiển thị tại cổng 80. Nhưng hệ thống / thực thể bên ngoài không thể truy cập vào nó, vì vậy nó cần được ánh xạ tới cổng máy chủ lưu trữ.
Lưu ý: bạn phải mở cổng máy chủ 10005 và sửa đổi các quy tắc tường lửa để cho phép các thực thể bên ngoài truy cập vào ứng dụng.
Họ có thể sử dụng
http: // {IP máy chủ}: 10005
một cái gì đó như thế này
TIẾP XÚC Điều này được sử dụng riêng để xác định cổng mà ứng dụng đang chạy bên trong bộ chứa docker.
Bạn có thể định nghĩa nó trong dockerfile. Nói chung, đó là cách thực hành tốt và được sử dụng rộng rãi để xác định EXPOSE bên trong dockerfile vì rất hiếm khi có ai chạy chúng trên cổng khác ngoài cổng 80 mặc định
Phần ports
này sẽ xuất bản các cổng trên máy chủ. Docker sẽ thiết lập chuyển tiếp cho một cổng cụ thể từ mạng chủ vào container. Theo mặc định, điều này được thực hiện với quy trình proxy không gian người dùng (docker-proxy
) lắng nghe trên cổng đầu tiên và chuyển tiếp vào vùng chứa, cần lắng nghe ở điểm thứ hai. Nếu container không nghe trên cổng đích, bạn vẫn sẽ thấy một cái gì đó đang nghe trên máy chủ, nhưng bị từ chối kết nối nếu bạn cố kết nối với cổng máy chủ đó, từ việc chuyển tiếp thất bại vào container của bạn.
Lưu ý, bộ chứa phải lắng nghe trên tất cả các giao diện mạng vì proxy này không chạy trong không gian tên của bộ chứa và không thể đạt tới 127.0.0.1 bên trong bộ chứa. Phương pháp IPv4 cho điều đó là cấu hình ứng dụng của bạn để nghe 0.0.0.0
.
Cũng lưu ý rằng các cổng được xuất bản không hoạt động theo hướng ngược lại. Bạn không thể kết nối với một dịch vụ trên máy chủ từ container bằng cách xuất bản một cổng. Thay vào đó, bạn sẽ tìm thấy lỗi docker khi cố gắng lắng nghe cổng máy chủ đã sử dụng.
Tiếp xúc là tài liệu. Nó đặt siêu dữ liệu trên hình ảnh và khi chạy, trên container cũng vậy. Thông thường, bạn định cấu hình này trong Dockerfile theo EXPOSE
hướng dẫn và nó đóng vai trò là tài liệu cho người dùng chạy hình ảnh của bạn, để họ biết cổng nào theo mặc định ứng dụng của bạn sẽ lắng nghe. Khi được định cấu hình với tệp soạn thảo, siêu dữ liệu này chỉ được đặt trên vùng chứa. Bạn có thể thấy các cổng bị lộ khi bạn chạy một docker inspect
hình ảnh hoặc thùng chứa.
Có một vài công cụ dựa vào các cổng tiếp xúc. Trong docker, -P
cờ sẽ xuất bản tất cả các cổng tiếp xúc lên các cổng phù du trên máy chủ. Ngoài ra còn có các proxy ngược khác nhau sẽ mặc định sử dụng cổng bị lộ khi gửi lưu lượng truy cập đến ứng dụng của bạn nếu bạn không đặt cổng container một cách rõ ràng.
Khác với những công cụ bên ngoài, phơi bày hoàn toàn không có tác động đến kết nối mạng giữa các container. Bạn chỉ cần một mạng docker chung và kết nối với cổng container, để truy cập một container từ một container khác. Nếu mạng đó là do người dùng tạo (ví dụ: mạng cầu nối mặc định có tên bridge
), bạn có thể sử dụng DNS để kết nối với các container khác.
Tôi hoàn toàn đồng ý với câu trả lời trước đó. Tôi chỉ muốn đề cập rằng sự khác biệt giữa phơi bày và cổng là một phần của khái niệm bảo mật trong docker. Nó đi đôi với mạng lưới docker. Ví dụ:
Hãy tưởng tượng một ứng dụng có giao diện người dùng web và cơ sở dữ liệu phía sau. Thế giới bên ngoài cần quyền truy cập vào giao diện người dùng web (có lẽ trên cổng 80), nhưng chỉ bản thân back-end mới cần quyền truy cập vào máy chủ cơ sở dữ liệu và cổng. Sử dụng cầu do người dùng xác định, chỉ cần mở cổng web và ứng dụng cơ sở dữ liệu không cần mở bất kỳ cổng nào, vì giao diện người dùng web có thể tiếp cận qua cầu do người dùng xác định.
Đây là trường hợp sử dụng phổ biến khi thiết lập kiến trúc mạng trong docker. Vì vậy, ví dụ trong một mạng cầu mặc định, không thể truy cập các cổng từ thế giới bên ngoài. Do đó, bạn có thể mở một điểm vào với "cổng". Với việc sử dụng "phơi bày", bạn xác định giao tiếp trong mạng. Nếu bạn muốn hiển thị các cổng mặc định, bạn không cần xác định "phơi sáng" trong tệp soạn thảo docker.
expose
trong mộtdocker-compose
? Theo như tôi có thể nói, bạn không cần chỉ định phơi bày để làm cho các cổng có thể truy cập được vào các dịch vụ được liên kết.