首页 > 解决方案 > 同一网络上的 Docker 容器无法访问彼此的暴露端口(Linux)

问题描述

这是我部署的一个相当简单的 docker 堆栈:

version: "3"
services:
  mysql:
    environment:
      - MYSQL_ROOT_PASSWORD=welcome
      - MYSQL_DATABASE=db1
      - MYSQL_USER=dbuser
      - MYSQL_PASSWORD=welcome
      - MYSQL_ROOT_HOST=*
      - MYSQL_LOG_CONSOLE=true
    image: mysql/mysql-server:latest
    deploy:
    replicas: 1
    restart_policy:
     condition: on-failure
    ports:
     - "3306:3306"
   networks:
    - test_net
repository:
  environment:
    - DB_USER=dbuser
    - DB_PASSWORD=welcome
    - DB_HOST=mysql
    - DB_PORT=3306
  image: private_repo/repository-service:0.1.3
  deploy:
    replicas: 1
    restart_policy:
      condition: on-failure
  ports:
    - "9091:80"
  networks:
    - test_net
deployment:
  environment:
      - DB_USER=dbuser
      - DB_PASSWORD=welcome
      - DB_HOST=mysql
      - DB_PORT=3306
  image: private_repo/deployment-service:0.1.3
  deploy:
    replicas: 1
    restart_policy:
      condition: on-failure
  ports:
    - "9092:80"
  networks:
    - test_net
networks:
  test_net:

在 docker stack deploy 之后,我可以看到所有服务都在运行。但是,当我尝试从主机系统上的程序(例如 Postman)访问存储库或部署服务的 REST API 时,这不起作用(连接只是挂起)。所以我做了一些调试:

1)容器可以使用服务名称在覆盖网络上相互ping通。例如

docker exec -i edb7432cdb64 ping mysql
PING mysql (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=3 ttl=64 time=0.058 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=4 ttl=64 time=0.083 ms
64 bytes from 10.0.0.2 (10.0.0.2): icmp_seq=5 ttl=64 time=0.062 ms

2)从一个容器我可以使用 curl 访问另一个容器,但只能在内部端口上。

例如这有效:

docker exec -i edb7432cdb64 curl http://models:80/services/v1/models

但这会返回一个错误:

docker exec -i edb7432cdb64 curl http://models:9091/services/v1/models

curl: (7) Failed connect to models:9091; Connection refused

3)覆盖网络似乎缺少信息:

docker inspect tf0z2ht7tfhe
[
  {
    "Name": "repository2_test_net",
    "Id": "tf0z2ht7tfhefrcqvh4g0a2zq",
    "Created": "0001-01-01T00:00:00Z",
    "Scope": "swarm",
    "Driver": "overlay",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "",
        "Options": null,
        "Config": null
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
        "Network": ""
    },
    "ConfigOnly": false,
    "Containers": null,
    "Options": {
        "com.docker.network.driver.overlay.vxlanid_list": "4097"
    },
    "Labels": {
        "com.docker.stack.namespace": "repository2"
    }
  }
]

当我尝试在我的 Mac 上部署这个确切的堆栈时,它可以工作!对覆盖网络的相同检查提供的信息要多得多。一方面,它显示了一个容器列表,还给了我一个子网和网关。

不知何故,在我的 Linux 机器上,overlay 的网络设置不正确。我不确定我可能错过了什么配置。Mac 的 docker stack/swarm 和 Linux 的 docker stack/swarm 之间似乎没有太大区别。任何关于接下来要查看或尝试的内容的指示将不胜感激。

docker -v 
Docker version 17.06.2-ol, build d02b7ab

标签: dockerdocker-swarmdocker-networkingdocker-stack

解决方案


因此,尽管我无法使用 localhost:9091 访问服务,但我可以使用 swarm manager 地址访问它们。

swarm init
Swarm initialized: current node (a5aiio3xh1qfpnw6gf8keam4y) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-2e1yxt76ui6syrk2p4970hns25n57tquvprxn1l160vnrk0bog-bi10m0b0jcz54cv17pd469a26 10.*.*.*:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

我可以在 10 点访问我的服务.*:9091。不知道为什么这只发生在 Linux 上,或者是否有办法在此配置中使用 localhost。但现在这行得通。


推荐阅读