是成对出现的虚拟网络设备,发送到Veth一端虚拟设备的请求会从另一端的虚拟设备中发出,在容器的虚拟化场景中,会使用Veth来链接不同网络的namespace
linux 提供了 veth pair 。可以把 veth pair 当做是双向的 pipe(管道),从一个方向发送的网络数据,可以直接被另外一端接收到;或者也可以想象成两个 namespace 直接通过一个特殊的虚拟网卡连接起来,可以直接通信。
lo
自身的回环设备
vxlan
什么是vxlan?
vxlan是一种网络虚拟化技术,通过把源主机发出的数据包封装在UDP中.并且使用物理网络的IP,MAC作为外层头进行封装,然后在IP网络上传输,到达目的地后由隧道终结点解封装并把数据发送给目标主机.
什么是隧道技术?
是一种数据包封装技术.可以把原始IP包封装在另外一个数据包的数据净荷中进行传输.
使用隧道的原因是在不兼容的网络上传输数据或者在不安全网络上提供一个安全路径.
veth pair只能实现两个网络接口之间的通信
如果实现多个网络接口之间的通信。就是Bridge网桥技术。简单说来,网桥就是把一台机器上的若干个网络接口连接起来。结果就是其中一个网口收到的报文会被转发到其他网口。实现了不同网络接口之间的报文相互转发
网桥对报文的转发基于MAC地址,网桥能够解析收发的报文,读取目标MAC地址的信息,然后根据自己的MAC表信息,来决定转发的目标网络端口
如果遇到一个从来没有记录过的地址,可以广播给所有的网络端口
Linux内核通过一个虚拟的网桥设备实现桥接,这个虚拟设备可以绑定若干个以太网接口设备,从而把他们连接起来
对于协议栈上层,只看得到br0,上层协议栈需要发送报文到br0种,网桥设备的处理代码再判断报文被转发到eth0或者是eth1.
反过来,从eth0或者eth1接收到的报文被提交给网桥的处理代码,也会在br0判断报文应该被转发丢弃还是提交到协议栈上层
容器直接使用宿主机的IP和端口.但是容器的文件系统,进程列表等还是和宿主机隔离
使用host模式的容器可以直接使用宿主机的IP地址和外界通信.容器内部的服务端口可以使用宿主机的端口,不需要进行NAT.host最大优势是网络性能比较好.
缺点: 端口没有做隔离,会有端口占用现象
指定新创建的容器和已经存在的一个容器共享一个Network Namespace.
新创建容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP,端口范围等
两个容器除了网络,其他如文件系统,进程列表还是隔离的
两个容器的进程通过lo网卡设备通信 (localhost)
网络模式下容器只有lo回环网络.这种网络没有办法联网,封闭网络能够很好保证容器的安全性.
在宿主机创建一个叫docker0的虚拟网桥.
宿主机上启动的Docker容器会连接到这个虚拟网桥上
这个虚拟网桥工作方式和物理交换机类似 主机所有容器通过交换机连在一个二层网络中
从docker0子网中分配一个IP给容器使用,并且设置docker0的IP地址作为容器的默认网关.在主机上创建一对虚拟网卡设备veth pair.
Docker把veth pair设备的一端放在新创建的容器中,命名为eth0
另外一端放在宿主机上,以vethxxx这样的方式命名.然后把这个网络设备加入到docker0网桥中.
bridge模式就是docker的默认网络模式.
约法三章:
四大目标:
搞清楚
本文解决后面两个问题
容器网络方案:
大体分为Underlay 和 Overlay两种方案
underlay
与host网络同层,与host网络使用同样的网段,输入输出基础设备,容器IP地址是不是需要与host网络取得协同.啥意思呢,就是ip地址是否由host网络来进行中心分配或者统一划分.
overlay
不一样的地方:并不需要从host网络的ipm的管理组件去申请IP
只需要与host网络不冲突,这个ip可以自由分配
总结: underlay和overlay区别在于容器网络是否与宿主机网络同层
Network Namespace
runC容器的技术不依赖于任何硬件,执行基础就在内核里面.进程内核代表就是task.
如果不需要隔离,那么用的主机空间就是主机的空间,不需要设置特别的空间隔离数据结构.
ipvs 是啥?iptables是啥?
ipvs运行在主机上,在真实的服务器集群中充当负载均衡器.
ipvs可以将基于TCP和UDP的服务请求转发到真实的服务器.使得真实服务器的服务在单个IP地址上显示为虚拟服务.
iptables不是防火墙.我们可以理解成一个客户端代理.用户通过iptables这个代理,把用户的安全设定执行到防火墙中
先回顾以下报文从网卡到
当客户端访问服务端的web服务的时候,客户端发送报文到网卡。
tcp/ip协议栈是内核的一部分,所以客户端的信息会通过内核的TCP协议传输到用户空间的web服务中。
这个时候客户端报文的终点为web服务监听的套接字。
我们所说的防火墙,是内核空间的一部分,所有进出报文都需要通过关卡。符合条件的关卡才可以放行。
这些关卡在iptables中称为"链"
上面那个是demo啦
当我们开启了防火墙功能的时候,报文需要经过以下关卡,也就是要根据实际情况不同,报文经过的转发链其实是不同的。
下图中红色的框就是“链”,链是因为每个关卡中所有规则都会串成一条链。
报文只有满足链上所有规则的时候才能通过这个关卡。
到本机某进程的报文: PREROUTING -> INPUT
由本机转发的报文: PREROUTING -> FORWARD -> POSTROUTING
由本机的某进程发出报文: OUTPUT->POSTROUTING
我们回到K8s网络的讨论
如果网络是需要隔离的话,并不需要特别设置空间隔离数据结构(nsproxy)
一个隔离的网络空间会有什么?
有自己的网卡或者是网络设备
网卡可能是虚拟的,也可能是物理网卡
拥有自己的IP地址,IP表和路由表
拥有自己的协议栈
拥有自己的status
拥有自己的iptables和ipvs
Pod和Netns的关系
每个Pod都有独立的网络空间。
所有容器都会通过pod的IP对外提供服务。
宿主机还有Root namespace,可以看作成一个特殊的网络空间,不过pid为1
上面解决的是容器的包如何到达host,这里通过加一个网桥Bridge.它的bckend其实是独立的,也就是这个包如何离开host,采用何种封装方法,或者是是否需要封装,都是可选择的。
提供基于策略的的网络控制,用来隔离应用并且减少攻击面。
使用Node Selector模拟传统的分段网络,并且通过策略控制他们之间的流量以及来自外部的流量,因为我们约法三章的时候提到Pod之间是可以实现全互联的。带来的问题是,在K8s集群中,可能希望某些Pod不能去访问其他的Pod,这个时候需要用到策略。
Network Policy需要决定:
流与端口
Network Policy之前,需要注意
下面我们着重解决文章开始提出的问题:
简而言之,container之间的默认网关都是Docker网桥,同一个宿主机内的容器都接入同一个网桥,那么容器之间可以通过容器的Container-IP直接通信
分为两类:同一个Node内的Pod之间的通信,和不同Node之间Pod的通信。
每个Pod都有一个真实的全局IP地址。
Pod1和Pod2都是通信veth pair连接到同一个docker0网桥上
它们的IP1,IP2都是通过docker0动态获取。他们和网桥本身的IP3是在同一个网段。
Pod1和Pod2处于同一个局域网,他们之间可以通过docker0作为路由来进行通信。
Pod之间假设通过访问对方的Pod IP进行通信。
不同Node之间的通信只能通过Node的物理网卡进行
Pod的IP地址由各个Node上的docker0网桥动态分配。
需要满足三个条件
对于第一个条件:K8s会记录Pod IP和Node IP之间的映射关系,信息保存在etcd中
对于第二个条件:以Flannel实现的容器跨主机通信为例,我们做解析
https://www.cnblogs.com/hongdada/p/9758939.html
K8s网络实现
https://www.jianshu.com/p/22a7032bb7bd