使用host-gw实现跨主机容器间通信

Kubernetes网络插件中,flannel也是比较受欢迎的一款。Flannel有多种不同的backend,典型的是VXLAN和host-gw。Vxlan利用内核的特性对包进行封装,不依赖特定的网络环境;host-gw直接利用物理网络,性能较好,但对网络有特殊要求。

Flannel官网对host-gw介绍不多,本文主要介绍如何通过手动配置host-gw网络,以探究host-gw工作原理。

测试环境使用两台虚拟机,使用virsh创建的kvm虚拟机,默认网桥virbr0,没有自定义配置。此文创建虚拟机略,虚拟机创建后的地址如下:

  • docker1: 192.168.122.174
  • docker2: 192.168.122.96

两台虚拟机按照官方文档安装docker,此处按照步骤略,增加配置(/etc/docker/daemon.json)如下:
docker1:

1
2
3
{
"bip": "172.16.10.1/24"
}

docker2:

1
2
3
{
"bip": "172.16.20.1/24"
}

这个配置是设置单机docker容器的子网(docker0网桥),避免网络产生冲突,其他docker配置使用默认。

查看服务器转发是否开启(安装完docker此项一般都有开启):

1
cat /proc/sys/net/ipv4/ip_forward

在服务器docker1上增加如下路由,目的地址为172.16.20.0/24的包发往192.168.122.96,即docker2:

1
ip route add 172.16.20.0/24 via 192.168.122.96 dev eth0

同样,在服务器docker2上增加如下路由:

1
ip route add 172.16.10.0/24 via 192.168.122.174 dev eth0

在两台服务器上分别创建容器,在服务器docker1上执行:

1
2
docker create --name nginx1 nginx:latest
docker start nginx1

在服务器docker2上执行:

1
2
docker create --name nginx2 nginx:latest
docker start nginx2

由于使用的是虚拟机,虚拟机docker1和docker2通过网桥virbr0连接,这时登陆容器nginx2去ping nginx1仍是不通的:

1
docker exec -it nginx2 /bin/bash

经过分析,在宿主机上增加如下路由,nginx1到nginx2的网络可以正常通信了:

1
2
ip route add 172.16.10.0/24 via 192.168.122.174 dev virbr0
ip route add 172.16.20.0/24 via 192.168.122.96 dev virbr0

下图为主机内的网络拓扑图:

从上文路由的设置看,此种网络结构是有一定局限性,容器所在主机需要在同一个网段。

参考