kubernetes网络 – 集群网络原理分析

vxlan网络 vxlan是一种基于3层网络实现的2层overlay网络。vxlan网络可以使用VNI划分出多个彼此隔离的网络,可应用于多租户场景。 vxlan可以结合bridge一起来使用,相当于使用vxlan将多个主机上的bridge连接起来形成一个大的逻辑上的bridge设备。也可以不使用bridge,而是结合路由使用。下图是结合路由或bridge使用的场景示例: 在kubernetes环境中,可以使用简单的路由方式。内核在vxlan数据包解包后将原始二层数据给到了vxlan设备去接收,vxlan设备将数据包送入到上层网络协议栈。网络协议栈根据主机上的路由表配置,将包发给相应pod的网卡。 在这种路由模式下,节点上不需要知道其他所有pod的mac地址,只需要节点上对应的网关的地址的mac。数据包通过vxlan设备发送和接收的大致流程如下: 数据发送: 数据包从pod1发出,进入peer网卡的接收队列,然后到达node1的协议栈,经过路由判决,走node1的forward链。 forward时,要去的pod2的IP为172.16.2.1,主机路由匹配到应该走vxlan设备,下一跳为172.16.2.0。 数据包到达vxlan设备,查询路由表得知网关地址为172.16.2.0,于是通过arp协议查找网关的mac地址,在arp表中找到了匹配的记录后完成mac头封装,准备发送。 vxlan设备发送数据包并不是提交到发送队列,而是调用udp隧道相关接口将数据包封装成一个udp数据包,接着会查询fdb表查找要将数据从那个VTEP接口发出,经过查找后得到的VTEP接口为192.168.56.2,从而将数据包发送node2节点 。 数据接收: node2接收后,走主机协议栈,判断这是发往本机的udp包,于是走INPUT方向,最终发到UDP隧道层处理。 当创建vxlan创建udp隧道时,会将其接收数据包方法覆盖为vxlan的接收方法,所以在收到vxlan的UDP数据包后,进行对vxlan包解包,之后调用网卡的接收数据包方法进行接收原始二层数据包,此时如果vxlan设备被加入到了bridge设备,那么这个数据包会由bridge设备收到,bridge设备决定进行二层抓发或是送入上层网络协议栈。如果没有加入bridge中,那么如果目的mac地址是自己的也会送入上层网络协议栈。 进入上层网络协议栈后,就会根据主机的路由判断是入站还是转发,发现目标地址是172.16.2.1,经过路由判决时,发现不是本机地址,进行转发,找到相应的路由通过veth-pairhost端发出,从而进入pod。 下面,我们通过一些列命令手动创建和管理vxlan设备,进行测试vxlan相关功能,此处我们采用纯路由方式。 首先在第一台主机上先创建vxlan设备,配置路由: set -ux sysctl -w net.ipv4.ip_forward=1 sysctl -w net.ipv4.conf.all.proxy_arp=1 sysctl -w net.ipv4.conf.all.rp_filter=0 iptables -A FORWARD -d 172.16.0.0/16 -j ACCEPT iptables -A FORWARD -s 172.16.0.0/16 -j ACCEPT ​ ip link add vxlan.1 type vxlan vni 1 ip link set vxlan.1 up ip addr add 172.16.1.0/32 dev vxlan.1 ip route add 172.16.2.0/24 via 172.16.2.0 dev vxlan.1…

kubernetes网络 – kube-proxy详解

