docker学习7:docker 容器的通信方式

使用Docker Compose 的时候,涉及到多个 docker 容器的通信,我们是通过指定宿主机 ip 和端口的方式。

因为 mysql、redis 的 Docker 容器都映射到了宿主机的端口,那 nest 的容器就可以通过宿主机来实现和其他容器的通信。

Docker 的实现原理那节我们讲过,Docker 通过 Namespace 的机制实现了容器的隔离,其中就包括 Network Namespace。

因为每个容器都有独立的 Network Namespace,所以不能直接通过端口访问其他容器的服务。

那如果这个 Network Namespace 不只包括一个 Docker 容器呢??

可以创建一个 Network Namespace,然后设置到多个 Docker 容器,这样这些容器就在一个 Namespace 下了,不就可以直接访问对应端口了?

Docker 确实支持这种方式,叫做桥接网络。

通过 docker network 来创建:

js 复制代码
docker network create common-network

这次跑的时候要指定 --network。

通过 --network 指定桥接网络为我们刚创建的 common-network。

不需要指定和宿主机的端口映射。

js 复制代码
docker run -d --network common-network -v /Users/guang/mysql-data:/var/lib/mysql --name mysql-container mysql

docker run -d --network common-network -v /Users/guang/aaa:/data --name redis-container redis

然后 nest 的部分我们要改下代码:

修改 AppModule 的代码,改成用容器名来访问:

js 复制代码
docker run -d --network common-network -p 3000:3000 --name nest-container mmm

这就是桥接网络。

之前我们是通过宿主机 ip 来互相访问的,现在可以通过容器名直接互相访问了。

原理前面讲过,就是 Namespace。

本来是 3 个独立的 Network Namespace:

桥接之后就这样了:

Namespace 下包含多个子 Namespace,互相能通过容器名访问。

比起端口映射到宿主机,再访问宿主机 ip 的方式,简便太多了。

那在 Docker Compose 里怎么使用这种方式呢?

js 复制代码
version: '3.8'
services:
  nest-app:
    build:
      context: ./
      dockerfile: ./Dockerfile
    depends_on:
      - mysql-container
      - redis-container
    ports:
      - '3000:3000'
    networks:
      - common-network
  mysql-container:
    image: mysql
    volumes:
      - /Users/guang/mysql-data:/var/lib/mysql
    environment:
      MYSQL_DATABASE: aaa
      MYSQL_ROOT_PASSWORD: guang
    networks:
      - common-network
  redis-container:
    image: redis
    volumes:
      - /Users/guang/aaa:/data
    networks:
      - common-network
networks:
  common-network:
    driver: bridge

version 是指定 docker-compose.yml 的版本,因为不同版本配置不同。

把 mysql-container、redis-container 的 ports 映射去掉,指定桥接网络为 common-network。

然后下面通过 networks 指定创建的 common-network 桥接网络,网络驱动程序指定为 bridge。

其实我们一直用的网络驱动程序都是 bridge,它的含义是容器的网络和宿主机网络是隔离开的,但是可以做端口映射。比如 -p 3000:3000、-p 3306:3306 这样。

这就是在 docker-compose 里使用桥接网络的方式。

不过,其实不指定 networks 也可以,docker-compose 会创建个默认的。

把 networks 部分注释掉,重新跑:

你会发现它创建了一个默认的 network:

所以,不手动指定 networks,也是可以用桥接网络的。

多个容器之间的通信方式,用桥接网络是最简便的。

相关推荐
Sayai1 小时前
Elasticsearch 9 安装验证实战:start-local 一键部署 + Docker 手动安装踩坑指南
大数据·elasticsearch·docker
名字还没想好☜7 小时前
Docker 容器安全加固实战:非 root、只读根文件系统、drop capabilities 与最小攻击面
运维·安全·docker·容器·kubernetes
码--到成功8 小时前
Docker、Kubernetes安装系列 二
docker·容器·kubernetes
M--Y9 小时前
Docker镜像与仓库管理详解
docker·容器
starzy19909 小时前
虚拟化解决方案全景:软件虚拟化、硬件虚拟化与 Docker 的位置
运维·docker·容器
名字还没想好☜14 小时前
Docker buildx 多架构镜像实战:一次构建 amd64+arm64,告别 exec format error
运维·docker·eureka·架构·kubernetes
gs8014015 小时前
告别 CI/CD 误伤与红条:Docker 镜像智能清理与优雅防冲突实战
ci/cd·docker·容器
wjcroom15 小时前
FileBrowser的docker运行了改变密码长度的做法
运维·docker·容器
dazhong201218 小时前
Docker 进阶篇(一) CentOS 7 离线升级 Docker 完整实战
docker·容器·centos
雾隐隐o19 小时前
Docker Compose 多容器编排实战
运维·docker·容器