同一个主机上的Docker容器之间通信
docker 引擎会在主机上增加一个docker0网卡,该网卡具有双重身份:
1.从容器视角,网桥(交换机)身份
docker0 对于运行在同一个主机上的各个容器来说,是二层交换机的角色:洪范,维护CAM表,在二层转发数据包;同时,docker0 自身也具有MAC地址,并且绑定了IP,因此在容器中还可以作为默认网关存在。
2.从宿主机视角,网卡身份
物理交换机提供了由硬件实现的高效的背板通道,供连接在交换机上的主机高效实现二层通信;对于开启了三层协议的物理交换机而言,其ip路由的处理 也是由物理交换机管理程序提供的。对于docker0而言,其负责处理二层交换机逻辑以及三层的处理程序其实就是宿主机上的Linux内核 tcp/ip协议栈程序。而从宿主机来看,所有docker0从veth(只是个二层的存在,没有绑定ipv4地址)接收到的数据包都会被宿主机 看成从docker0这块网卡接收进来的数据包,尤其是在进入三层时,宿主机上的iptables就会 对docker0进来的数据包按照rules进行相应处理(通过一些内核网络设置也可以忽略docker0 brigde数据的处理)。
通过,docker0的网桥功能,可以实现在同一个主机上的各个容器之间的通信。
不同主机上的Docker容器之间通信
网上找到一些解决方案:
- 使用openvswitch 搭建 xvlan协议隧道
- 将多个物理机的容器组到一个物理网络,这需要在每台机器上创建自己的网桥br0,然后将docker默认网桥绑定到br0
- 使用docker的swarm集群
- 使用docker的overlay网络
swarm集群在上文中已经实现,这里实现方案4,使用docker的overlay网络。
准备
搭建环境:
(1)物理主机 dev-11 IP=162.10575.113, 上面运行docker容器 host1
(2)物理主机 dev-12 IP=162.105.75.220,上面运行docker容器 host2
1. 安装并配置consul
Consul
是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla
Public License 2.0 的协议进行开源. Consul 支持健康检查,并允许 HTTP 和 DNS 协议调用 API 存储键值对.
(1)直接从官网下载,并解压,将二进制文件拷贝到 /usr/local/bin 目录下即安装完成,同时创建新文件夹 /opt/consul 用于存放consul运行时产生的文件
(2)在dev-11机器上执行nohup consul agent -server -bootstrap -data-dir /opt/consul -bind=162.105.75.113 &
,将dev-11作为server节点
(3)在dev-12机器上执行nohup consul agent -data-dir /opt/consul -bind=162.105.75.220 &
,将dev-12作为client节点,然后 consul join dev-11
加入集群。
(4)分别在 dev-11和dev-12上执行,consul members
来查看集群中是否有两个主机。
[root@dev-12 skc]# consul members
Node Address Status Type Build Protocol DC
dev-11 162.105.75.113:8301 alive server 0.7.5 2 dc1
dev-12 162.105.75.220:8301 alive client 0.7.5 2 dc1
我在搭建的时候一直出现 500 错误,无法建成集群,最后发现是防火墙的原因。**centos 7 下默认防火墙为firewalld,且默认开机启动,一定要注意!**
2. 配置docker启动参数
在配置文件/lib/systemd/system/docker.service 中,
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=consul://localhost:8500 --cluster-advertise=eth0:2375
其中 cluster-store 的主机指定为localhost即可,cluster-advertise的ip可以指定为本机的网卡名。
3. 创建overlay网络
在dev-11上执行,docker network create -d overlay multihost
创建overlay类型网络multihost。然后
[root@dev-11 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
914e62484c33 bridge bridge local
018d41df39c5 docker_gwbridge bridge local
0edff5347b33 host host local
e7b16dd58248 multihost overlay global
1d25e019c111 none null local
说明网络建立成功
此时,在dev-12机器上,
[root@dev-12 skc]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7af47cbb82c8 bridge bridge local
30911dfed7f2 docker_gwbridge bridge local
6e6deb4077c4 host host local
e7b16dd58248 multihost overlay global
dc7f861e601a none null local
说明overlay网络被同步过去了。
4. 创建容器并测试
[root@dev-11 skc]# docker run -it --name=host1 --net=multihost debugman007/ubt14-ssh:v1 bash
[root@dev-12 skc]# docker run -it --name=host2 --net=multihost debugman007/ubt14-ssh:v1 bash
在host1中,
root@d19636118ead:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0a:00:00:02
inet addr:10.0.0.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:aff:fe00:2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:24 errors:0 dropped:0 overruns:0 frame:0
TX packets:25 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1904 (1.9 KB) TX bytes:2122 (2.1 KB)
eth1 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1018 (1.0 KB) TX bytes:868 (868.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:970 (970.0 B) TX bytes:970 (970.0 B)
在host2中
root@7bd8ff1ab133:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0a:00:00:03
inet addr:10.0.0.3 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:aff:fe00:3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:25 errors:0 dropped:0 overruns:0 frame:0
TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1966 (1.9 KB) TX bytes:1850 (1.8 KB)
eth1 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:22 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2412 (2.4 KB) TX bytes:648 (648.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:934 (934.0 B) TX bytes:934 (934.0 B)
此时,在host1中ping host2
root@d19636118ead:/# ping host1
PING host1 (10.0.0.2) 56(84) bytes of data.
64 bytes from d19636118ead (10.0.0.2): icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from d19636118ead (10.0.0.2): icmp_seq=2 ttl=64 time=0.057 ms
^C
--- host1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.047/0.052/0.057/0.005 ms
root@d19636118ead:/# ping host2
PING host2 (10.0.0.3) 56(84) bytes of data.
64 bytes from host2.multihost (10.0.0.3): icmp_seq=1 ttl=64 time=0.917 ms
64 bytes from host2.multihost (10.0.0.3): icmp_seq=2 ttl=64 time=0.975 ms
64 bytes from host2.multihost (10.0.0.3): icmp_seq=3 ttl=64 time=0.935 ms
^C
--- host2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 0.917/0.942/0.975/0.034 ms
能够ping通,说明跨主机的容器搭建完成。
参考
理解Docker单机容器网络
理解Docker跨多主机容器网络
基于consul的Docker-overlay跨多宿主机容器网络