如何使用Docker在两个容器之间进行通信

时间:2019-04-26 07:05:20

标签: node.js docker

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

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

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

      userServiceProxy(req, res);

  });

api-gateway 在端口8080上运行

我的用户服务文件可能如下所示

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

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

我的 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"

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

4 个答案:

答案 0 :(得分:5)

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

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

如果容器在同一网络中,则地址http://api-gateway:8093应该有效。

另一种方法是在网络模式host上运行容器。这种隔离较少,但是地址localhost起作用了,因为该容器现在正在docker deamon的界面上运行

答案 1 :(得分:1)

只需在您的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中指定的端口和服务,现在可以进行以下连接:

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

如果我做对了,您的api网关现在将是:

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访问。可能正是您想要的。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

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