【问题标题】:How to communicate between two containers using docker如何使用 docker 在两个容器之间进行通信
【发布时间】:2019-04-26 07:05:20
【问题描述】:

我在访问另一个容器中的一个容器路由时遇到了问题。例如,我有两个名为 user-serviceapi-gateway 的微服务。我正在尝试访问 api-gateway 中的 user-service 路由。

我的 api-gateway 文件可能如下所示

  const userServiceProxy = httpProxy(http://localhost:8093);
  this.app.post('/admin/register', async(req, res) => {

      userServiceProxy(req, res);

  });

api-gateway 正在端口 8080

上运行

我的 user-service 文件可能如下所示

 app.post('/admin/register', function (req, res) {
  res.send('POST request')
 })

当我使用端口 8080 通过 api-gateway 访问路由时,我无法调用该路由,但是当我尝试使用端口 8093 访问时,我可以看到结果。

我的 docker-compose 文件可能如下所示

 version: '3'
 services:
   api-gateway:
     container_name: api-gateway
     build: './api-gateway'
     ports:
       - "8080:8080"
     links:
       - user-service
   user-service:
     build: ./user-service
     container_name: user-service
     ports:
     - "8093:8093"

任何帮助将不胜感激,在此先感谢!

【问题讨论】:

  • httpProxy 对象是什么?
  • 当用户尝试使用端口 8080 访问路由时,通常会重定向到运行在端口 上的 用户服务 的路由8093。顺便说一句,我使用 express-http-proxy

标签: node.js docker


【解决方案1】:

localhost 指的是容器内的本地主机,而不是主机系统。

使用Docker Networks 并将localhost 替换为api-gateway 之类的服务名称。

如果容器在同一个网络中,地址http://api-gateway:8093应该可以工作。

另一种方法是在网络模式host 上运行容器。这是较少的隔离,但地址 localhost 有效,因为容器现在在 docker 守护进程的接口上运行

【讨论】:

  • 感谢您的回答@Wie!您能否建议我如何使用 Docker Networks
  • 抱歉,我离开了几天,@shape 与他或她的例子是对的。
【解决方案2】:

只需向您的 docker-compose 文件添加网络规范即可使用自定义桥接网络。

类似的东西可能对你有用

version: '3'
services:
  api-gateway:
    container_name: api-gateway
    build: './api-gateway'
    ports:
    - "8080:8080"
    networks:
    - mynet
  user-service:
    build: ./user-service
    container_name: user-service
    ports:
    - "8093:8093"
    networks:
    - mynet

networks:
  mynet:
    driver: bridge
    ipam:
      driver: default

根据您在 docker-compose 中指定的端口和服务,现在可以进行以下连接:

  • api-gateway 容器:user-service:8093
  • 用户服务容器:api-gateway:8080

如果我做对了,你的 api-gateway 现在是:

const userServiceProxy = httpProxy(http://user-service:8093);
  this.app.post('/admin/register', async(req, res) => {
      userServiceProxy(req, res);
  });

在 docker 网络中,您可以直接从其他容器访问端口(无需指定到主机的端口映射)。因此,您的端口映射之一可能是不必要的。如果您仅通过 api-gateway 而不是直接访问用户服务,则可以删除 docker-compose 文件(用户服务块)中的端口规范。然后,您的用户服务将只能使用 api-gateway 访问。这可能就是你想要的。

【讨论】:

  • 非常感谢@shape!这就是我一直在寻找的,它就像冠军一样。
【解决方案3】:

还有一个鲜为人知的选项将两个或多个容器连接在一起:

version: '3'

services:
  test1:
    image: alpine
    command: nc -lp 1337
  test2:
    image: alpine
    command: nc -lp 1337
    network_mode: service:test1

这类似于 Kubernetes pod 的内部网络 - 以这种方式链接的容器共享相同的内部地址(发布的端口在 localhost 上可见并且可以相互冲突)。因此,上述配置将无法正常工作,因为会发生端口冲突:

➜  docker-pod-test docker-compose up
Creating docker-pod-test_test1_1 ... done
Creating docker-pod-test_test2_1 ... done
Attaching to docker-pod-test_test1_1, docker-pod-test_test2_1
test2_1  | nc: bind: Address in use
docker-pod-test_test2_1 exited with code 1

【讨论】:

    【解决方案4】:

    最简单的方法是使用 docker 标志 --net=host 这样您的 docker 容器将使用主机的网络而不是它们自己的命名空间网络。例如

    docker run -d --network host -p 80:80 nginx
    

    您可以在http://localhost 上查看 nginx 欢迎页面。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2018-01-28
      • 2021-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多