k8s网络之flannel(vxlan)

简介: k8s网络之flannel(vxlan)

说明


本文主要包括以下内容:


  • vxlan简单介绍
  • 为什么要使用vxlan
  • k8s使用flannel(vxlan)如何进行pod之间的通信


vxlan简单介绍


VXLAN(Virtual eXtensible LAN,虚拟可扩展的局域网),是一种虚拟化隧道通信技术。它是一种overlay(覆盖网络)技术,通过三层的网络搭建虚拟的二层网络。简单来讲,VXLAN是在底层物理网络(underlay)之上使用隧道技术,依托UDP层构建的overlay的逻辑网络,使逻辑网络与物理网络解耦,实现灵活的组网需求。它不仅能适配虚拟机环境,还能用于容器环境。


为什么要使用vxlan


  1. vxlan支持更多的子网(vlan只支持2的12次方个子网,vxlan支持2的24次方个子网),并通过VNI(Virtual Network Identifier)区分不同的子网,相当于VLAN中的LAN ID


  1. 多租户网络隔离。不同用户之间需要独立地分配IP和MAC地址


  1. 云计算业务对业务灵活性要求很高,虚拟机可能会大规模迁移,并保证网络一直可用。解决这个问题同时保证二层的广播域不会过分扩大,这也是云计算网络的要求


k8s中使用flannel(vxlan)


说明:我这里使用kubeadm安装的k8s,version为1.19,flannel的网络模式为vxlan,可以根据需要自己修改。


[root@master huazai]# kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:30:33Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.0", GitCommit:"e19964183377d0ec2052d1f1fa930c4d7575bd50", GitTreeState:"clean", BuildDate:"2020-08-26T14:23:04Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}


参考:https://kubernetes.io/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-networking-model


下载flannel.yml


wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml


安装flannel


kubectl apply -f kube-flannel.yml


查看安装结果


[root@master huazai]# kubectl  get po -A |grep flannel
kube-system            kube-flannel-ds-f4x7m                        1/1     Running   0          15h
kube-system            kube-flannel-ds-ltr8h                          1/1     Running   0          15h
kube-system            kube-flannel-ds-mp76x                        1/1     Running   0          15h


看看安装flannel之后,它对主机做了什么


  1. 创建一个名为flannel.1的VXLAN网卡


[root@master huazai]# ip -d link show flannel.1
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default 
    link/ether fe:be:87:93:06:e2 brd ff:ff:ff:ff:ff:ff promiscuity 0 
    vxlan id 1 local 192.168.0.39 dev eth0 srcport 0 0 dstport 8472 nolearning ageing 300 noudpcsum


可以看到mtu为1450(IP头、UDP头、MAC头、vxlan协议共占了50)。dstport为8472,local IP为节点IP,查看flannel.1的信息如下


