docker overlay网络拓扑及服务注册问题

跨主机docker网络有多种方案,如overlay、flannel、calico、weave等,其中overlay是docker原生的跨主机网络方案。最近使用overlay方案部署容器集群,在进行服务注册时遇到问题,需要手动创建veth设备解决。

1. overlay网络拓扑


overlay网络中,docker会为每一个overlay网络创建一个独立的network namespace,即上图中的net1和net2。每个namespace中都有一个linux bridge br0,docker容器与br0之间通过veth pair连接,一端为容器中的eth0,另一端通过namespace中的veth接口连接到br0。br0还连接了vxlan1,通过vxlan隧道实现跨主机容器通信。

br0没有与宿主机namespace中的接口相连,因此容器无法通过eth0与主机通信。在overlay网络中,为了实现容器与主机之间的通信,在宿主机namespace中创建了linux bridge docker_gwbridge。所有容器都通过veth pair连接到该网桥中。上图中,容器可以通过eth1与宿主机通信。eth1接口仅用于容器与宿主机通信,即使位于同一个overlay网络中的容器间,也无法通过eth1接口通信。


2. 服务注册问题


最近,使用overlay网络部署容器集群后,需要将容器的IP地址和端口注册到api网关中,api网关将容器提供的服务进行映射,对外暴露统一的IP地址。有两种使用场景:

a) 集群外部通过api网关查询服务,通过映射后的地址和端口号访问

b) 集群内部通过api网关查询服务,可通过映射后的地址和端口号访问,也可直接选择容器的地址和端口号访问

在以上的应用场景中,通过映射后的地址和端口号服务,访问服务时需要经过api网关,再到达容器。在我的集群中,api网关使用host方式部署,与提供服务的容器之间通过eth1接口进行通信,容器向api网关注册时,服务的IP地址必须为eth1的IP地址,才能保证通过api网关顺利转发。但这时,集群内访问时,查询到的容器IP是eth1的IP地址,无法直接访问。如果注册时服务的IP采用eth0的IP,则无法通过api网关转发。
为了解决以上问题,我通过vethpair设备将overlay网络直接与宿主机相连通。这样,将eth0的IP注册到api网关,同样能通过api网关进行转发。具体步骤如下:

  创建vethpair设备:
      ip link add vethhost type veth peer name gw_api:
  将vethpair的vethhost一端连接到overlay网络的namespace中,namespace可在/var/run/netns中找到,横线后为overlay网络的ID(cae3e00181)
      ip link set vethhost netns 1-cae3e00181
  将vethhost端接入br0网桥:
      ip netns exec 1-cae3e00181 brctl addif br0 vethhost
  设置vethhost端mtu并up:
      ip netns exec 1-cae3e00181 ifconfig vethhost mtu 1450 up
  设置gw_api端mtu和IP地址(overlay网络同网段IP)
      ifconfig gw_api mtu 1450 193.168.120.1/16

经过上述设置,容器与api网关的网络拓扑如下(省略了net2):

由于apigateway使用宿主机网络,可以通过gw_api接口与overlay网络net1通信。

在这一解决方法中,我修改了overlay网络的拓扑。暂时没有考虑其他几种跨主机容器网络方案能不能避免该问题,等有时间研究一下k8s的网络方案,或许会有更多收获。

猜你喜欢

转载自www.cnblogs.com/doujianli/p/9939611.html