Docker容器间通信

Docker容器间通信是很常见的操作,它允许一个容器使用另一个容器提供的服务。本文主要介绍的是多个容器在同一个Docker主机进行通信的方式。

myapp/docker-compose.yml

version: '3.8'
services:
  app:
    container_name: docker-node-mongo
    restart: always
    build: .  # 在当前目录下查找 Dockerfile 构建容器
    ports:
      - '8080:3000'
    depends_on:
      - mongodb
      
  mongodb:
    container_name: mongo
    image: mongo
    ports:
      - '27015:27017'

运行docker-compose up之后,将会发生以下事情

  1. 创建名为myapp_default的网络,myappdocker-compose.yml所在的目录
  2. 创建docker-node-mongo容器,并加入到myapp_default网络
  3. 创建mongo容器,并加入到myapp_default网络

每个容器可以通过主机名(hostname)docker-node-mongomongo查找对应容器的ip地址,如docker-node-mongo容器的代码中可以通过mongodb://mongo:27017/docker-node-mongo连接到Mongo数据库。

这里注意区分HOST_PORTCONTAINER_PORT,对于mongodbCONTAINER_PORT为27017,它是服务间通信的端口,HOST_PORT为27015,它是外部访问mongo服务的端口。

depends_on用于建立服务间的依赖关系,但是仅仅是按顺序启动,并不能保证此时数据库已就绪,可以参考这篇文章了解解决方案

如果两个服务并不是定义在同一个yml文件中,这种直接通信方式就失效了,这里提供两种解决方式。

  • 方式一:让需要通信的服务处于同一个外部网络

创建网络

docker network create app_net

docker-node-mongo/docker-compose.yml

version: '3'
services:
  app:
    container_name: docker-node-mongo
    restart: always
    build: .
    image: docker-node-mongo:1.0.1
    ports:
      - '8550:3000'

    networks:
      - default
      - app_net
networks:
  app_net:
    external: true

mongo/docker-compose.yml

version: '3'
services:
  mongodb:
    container_name: mongo
    image: mongo
    ports:
      - '27017:27017'
    volumes:
      - /opt/docker_mongo/data/db:/data/db
    networks:
      - default
      - app_net
networks:
  app_net:
    external: true

这样两个服务都使用了同一个外部网络app_net,也就可以正常通信了。使用docker exec -it docker-test ping mongo查看容器间是否连通。

docker exec -it docker-test ping mongo
PING mongo (172.28.0.2) 56(84) bytes of data.
64 bytes from mongo.app_net (172.28.0.2): icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from mongo.app_net (172.28.0.2): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from mongo.app_net (172.28.0.2): icmp_seq=3 ttl=64 time=0.053 ms
64 bytes from mongo.app_net (172.28.0.2): icmp_seq=4 ttl=64 time=0.061 ms
64 bytes from mongo.app_net (172.28.0.2): icmp_seq=5 ttl=64 time=0.060 ms
^C
--- mongo ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4104ms
  • 方式二:更改需要通信的服务的网络模式

mongo/docker-compose.yml

version: '3'
services:
  mongodb:
    container_name: mongo
    image: mongo
    ports:
      - '27017:27017'
    volumes:
      - /opt/docker_mongo/data/db:/data/db
    network_mode: bridge

docker-test/docker-compose.yml

version: '3'
services:
  app:
    container_name: docker-test
    restart: always
    build: .
    image: docker-test:1.0
    ports:
      - '8150:4000'
    network_mode: bridge
    external_links:
      - mongo

通过修改network_modebridge,并且指定external_links为另一个容器的container_name,可以实现docker-testmongo的单向通信。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。