[root@master huazai]# ifconfig flannel.1
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.244.0.0  netmask 255.255.255.255  broadcast 10.244.0.0
        inet6 fe80::fcbe:87ff:fe93:6e2  prefixlen 64  scopeid 0x20<link>
        ether fe:be:87:93:06:e2  txqueuelen 0  (Ethernet)
        RX packets 2622  bytes 465577 (454.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4765  bytes 1081070 (1.0 MiB)
        TX errors 0  dropped 8 overruns 0  carrier 0  collisions 0


  1. 创建到其他节点pod cidrs(可通过kubectl get node master -o yaml得知)的路由表,主要是能让Pod中的流量路由到flannel.1接口


[root@master huazai]# route -n 
10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1


  1. 在节点中添加一条该节点的IP及VTEP设备的静态ARP缓存


[root@master huazai]# arp -n 
10.244.1.0               ether   0e:61:06:ff:7a:73   CM                    flannel.1
10.244.2.0               ether   0a:72:bf:3f:cd:40   CM                    flannel.1
[root@master huazai]# bridge  fdb
0a:72:bf:3f:cd:40 dev flannel.1 dst 192.168.0.8 self permanent
0e:61:06:ff:7a:73 dev flannel.1 dst 192.168.0.22 self permanent


以上的mac地址均为对应节点上flannel.1设备的mac


pod之间如何进行访问


  1. 同一个节点的pod如何访问


以下面两个pod为例,两个pod都在node1,ip分别为10.244.1.8、10.244.1.9,假设在ip为10.244.1.8的pod中去ping ip为10.244.1.9的pod


[root@master huazai]# kubectl get  po -o wide
nginx-deployment-66b6c48dd5-nzjgd   1/1     Running   0          35m   10.244.1.8   node1            
nginx-deployment-66b6c48dd5-jcwc9   1/1     Running   0          35m   10.244.1.9   node1


进入pod ip为10.244.1.8的pod中


[root@master huazai]# kubectl exec -it  nginx-deployment-66b6c48dd5-jcwc9  -- /bin/bash
root@nginx-deployment-66b6c48dd5-jcwc9:/#


查看其路由


root@nginx-deployment-66b6c48dd5-jcwc9:/# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.244.1.1      0.0.0.0         UG    0      0        0 eth0
10.244.0.0      10.244.1.1      255.255.0.0     UG    0      0        0 eth0
10.244.1.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0


可以发现在同一个节点上的pod,直接进行访问了(在同一个网络段),没有经过转发。进入另外一个pod中查看路由,发现也是一样的


[root@master ~]# kubectl exec -it nginx-deployment-66b6c48dd5-nzjgd  -- /bin/bash
root@nginx-deployment-66b6c48dd5-nzjgd:/#
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.244.1.1      0.0.0.0         UG    0      0        0 eth0
10.244.0.0      10.244.1.1      255.255.0.0     UG    0      0        0 eth0
10.244.1.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0


  1. 不同节点的pod如何访问


以下面两个pod为例,其中一个pod在node1上,IP为10.244.1.8,另外一个pod在node2,IP为10.244.2.4


[root@master ~]# kubectl get po -o wide
nginx-deployment-66b6c48dd5-f7v9q   1/1     Running   0          60m   10.244.2.4   node2  
nginx-deployment-66b6c48dd5-nzjgd   1/1     Running   0          60m   10.244.1.8   node1


进入pod ip为10.244.1.8的pod中


[root@master huazai]# kubectl exec -it  nginx-deployment-66b6c48dd5-jcwc9  -- /bin/bash
root@nginx-deployment-66b6c48dd5-jcwc9:/#


查看其路由 root@nginx-deployment-66b6c48dd5-jcwc9:/# route -n Kernel IP routing table Destination     Gateway         Genmask         Flags Metric Ref    Use Iface 0.0.0.0         10.244.1.1      0.0.0.0         UG    0      0        0 eth0 10.244.0.0      10.244.1.1      255.255.0.0     UG    0      0        0 eth0 10.244.1.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0  可以发现如果是执行ping 10.244.2.4则需要经过10.244.1.1,而10.244.1.1为node1上cn0的IP,cni0为flannel自己创建的网桥


[root@node1 net.d]# ifconfig
 cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
      inet 10.244.1.1  netmask 255.255.255.0  broadcast 10.244.1.255


再查看node1上的路由


[root@node1 net.d]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth0
10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1
10.244.1.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.0.0     0.0.0.0         255.255.255.192 U     0      0        0 eth0


由路由发现,目标地址为10.244.2.0的数据包的下一跳为10.244.2.0,且要通过flannel.1,flannel.1作为一个VTEP设备,收到报文后将按照VTEP的配置进行封包。查看node1上的arp和fdb


[root@node1 net.d]# arp -n 
10.244.0.0               ether   fe:be:87:93:06:e2   CM                    flannel.1
10.244.2.0               ether   0a:72:bf:3f:cd:40   CM                    flannel.1
[root@node1 net.d]# bridge  fdb 
0a:72:bf:3f:cd:40 dev flannel.1 dst 192.168.0.8 self permanent
fe:be:87:93:06:e2 dev flannel.1 dst 192.168.0.39 self permanent


这里的话,通过etcd可以得知10.244.2.4在node2上,并且可以得到node2的IP,并且通过node1上转发表,可以知道node2上对应的VTEP的mac,然后根据flannel.1设备创建时的设置参数(VNI、local IP、Port)进行VXLAN封包。然后数据包通过node1跟node2之间的网络连接,VXLAN包到达node2,通过端口8472,VXLAN包被转发给VTEP设备flannel.1进行解包,解封装后的IP包匹配node2中的路由表(10.244.2.0),内核将IP包转发给cni0。


[root@node2 ~]# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.0.1       0.0.0.0             UG    0      0        0 eth0
10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1
10.244.1.0      10.244.1.0      255.255.255.0    UG    0      0        0 flannel.1
10.244.2.0      0.0.0.0         255.255.255.0     U     0      0        0 cni0


cni0将IP包转发给连接在cni0上的pod


总结


通过以上发现,不同节点上的pod要互相进行访问时,需要通过主机路由,需要经过内核的封包解包操作,整个过程如下所示:


640.png


因此,在后续发现相关网络时,可通过tcpdump对节点上的cn0、flannel.1、eth0以及veth pair抓包进行判断和处理。同时,也要查看节点上的arp和fdb。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
16天前
|
运维 Kubernetes Cloud Native
探索Kubernetes的大二层网络:原理、优势与挑战🚀
在云原生领域,Kubernetes (K8s) 已经成为容器编排的事实标准☁️📦。为了支撑其灵活的服务发现和负载均衡🔍🔄,K8s采用了大二层网络的设计理念🕸️。本文将深入探讨大二层网络的工作原理、带来的好处✨,以及面临的挑战和解决方案❗🛠️。
探索Kubernetes的大二层网络:原理、优势与挑战🚀
|
4月前
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes|networkPolicy网络策略详解
云原生|kubernetes|networkPolicy网络策略详解
34 0
|
4月前
|
Kubernetes Cloud Native Docker
云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版
云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版
137 0
|
11天前
|
JSON Kubernetes 网络架构
Kubernetes CNI 网络模型及常见开源组件
【4月更文挑战第13天】目前主流的容器网络模型是CoreOS 公司推出的 Container Network Interface(CNI)模型
|
25天前
|
Kubernetes Shell Docker
K8S核心插件-Flannel网络插件
K8S核心插件-Flannel网络插件
45 0
|
1月前
|
Kubernetes 应用服务中间件 nginx
Kubernetes服务网络Ingress网络模型分析、安装和高级用法
Kubernetes服务网络Ingress网络模型分析、安装和高级用法
36 5
|
4月前
|
存储 Kubernetes Cloud Native
云原生|kubernetes|centos7下离线化部署kubesphere-3.3.2---基于kubernetes-1.22.16(从网络插件开始记录)
云原生|kubernetes|centos7下离线化部署kubesphere-3.3.2---基于kubernetes-1.22.16(从网络插件开始记录)
82 0
|
存储 Kubernetes 网络协议
Kubernetes网络分析之Flannel
Flannel是cereos开源的CNI网络插件,flannel支持多种网络模式,在实际的生产环境中,最常用的还是vxlan模式,本文将介绍其工作原理,并通过源码解析实现过程。
|
存储 Kubernetes 网络协议
Kubernetes网络分析之Flannel
Flannel是CoreOS开源的CNI网络插件,下图flannel官网提供的一个数据包经过封包、传输以及拆包的示意图,从这个图片里面里面可以看出两台机器的docker0分别处于不同的段:10.1.20.1/24 和 10.1.15.1/24 ,如果从Web App Frontend1 pod(10.1.15.2)去连接另一台主机上的Backend Service2 pod(10.1.20.3),网络包从宿主机192.168.0.100发往192.168.0.200,内层容器的数据包被封装到宿主机的UDP里面,并且在外层包装了宿主机的IP和mac地址。
3199 0
|
1月前
|
Prometheus 监控 Kubernetes
Kubernetes 集群监控与日志管理实践
【2月更文挑战第29天】 在微服务架构日益普及的当下,Kubernetes 已成为容器编排的事实标准。然而,随着集群规模的扩大和业务复杂度的提升,有效的监控和日志管理变得至关重要。本文将探讨构建高效 Kubernetes 集群监控系统的策略,以及实施日志聚合和分析的最佳实践。通过引入如 Prometheus 和 Fluentd 等开源工具,我们旨在为运维专家提供一套完整的解决方案,以保障系统的稳定性和可靠性。