RedHat Openshift 3.9 网络流量模型简析

 

我们知道Kubernetes的网络插件多种多样,常见的有Calico、Fannel、Weave等,这些网络插件的核心思想主要解决跨宿主机之间Pod的通信,近期,在对RedHat Openshift 3版本进行学习的时候,大致谅解了下其网络实现方案,今天就跟大家做一个分享,若有不正确的地方,望各位指正。

一、实验环境介绍

首先介绍下实验环境(图1所示),我们通过ansible脚本部署了一套openshift,其中包括三个节点,一个Master节点和两个Node节点,这三个节点通过172.25.250.0/24这个网络连接起来,部署完成后,我们可以通过oc命令查看node的情况(图2所示),可以看到openshift 3.9是基于k8s 1.9.1版本实现的。

RedHat Openshift 3.9 网络流量模型简析_第1张图片 图1

 

图2

二、观察各节点关于网络的配置和设备

    通过oc get pods命令,我们可以到在default的project中,openshift为我们创建了两个router(图3所示),这两个router被调度在Node1和Node2上面,并且这两个router的IP为宿主机的物理IP地址,router在openshift中是用于外部网络访问集群服务(openshift中有专门的route资源定义),类似于kubernetes中的Ingress,router本生是通过HaProxy来实现的,这一点我们可以通过进入router容器来确认(如图4所示)

图3 图4

 我们再来看看Master节点、两个Node节点的网络设备有什么变化,我们在node1上执行ip addr(图5),可以看到Openshift为每个宿主机节点创建了一些网络设备。其中docker0是docker默认创建的网桥,但是在Openshift中并没有进行使用,另外比较重要的我们可以看到,openshift为我们创建了一个名为br0的ovs,有此我们知道openshift网络模型主要是通过ovs来实现的。接下来我们仔细看下ovs的详细信息。

 

RedHat Openshift 3.9 网络流量模型简析_第2张图片 图5

 我们通过ovs-vsctl show br0 --protocols=OpenFlow13 来查看br0的详细信息(图6),其中--protocols用于制定openflow版本信息,可以看到ovs上有许多端口,其中veth这种类型的端口属于veth pair,用于连接pod和ovs,vxlan0是用于连接不通宿主机之间的端口,后面可以看到openshift跨宿主机POD之间的通信是通过相同的vxlan隧道连接起来的,Tun0设备被设置为当前宿主机Pod网段的网关,用于Pod与集群外部网络进行通信。

RedHat Openshift 3.9 网络流量模型简析_第3张图片 图6

 我们在来看下ovs内部的流表(图7),由于流表很复杂,我们这里借助另一篇文章中梳理出来的内容,对ovs的转发过程进行大致的了解。

RedHat Openshift 3.9 网络流量模型简析_第4张图片 图7

 流量规则表(图8)(引用地址:https://www.cnblogs.com/sammyliu/p/10064450.html):

table 0: 根据输入端口(in_port)做入口分流,来自VXLAN隧道的流量转到表10并将其VXLAN VNI 保存到 OVS 中供后续使用,从tun0过阿里的(来自本节点或进本节点来做转发的)流量分流到表30,将剩下的即本节点的容器(来自veth***)发出的流量转到表20;

table 10: 做入口合法性检查,如果隧道的远端IP(tun_src)是某集群节点的IP,就认为是合法,继续转到table 30去处理;

table 20: 做入口合法性检查,如果数据包的源IP(nw_src)与来源端口(in_port)相符,就认为是合法的,设置源项目标记,继续转到table 30去处理;如果不一致,即可能存在ARP/IP欺诈,则认为这样的的数据包是非法的;

table 30: 数据包的目的(目的IP或ARP请求的IP)做转发分流,分别转到table 40~70 去处理;

table 40: 本地ARP的转发处理,根据ARP请求的IP地址,从对应的端口(veth)发出;

table 50: 远端ARP的转发处理,根据ARP请求的IP地址,设置VXLAN隧道远端IP,并从隧道发出;

table 60: Service的转发处理,根据目标Service,设置目标项目标记和转发出口标记,转发到table 80去处理;

table 70: 对访问本地容器的包,做本地IP的转发处理,根据目标IP,设置目标项目标记和转发出口标记,转发到table 80去处理;

table 80: 做本地的IP包转出合法性检查,检查源项目标记和目标项目标记是否匹配,或者目标项目是否是公开的,如果满足则转发;(这里实现了 OpenShift 网络层面的多租户隔离机制,实际上是根据项目/project 进行隔离,因为每个项目都会被分配一个 VXLAN VNI,table 80 只有在网络包的VNI和端口的VNI tag 相同才会对网络包进行转发)

table 90: 对访问远端容器的包,做远端IP包转发“寻址”,根据目标IP,设置VXLAN隧道远端IP,并从隧道发出;

table 100: 做出外网的转出处理,将数据包从tun0发出。

RedHat Openshift 3.9 网络流量模型简析_第5张图片 图8

 

三、流量模型分析

 基于上面观察的结果,我们大致可以画出叠加了网络设备的示意图(图9):

RedHat Openshift 3.9 网络流量模型简析_第6张图片 图9

 

如上图所示,每个节点都有一个ovs,pod通过veth pair设备连接到ovs,ovs中通过流表来控制数据包的转发。

(1) 宿主机内Pod通信

宿主机内相同project下Pod通信只需要通过ovs即可完成(图10)

RedHat Openshift 3.9 网络流量模型简析_第7张图片 图10

 

(2) 跨宿主机Pod通信

Pod将数据包发送给ovs,ovs通过流表规则通过vxlan0对数据包进行封装,目标地址为其它node的物理IP,通过underlay网络将数据包送到目标的node,目标node通过解封vxlan头部并将数据包交给ovs,由ovs将数据包转发到目标Pod(图11)

RedHat Openshift 3.9 网络流量模型简析_第8张图片 图11

 

(3) 外部网络访问集群内提供的服务

    集群内部提供的服务会通过haproxy来对外暴露,由于haproxy的地址就是宿主机的IP地址,所以可以被外部网络所访问到,同时服务是通过域名的方式对外提供服务的,所以在做DNS解析的时候,只要DNS能够解析到任意一台具有haproxy的宿主机即可,如下图所示,用户访问到test.example.com后,通过DNS解析到node1的IP地址,haproxy收到请求后查询后端配置,并转发到Pod的IP地址上,数据包通过先转发到tun0上,再由ovs将数据包转发到相应的pod上面。(图12)

       另外需要补充的是haproxy是通过服务的svc地址查询到pod的地址,并配置到haproxy中。

RedHat Openshift 3.9 网络流量模型简析_第9张图片 图12

 

(4) Pod访问外部网络

Pod访问外部网络会很简单,Pod将数据包送到tun0(网关),并通过SNAT将进行地址转换,从而访问外部网络。(图13)

RedHat Openshift 3.9 网络流量模型简析_第10张图片 图13

 

参考文章:

     https://www.cnblogs.com/sammyliu/p/10064450.html

 

你可能感兴趣的:(kubernetes学习,openshift,kubernetes,openshift,流量模型,k8s)