kube-proxy是kubernetes中网络核心组件,实现了服务暴露和转发等网络功能。如前面章节讲到,kube-proxy支持用户空间模式,ipvs和iptables三种代理模式。用户空间模式性能问题较严重,基本不再使用,应用最多的是iptables和ipvs模式。如果启动时不指定具体使用哪种模式,当前版本kube-proxy会优先使用iptables模式,如果探测到系统不支持则回滚到用户空间模式。当然,如果指定了ipvs模式,但是系统不支持的话也会回滚到iptables模式。 kube-proxy通过apiserver监听service和endpoint资源的变化,并动态更新网络配置规则。当前iptables应该是应用较多的模式,因此本节主要针对iptables规则进行分析。对于ipvs模式来说也并不是不需要iptables规则,在下列情况的时候还是会依赖iptables的规则实现相关功能:参考这里。在本节对iptables规则进行分析之后,可以按照这种方式再去分析ipvs相关规则配置,在分析ipvs规则时也需要要求我们熟悉ipvs和ipset等。 在kubernetes网络中,还有其他网络插件实现了和kube-proxy相同的功能,若kube-router,cilium,他们都支持kube-proxy实现的功能,因此在使用上述网络插件时,集群里可以不部署kube-proxy。 kube-proxy在同步iptables规则时是通过iptables-save方式获取当前的规则,然后根据集群内的service状态动态对已有规则进行更新,最后使用iptables-save将规则在配置到系统上。kube-proxy重启不会影响到新建链接和已有链接的状态。在删除已有service,kube-proxy还会释放相关的链接,以及对不同协议的额外处理操作,这里不做太多分析。 下面是一个固定nginx的service的来进行分析iptables规则。 [root@master1 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 172.17.0.1 <none> 443/TCP 79d nginx LoadBalancer 172.17.45.122 192.168.64.1,4.3.2.1 80:30935/TCP 3d5h [root@master1 ~]# kubectl edit svc nginx Edit cancelled, no changes made. [root@master1 ~]# kubectl get svc nginx -oyaml apiVersion: v1 kind: Service metadata: creationTimestamp: "2021-10-16T05:55:09Z" labels: app: nginx name: nginx namespace: default resourceVersion: "619828" uid: 58ad25b5-6ee0-4a10-8c60-3a4371db1bbc spec: clusterIP: 172.17.45.122 clusterIPs: - 172.17.45.122…

kubernetes网络 – iptables讲解

iptables命令用来管理ip数据包的过滤。iptables由命令行工具和一系列内核模块组成,iptables命令行工具用来管理规则配置,内核模块负责执行具体的规则。iptables内核模块依托于linux的netfilter网络框架,netfilter框架提供了一系列的网络钩子,ip数据包在经过网络协议栈的时候会触发这些钩子以执行注册到这些钩子上的函数。iptables内核模块会在这些钩子上注册处理函数来实现对ip数据包的过滤等。 netfilter中提供了ip钩子,ipv6钩子,arp钩子和bridge钩子等,都有对应的命令行工具和内核模块,如ip6tables,ebtables等,可以为不同网络层提供过滤功能,关于这些不同的功能,可以参考对应的文档查看。我们主要关心iptables,来看下netfilter中包含的ip钩子: NF_IP_PRE_ROUTING ip数据包达到网络协议栈后最先触发的是这个钩子,在还未执行路由决策之前触发。 NF_IP_LOCAL_IN 在linux对ip数据包执行了路由之后,如果目的地是给本地系统时触发。 NF_IP_FORWARD 在linux对ip数据包执行了路由之后,如果需要转发给其他主机时触发。 NF_IP_LOCAL_OUT 本地数据包将要从本地发出时触发。 NF_IP_POST_ROUTING 在任何本地发出的或本地进行转发的数据包将要在网络设备发发出时触发。 ip数据包在netfilter框架中会经过上面的钩子进行处理,iptables内核模块在这些钩子上注册了不同的处理函数,可以对数据包进行处理。iptables中包含这几种对数据包的处理功能: 包过滤,主要用来实现防火墙功能 包修改,修改数据包中的信息 网络地址转换,实现网络地址转换功能 表、链和目标 iptables中有不同类型的表:默认的filter表,nat表,mangle表raw表,每张表里存放不同类型的规则。 不同的表中还包含不同的链,可以是内置的链或用户自定义的链,内置的链包括:INPUT,PREROUTING,FORWARD,POSTROUTING,OUTPUT,这些是和netfilter中的钩子相对应的,是执行我们规则的入口。 每个链中又包含不同的规则,规则定义如何对数据包进行匹配,以及匹配之后要执行的目标动作,这些动作可以是跳转到用户的自定义链或者是内置的ACCEPT,DROP,RETURN,还可以是扩展模块中的,如REJECT,MARK等。这些目标可以分为终结和非终结型,终结型规则在执行完之后不会再匹配接下来规则,如ACCEPT,DROP,REJECT,MASQUERADE(nat的都是),而非终结类型再执行完当前规则后还会继续匹配后面的规则,如MARK,LOG。链中的规则匹配是按照顺序机型匹配执行的,如果当前规则不匹配则会一直匹配下一条规则,直到终结或匹配结束。 ACCEPT是允许数据包通过。DROP是丢弃数据包。RETURN是从当前链返回到调用该链的上层链中的下一条继续匹配。如果是内置链,则当匹配结束,或有规则使用了RETURN作为目标动作时,则使用这个内置链的策略决定是否允许通过。 关注Network Layer,以及注意图中包的路径,表的先后顺序。 命令行工具 iptables规则表,链和规则的关系为:table <-> chain -> rule。 指定表 -t, --table table 指定要操作的表,如果不指定这个参数则操作默认的filter表,针对所有命令生效。 默认策略 -P, --policy chain target 指定内置表的默认策略,target必须是ACCEPT或DROP。 链操作 -L, --list [chain]列出指定链内的规则,如果chain未指定,则列出该表下的所有规则。可以和-n选项结合使用,来讲ip地址和端口以数字形式显示。可以和--line-numbers结合使用,显示行号。 -S, --list-rules [chain]列出指定链内的规则,如果chain未指定,则列出该表下的所有规则。该命令以定义规则所使用的命令方式展示。 -F, --flush [chain]清空指定链内的规则(链仍然保留),如果chain未指定,则清空该表下的所有规则。 -N, --new-chain chain创建新的链。 -X, --delete-chain [chain]删除用户自定义链。被删除的链不能有其他链引用,被删除的链必须为空,即里面没有规则。如果不指定chain的话将会尝试删除所有的用户自定义链。 -E, --rename-chain old-chain new-chain修改链的名称。 规则操作 -A, --append chain rule-specification添加规则到链中。 -C, --check chain rule-specification测试指定规则是否存在 -D,…