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。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
1月前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
65 2
|
3月前
|
运维 定位技术 网络虚拟化
|
3月前
|
负载均衡 监控 网络虚拟化
|
3月前
|
Kubernetes 网络协议 网络安全
k8s中网络连接问题
【10月更文挑战第3天】
242 7
|
3月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
1246 1
|
4月前
|
Kubernetes 容器 Perl
Kubernetes网络插件体系及flannel基础
文章主要介绍了Kubernetes网络插件体系,特别是flannel网络模型的工作原理、配置和测试方法。
140 3
|
3月前
|
Kubernetes 容器
基于Ubuntu-22.04安装K8s-v1.28.2实验(三)数据卷挂载NFS(网络文件系统)
基于Ubuntu-22.04安装K8s-v1.28.2实验(三)数据卷挂载NFS(网络文件系统)
243 0
|
1月前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
75 17
|
1月前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。

热门文章

最新文章