简体   繁体   English

公开一个容器端口,但主机无法访问其他容器端口

[英]Expose one container port but other not reacheable from the host machine

I do not know how to achieve that.我不知道如何实现。 Now all the ports are exposed to the host machine but I just want to expose one container port ( 80 ), not the other ( 8080 ).现在所有端口都暴露给主机,但我只想暴露一个容器端口( 80 ),而不是另一个( 8080 )。 Here is the docker-compose file:这是 docker-compose 文件:

---
version: "3.9"

services:
  app:
    image: sandbox/app
    container_name: app
    volumes:
      - ./src/app:/app/
    expose:
      - "8080"
    restart: unless-stopped
    networks:
      custom-net:
        ipv4_address: 10.0.0.7
  web_server:
    image: nginx:latest
    container_name: proxy
    ports:
      - "80:80"
    networks:
      custom-net:
        ipv4_address: 10.0.0.6
networks:
  custom-net:
    name: custom-net
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 10.0.0.0/8

If I run from the local machine nmap 10.0.0.6 , it shows port as open in port 80. This container exposure is the desired one.如果我从本地机器nmap 10.0.0.6运行,它会显示端口在端口 80 中打开。此容器暴露是所需的。 But when I run nmap 10.0.0.7 , it also shows as open 8080 port, how it could be that one?但是当我运行nmap 10.0.0.7时,它也显示为开放的 8080 端口,它怎么可能是那个? Checking some stackoverflow thread , ports is defined like that:检查一些stackoverflow 线程ports定义如下:

Expose ports.暴露端口。 Either specify both ports (HOST:CONTAINER), or just the container port (a random host port will be chosen).要么指定两个端口 (HOST:CONTAINER),要么只指定容器端口(将选择随机主机端口)。

and expose :expose

Expose ports without publishing them to the host machine - they'll only be accessible to linked services.公开端口而不将它们发布到主机 - 它们只能被链接服务访问。 Only the internal port can be specified.只能指定内部端口。

Do I miss some network concepts or do I have wrong docker-compose file?我错过了一些网络概念还是我有错误docker-compose文件?

You must be on a native-Linux host.您必须在本机 Linux 主机上。 If you happen to know the Docker-internal IP addresses, and you're on a native-Linux host, then you can always connect to a container using those addresses;如果您碰巧知道 Docker 内部 IP 地址,并且您在本机 Linux 主机上,那么您始终可以使用这些地址连接到容器; you can't prevent this (without iptables magic) but it's also not usually harmful.你无法阻止这种情况(没有iptables魔法),但它通常也不是有害的。 This trick doesn't work in other environments (on MacOS or Windows hosts, or if Docker is in a Linux VM, or from a different host from the container) and it's much more portable to connect only to containers' published ports: .这个技巧在其他环境中不起作用(在 MacOS 或 Windows 主机上,或者如果 Docker 在 Linux VM 中,或者来自与容器不同的主机),并且仅连接到容器的已发布ports: .

You should be able to use a much simpler Compose file.您应该能够使用更简单的 Compose 文件。 Delete all of the networks: blocks and the expose: blocks.删除所有networks:块和expose:块。 You also do not need container_name: , and you should not need to inject code using volumes: .您也不需要container_name: ,也不需要使用volumes:注入代码。 Trimming out all of the unnecessary options leaves you with修剪掉所有不必要的选项给你留下

version: '3.8' # last version supported by standalone docker-compose tool
services:
  app:
    image: sandbox/app # may want `build: .` _instead of_ this line
    restart: unless-stopped
  web_server:
    image: nginx:latest # needs some custom configuration?
    ports:
      - "80:80"

That should literally be the entire file.那应该是整个文件。

From outside Docker but on the same machine, http://localhost:80 matches the first ports: of the web_server container, so forwards to the second ports: , on which the Nginx server is listening.从 Docker 外部但在同一台机器上, http://localhost:80匹配web_server容器的第一个ports: ,因此转发到 Nginx 服务器正在侦听的第二个ports: The Nginx configuration should include a line like proxy_pass http://app:8080 which will forward to the application container. Nginx 配置应该包括像proxy_pass http://app:8080这样的行,它将转发到应用程序容器。

Compared to your original file:与您的原始文件相比:

  • expose: is an artifact of first-generation Docker networking. expose:是第一代Docker网络的神器。 In a Compose file it does absolutely nothing at all and it's always safe to delete it.在 Compose 文件中,它完全不做任何事情,删除它总是安全的。
  • Connections between containers (where web_server uses app as a host name) connect directly to the specified port;容器之间的连接(其中web_server使用app作为主机名)直接连接到指定的端口; they do not use or require expose: or ports: settings, and they ignore ports: if they're present.他们不使用或需要expose:ports:设置,并且他们忽略ports:如果它们存在。
  • Compose assigns container names on its own, and there are docker-compose CLI equivalents to almost all Docker commands that can figure out the right mapping. Compose 自己分配容器名称,并且几乎所有 Docker 命令都有docker-compose CLI 等效项,可以找出正确的映射。 You don't need to manually specify container_name: .您无需手动指定container_name:
  • Docker automatically assigns IP addresses to containers. Docker 自动为容器分配 IP 地址。 These are usually an internal implementation detail;这些通常是内部实现细节; it's useful to know that containers do have their own IP addresses (and so you can have multiple containers that internally listen on the same port) but you never need to know these addresses, look them up, or manually specify them.知道容器确实有自己的 IP 地址是很有用的(因此您可以有多个容器在内部侦听同一端口),但您永远不需要知道这些地址、查找它们或手动指定它们。
  • Compose automatically creates a network named default for you and attaches containers to it, so in most common cases you don't need networks: at all. Compose 会自动为您创建一个名为default的网络并将容器附加到它,因此在大多数情况下,您根本不需要networks:

Networking in Compose in the Docker documentation describes how to make connections between containers (again, you do not need to know the container-private IP addresses). Docker 文档中的 Compose 中的网络描述了如何在容器之间建立连接(同样,您不需要知道容器专用 IP 地址)。 Container networking discusses these concepts separately from Compose. 容器网络与 Compose 分开讨论这些概念。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM