容器间的通信方式
一个分布式应用,多个容器之间往往需要通信,比如 HTTP 服务容器往往需要与数据库容器进行通信。容器的通信方式有以下几种:
- 通过
docker run
起一个容器时带上--link
参数指定该容器与其他容器进行相关联 (即将废弃,原理就不描述了) - 通过
docker network
系统来建立通信 - docker-compose
Docker Network
网络驱动模式
Docker Network 有多种驱动模式,默认为 bridge,即桥接模式。bridge network 原理是新建 network 时建立一个网桥(网关),所有加入此 network 的容器需要彼此通信时通过该网桥进行转发。每一个 bridge network(包含网关及其下的容器)都有一个独立的 IP 网段,不同网段间的容器无法通信,这也就是指定 bridge network 进行容器间网络隔离的原理。
默认 Network
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
9c9d4fd4f950 bridge bridge local
3ce82c0caf70 host host local
f1a111712ad4 none null local
Docker 内置了一个默认 bridge network(名为 bridge,第一行),所有未指定 network 的容器,默认连接到此 network 中,其网段为 172.17.0.X
。所以,两个未进行任何连接操作的容器是可以通过 IP 地址互相通信的,因为他们同在一个 network 下,但通讯只能通过 IP 地址进行(比如 ping 172.17.0.5
),不可以通过容器名通信(比如 ping container-name
)。但自定义创建的网络可以通过容器名进行通信。
自定义网络
$ docker network create NAME
- 不指定
-d
参数,默认创建 bridge 驱动模式的 network。 - 自定义的 bridge network 会有自己专属的一个网段,与其他 network 隔离。
- 可以通过
docker network connect
指令将容器连接到一个 network,也可以在起容器(docker run
指令)时加入--network
参数指定即将创建的容器加入到哪个 network,还可以通过docker network disconnect
命令将容器移出自定义的 network。 - 加入到同一个自定义 bridge network 的容器间可以通过容器名(充当 hostname)进行通信,会自动进行 DNS 解析。也可以通过 IP 进行通信,因为属于同一个网段。
- 同一个容器可以同时加入到多个 network 下,此时该容器拥有多个虚拟网卡(可以通过 ifconfig 查看)。