7.1 Docker 网络配置-容器间通信
在早期的Docker版本及介绍中,通常采用 --link 参数使容器互联。如果N个容器彼此通信, 如此配置是令人崩溃的。
随着Docker版本的提升,强烈建议大家通过自定义 docker bridge(自定义) 网桥来连接多个容器, 摈弃 --link 参数
演示环境
Linux系统:Ubuntu 16.04
docker版本:18.09.5
演示目标: 启动两个容器,分别是CTN1,CTN2. 直接通过容器名(或hostname)相互通信.
互联原理
bridge网络
docker的桥接网络使用虚拟网桥,bridge网络用于同一主机上的docker容器相互通信,连接到同一个网桥的docker容器可以相互通信
默认网桥Docker0
默下启动docker之后会创建一个名为 docker0的网桥,新创建的容器都会自动连接到该网桥,但默认网桥具有一定缺陷
- 默认桥接网络中的容器只能通过IP地址访问其他容器(除非使用遗留的-link指令连接两个容器),而容器的IP创建前并不确定,为我们部署系统造成很大障碍(如服务的注册与发现,gateway的基本设置)
- 由于默认桥接网络只有一个,因此所有容器的网络配置都是一样的.
自定义网络
- 自定义桥接网络提供DNS解析,可以通过容器的名字或是别名访问其他容器
- 用户自定义网络可以在创建时指定网络配置(例如默认网关、MTU等),不需要重启docker,灵活性更高
- 多个容器可以使用同一个docker-compose(与docker service有关)文件启动 ,可以在该文件中定义共享环境变量
操作思路
- 新建网络
针对这组容器创建一个专属网络CTN-NET
$ docker network create -d bridge CTN-NET
验证该网络已创建
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
0114a94dbb98 CTN-NET bridge local
ef2bf4b9d358 bridge bridge local
7498c737475f host host local
2281172e376b none null local
- 连接容器入网
运行一个容器并连接到新建的 CTN-NET 网络
$ docker run -it --rm --name CTN1 --network CTN-NET tomcat sh
打开新的终端,再运行一个容器并加入到 CTN-NET 网络
$ docker run -it --rm --name CTN2 --network CTN-NET tomcat sh
通过 ping 来证明 CTN1 容器和 CTN2 容器建立了互联关系。
- 通信验证
在CTN1容器中Ping CTN2,成功
# ping CTN2
PING CTN2 (172.20.0.3) 56(84) bytes of data.
64 bytes from CTN2.CTN-NET (172.20.0.3): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from CTN2.CTN-NET (172.20.0.3): icmp_seq=2 ttl=64 time=0.076 ms
在CTN2容器中Ping CTN1,成功
# ping CTN1
PING CTN1 (172.20.0.2) 56(84) bytes of data.
64 bytes from CTN1.CTN-NET (172.20.0.2): icmp_seq=1 ttl=64 time=0.145 ms
64 bytes from CTN1.CTN-NET (172.20.0.2): icmp_seq=2 ttl=64 time=0.082 ms
这样,CTN1 容器和 CTN2 容器建立了互联关系.
如果你有多个容器之间需要互相连接,推荐使用 Docker Compose
Docker Compose的网桥设置
- 默认网桥
Docker compose 会默认创建一个网桥, 该网桥中的每个容器服务可以相互通信, hostname同容器名
services:
CTN1:
build: ./
container_name: CTN1
image: tomcat:latest
ports:
- 9010:8080
hostname: CTN1 #自定义该容器的hostname,全网桥有效
CTN2:
build: ./
container_name: CTN2
image: tomcat:latest
ports:
- 9020:8080
hostname: CTN2
Note:默认创建的网桥名称取决于docker-compose.yml放置的文件夹名称,例如 CTN/docker-compose.xml ,则默认网桥 CTN_default 将被创建.
CTN1,CTN2会默认加入该网桥
- 自定义网桥
自定义网桥具备更大的灵活性, 你可以为容器服务指定已经创建的外部网桥.
version: "3"
services:
CTN1:
build: ./
container_name: CTN1
networks:
- mynet
image: tomcat:latest
ports:
- 9010:8080
hostname: tomcat-one
CTN2:
build: ./
container_name: CTN2
networks:
- mynet
image: tomcat:latest
ports:
- 9020:8080
hostname: CTN2
networks:
mynet:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"