
Kubernetes网络模型
三种网络模型
在k8s中一般常见的网络模型支持三种,虚拟网桥、多路复用和硬件交换。
虚拟网桥
创建一个虚拟网卡对(veth pair),一头插在容器里面,一头插在宿主机的root namespace内。这样一来,容器内发出的网络数据包,可以通过网桥进入宿主机网络栈,而发往容器的数据包也可以经过网桥进入容器。
多路复用
使用一个中间网络设备,暴露多个虚拟网卡接口,容器网卡都可以接入这个中间设备,并通过mac地址/IP地址来区分packet应该转发给哪一个容器设备。
(我的简单理解:两个网关,一个是宿主机本身,一个是在容器里面跑一个。由于容器是应用网关设备,会导致用户态到内核态的两次调用,导致性能不佳。
如果回答有误,欢迎评论区留言!)
硬件交换
还有个比较直接的方法就是为每个Pod分配虚拟网卡,这样一来,Pod与Pod之间的连接关系就会变得非常清晰,因为近乎物理机之间的通信基础,如今大多数网卡都支持SR-IOV功能,该功能将单一的物理网卡虚拟成多个VF接口,每个1VF接口都有单独的虚拟PCIE通道,这些虚拟的PCIE通道共用物理网卡的PCIE通道。
虚拟网桥
我们需要通过如下命令来安装虚拟网桥的ctl
yum install -y brctl
安装完成后可以通过brctl show
查看所有的虚拟网桥。这里我们发现有docker0
与virbr0
两个桥接网络。
然后我们通过运行容器,发现在docker0
中添加了一个虚拟的网卡,而这网卡也是对应到我们容器中连接的网卡。
docker run -d nginx:alpine
brctl show
Kubernetes Network IPVLAN L2
ipvlan L2 模式和macvlan bridge 模式工作原理很相似,父接口作为交换机来转发子接口的数据。同一个网络的子接口可以通过父接口来转发数据,而如果想发送到其他网络,报文则会通过父接口的路由转发出去。
通过上面的图来创建对应的ipvlan L2,先创建网络空间 net1 与 net2
ip netns list
ip netns add net1
ip netns add net2
ip netns list
首先查看父接口是哪个(我这里是ens32,你们可能是ens33),然后再创建对应的ipvlan子接口(ipvlan1,ipvlan2)。
ip link add ipvlan1 link ens32 type ipvlan mode l2
ip link add ipvlan2 link ens32 type ipvlan mode l2
关联ipvlan与vm上的网络空间
ip link set ipvlan1 netns net1
ip link set ipvlan2 netns net2
设置ip我这里分别是192.168.163.135
与192.168.163.136
,并查看网络空间的设置情况
ip netns exec net1 ifconfig ipvlan1 192.168.163.135/24 up
ip netns exec net2 ifconfig ipvlan2 192.168.163.136/24 up
ip netns exec net1 ifconfig -a
ip netns exec net2 ifconfig -a
如果出现问题:RTNETLINK answers: Operation not supported
请务必升级内核,请参考https://www.tnblog.net/hb/article/details/6220
测试二则互相访问的情况,从net1访问net2,我们发现是没有问题的
ip netns exec net1 ping 192.168.163.136
但是我们从net1访问到父接口(192.168.163.130
)是ping不通的。因为从上面的图片中,我们发现net1与net2的mac地址是相同的,当我们发出去的时候是没有问题的但当这个数据要返回时,交换机不知道把包返回发给谁。
我们从net1访问网关是能ping通的
# 查看路由(网关)
route -n
# ping 父接口的网关
ip netns exec net1 ping 192.168.163.2
我们通过net1来访问一下电信的DNS114.114.114.114
,它说网络不可达。
原因是:因为net网络里面没有114.114.114.114
的路由所以访问不了,我们通过添加路由来解决这个问题。
# 添加从默认网关的出口
ip netns exec net1 route add -net 0.0.0.0/0 gw 192.168.163.2
ip netns exec net1 ping 114.114.114.114
Kubernetes Network IPVLAN L3
路由器(Route)
路由器主要是实现不同网段的互联互通。
结合下图的意义就是:让192.168.1.1
与192.168.2.1
网段实现互联互通。
IPVLAN L3
ipvlan 有点像路由器的功能,它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同,即使虚拟机/容器不在同一个网络,也可以互相ping通对方因为ipvlan会在中间做报文的转发工作。
接下来根据上面的图来进行,先删除原有的网络空间,执行如下命令:
ip netns delete net1
ip netns delete net2
接下来的步骤与二相似
# 创建网络空间
ip netns add net1
ip netns add net2
# 创建子接口
ip link add ipvlan1 link ens32 type ipvlan mode l3
ip link add ipvlan2 link ens32 type ipvlan mode l3
# 关联ipvlan l3与vm上的网络空间
ip link set ipvlan1 netns net1
ip link set ipvlan2 netns net2
# 设置不同网段
ip netns exec net1 ifconfig ipvlan1 192.168.10.135/24 up
ip netns exec net2 ifconfig ipvlan2 192.168.20.136/24 up
# 测试一下二则是否ping得通
ip netns exec net1 ping 192.168.20.136
我们发现它并ping不通,因为网段不一样,而且我们来看看net1的路由信息。
我们会很轻容易的发现,它只有到192.168.10.0
的路由,并没有到192.168.20.0
的路由
从这里我们就发现一个ipvlan l3的缺陷:
路由器它是具有自己学习路由的能力的,比如自己找到哪些网段可以连接上。
而ipvlan l3 需要自己手动添加路由。
# net1添加192.168.20.0目的地,路由从ipvlan1子接口出去
ip netns exec net1 route add -net 192.168.20.0/24 dev ipvlan1
# net2添加192.168.10.0目的地,路由从ipvlan2子接口出去
ip netns exec net2 route add -net 192.168.10.0/24 dev ipvlan2
最后我们再来测试一下是否ping得通。
ENSP模拟路由器(Route)
IPVLAN L3与传统的路由不一样,在传统的路由器中它将会自动学习。
接下来我们来使用ENSP来模拟一下。
首先我们在ensp上添加一个AR1220
的路由器,和两个PC。我们先配置PC4,IP为192.168.1.10
,子网掩码255.255.255.0
,网关为192.168.1.1
,如下图所示。PC5也差不多只不过第三段的位为2
。
所以0/0/0
的接口对应的是192.168.2.10
PC4.0/0/1
的接口对应的是192.168.2.10
PC4.
我们来查看路由表,它们每个接口是否有配置,通过如下命令进行查看。
system-view
# PC4的接口
interface G0/0/0
ip a 192.168.1.1 24
# 查看接口ip与子网掩码
dis this
interface G0/0/1
ip a 192.168.2.1 24
# 查看接口ip与子网掩码
dis this
# 查看所有的
dis ip int b
#退出当前网络接口
q
#查看路由表
dis ip routing-table
我们可以看到路由表中有学习到他们的IP,尝试ping是没有任何问题的。
Kubernetes Network MACVLAN
MAVLAN通过一个简单的网桥连接父接口上的所有子接口。从一个接口到另一个接口的帧直接传递,而不是发送出去。广播帧被淹没到所有其他网桥端口和外部接口,但当它们从VEP交换机返回时,它们被丢弃。由于所有MAVLAN子接口MAC地址都是已知的,所以MAVLAN网桥模式不需要MAC学习,也不需要STP。网桥模式提供了虚拟机之间最快的通信.
但有一个缺陷,您应该注意——如果父接口状态挂掉了,所有MAVLAN子接口也会挂掉。当物理接口断开时,虚拟机将无法相互通信。
首先清空两个网络空间,然后开启ens32的混杂模式,然后创建两个网络空间。…
ifconfig ens32 promisc
ip netns list
ip netns add net1
ip netns add net2
ip netns list
ip link add link ens32 name macv1 type macvlan mode bridge
ip link add link ens32 name macv2 type macvlan mode bridge
ip link set macv1 netns net1
ip link set macv2 netns net2
ip netns exec net1 ifconfig macv1 192.168.163.135/24 up
ip netns exec net2 ifconfig macv2 192.168.163.136/24 up
我们来看看它们的mac地址与ip情况,我们会发现它们每一个mac都不一样。
ip netns exec net1 ifconfig
ip netns exec net2 ifconfig
测试请求访问。没有问题
DANM
DANM是针对在 Kubernetes 集群中运行的电信工作负载的网络解决方案。它由以下组件构成:
1.一个 CNI 插件,能够提供具有高级功能的 IPVLAN 接口
2.一个内置的 IPAM 模块,能够管理多个集群范围的不连续 L3 网络,并按需提供动态、静态或无 IP 分配方案
3.一个 CNI 元插件,能够通过其自己的 CNI 或通过将作业委托给任何流行的 CNI 解决方案(如 SRI-OV 或 Flannel 并行)将多个网络接口附加到容器
4.一个 Kubernetes 控制器,能够集中管理所有 Kubernetes 主机的 VxLAN 和 VLAN 接口
5.另一个 Kubernetes 控制器扩展了 Kubernetes 的基于服务的服务发现概念,以在 Pod 的所有网络接口上工作
有了这个工具集,DANM 能够提供多个独立的网络接口,可以为 Pod 使用不同的网络后端和高级 IPAM 功能。
简单来讲:一个pod的容器里面可以有多个网络接口与网卡的关联,这样使得更多CNI插件可以共同管理与关联,且互不影响。并且所链接的网络模式可以是L3,L2等模式。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

