容器之间可以通过IP Docker DNS Server 或joined容器三种方式通信
从前面的例子可以得出一个结论:两个容器要能通信,必须有属于同一个网络的网卡 具体做法就是在容器创建的时候通过 --network 指定相应的网络 或者通过docker network connect 将现有的容器加入到指定的网络 #参考之前的rhel7-up和busybox的例子
##连接到网络 docekr network connect my-net my-nginx 将一个容器的容器 my-nginx连接到一个正在运行的网络 my-net上 #容器脱离网络 docker network disconnect my-net my-nginx 将容器my-nginx从网络my-net上断开连接。通过IP访问容器虽然满足了通信的需求,但是还是不够灵活,因为在部署应用之前可能无法确定IP 部署之后再指定要访问的IP会比较麻烦 对于这个问题,可以通过docker 自带的DNS服务解决 从docker1.10版本开始,docker daemon实现了一个内嵌的DNS server,使容器可以直接通过“容器名”通信,方法很简单,只要在启动时用 --name为容器命名就可以了 bridge模式
[root@server7 ~]# docker run -it --network=my_net2 --name=bbox1 busybox / # ping bbox2 PING bbox2 (172.22.16.3): 56 data bytes 64 bytes from 172.22.16.3: seq=0 ttl=64 time=0.041 ms 64 bytes from 172.22.16.3: seq=1 ttl=64 time=0.047 ms ^C --- bbox2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.041/0.044/0.047 ms [root@server7 ~]# docker run -it --network=my_net2 --name=bbox2 busybox / # ping bbox1 PING bbox1 (172.22.16.2): 56 data bytes 64 bytes from 172.22.16.2: seq=0 ttl=64 time=0.057 ms 64 bytes from 172.22.16.2: seq=1 ttl=64 time=0.049 ms ^C --- bbox1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.049/0.053/0.057 ms # 使用docker DNS有个限制:只能在user-defined网络中使用 也就是说默认的bridge网络是无法使用DNS的 [root@server7 ~]# docker run -it --name=bbox3 busybox/ # [root@server7 ~]# docker run -it --name=bbox4 busybox / # ping bbox3 ^C / # ping bbox3 ping: bad address 'bbox3'另一种实现容器间通信的方式 joined容器非常特别,它可以使两个或多个容器共享一个网络栈 共享网卡和配置信息,joined容器之间可以通过127.0.0.1 直接通信
先创建一个rhel7-up容器 名字为server1 [root@server7 ~]# docker run -it --name=server1 rhel7-up /bin/bash bash-4.2# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 48: eth0@if49: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever 然后创建busybox容器并通过 --network=container:server1 指定joined容器为server1 [root@server7 ~]# docker run -it --network=container:server1 busybox / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 48: eth0@if49: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever #busybox和web1的网卡mac地址与IP完全一样,它们共享了相同的网络栈 busybox可以直接用127.0.0.1访问server1 """ joined容器非常适合以下场景 1.不同容器中的程序希望通过loopback高效地通信 比如web server 与 App Server 2.希望监控其他容器的网络流量 比如运行在独立容器中的网络监控 """