为什么我能够访问桥接网络之外的容器?

Why is that I am able to access container outside the bridge network?

我从 docker 容器启动 mysqldb。我很惊讶我可以使用以下命令通过本地主机连接它

mysql -uroot -proot -P3306 -h localhost

我认为 docker 容器在桥接网络上启动并且在该网络之外不可用。 mysql CLI 是如何连接到这个实例的

下面是我的 docker compose 运行 mysqldb-docker 实例

version: '3.8'
services:
  mysqldb-docker:
    image: 'mysql:8.0.27'
    restart: 'unless-stopped'
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_PASSWORD=root
      - MYSQL_DATABASE=reco-tracker-dev
    volumes:
      - mysqldb:/var/lib/mysql
  reco-tracker-docker:
    image: 'reco-tracker-docker:v1'
    ports:
      - "8083:8083"
    environment:
      - SPRING_DATASOURCE_USERNAME=root
      - SPRING_DATASOURCE_PASSWORD=root
      - SPRING_DATASOURCE_URL="jdbc:mysql://mysqldb-docker:3306/reco-tracker-dev"
    depends_on: [mysqldb-docker]
    env_file:
      - ./.env
volumes:
  mysqldb:

您有 published 个端口。这意味着您可以通过已发布的端口在主机系统上访问它们。

By default, when you create or run a container using docker create or docker run, it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container’s network, use the --publish or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host to the outside world.

您配置中的关键部分如下。您已将 ports 密钥添加到您的服务中。这是发布端口的组合方式。左侧部分是您将其发布到主机系统上的端口。右边部分是容器实际监听的地方。

ports:
  - "3306:3306"

另请记住,当您开始撰写时,会创建一个默认网络,将所有容器连接到撰写 堆栈 中。这就是为什么这些容器可以找到彼此,以服务名称 and/or容器名称作为主机名。

您不需要像以前那样发布端口以便它们能够通信。我想这就是你这样做的原因。如果可能,您可以并且可能应该从 internal 服务中删除任何端口映射。这将为您的设置增加额外的安全性,因为它的行为就像您描述的那样。只有同一网络中的容器才能找到彼此。