通过 VXLAN 搭建 overlay 网络

date
Jul 31, 2022
updateDate
slug
overlay-network-with-vxlan
status
Published
tags
Kubernetes
Network
VXLAN
summary
手动模拟flannel vxlan 的组网原理
type
Post
VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),是对传统VLAN协议的一种扩展。VXLAN的特点是将L2的以太帧封装到UDP报文(即L2 over L4)中,并在L3网络中传输。
关于 vxlan 的原理网上有很多写的非常好的文章做解释,本文不过多说明,只是解释如何实践。
 
此文为了学习 flannel 中的 vxlan 网络,基本原理和 flannel 差不多。

目的

使 3 台 虚拟机的 docker 容器 之间网络互通。

原理以及数据流:

假设 01 节点上有一个容器 ip 192.168.230.2 需要访问 03 节点上的 192.168.231.2
  1. 容器到本地节点之间互通,这一部分由 容器和节点之间的 veth pair 实现。
  1. 数据包到达本地节点后,交由 本地 vxlan device 将这个 L2 数据包包装成 L4 的 udp 包发到往 目的节点的 vxlan device。
  1. 目的 vxlan 收到后拆包出 L2 数据包
  1. 此时进入本地节点和容器之间的互相通信。
 

整体规划:

 
Host
node ip
docker0
VXLAN ip
VXLAN Mac (可以由linux自动生成)
vxlan-01
10.0.0.230/24
192.168.230.1/24
192.168.230.0/32
aa:bb:cc:dd:ee:00
vxlan-02
10.0.0.231/24
192.168.231.1/24
192.168.231.0/32
aa:bb:cc:dd:ee:01
vxlan-03
10.0.0.232/24
192.168.232.1/24
192.168.232.0/32
aa:bb:cc:dd:ee:02
在各个虚拟机上配置 vxlan device,(mac 地址建议用 linux 自动生成,这里为了测试提前规划好了一个随便的 mac 地址)
节点都在同一个子网中,直接加一条路由规则也可达到目的(即 flannel 中的 host-gw 模式)此文章仅为了学习 vxlan
ip route add 192.168.231.0/24 via 10.0.0.231 ip route add 192.168.232.0/24 via 10.0.0.232
  • vxlan-01
    • VNI=99 PORT=4899 VXIP=192.168.230.0/32 VXMAC=aa:bb:cc:dd:ee:00 PREFIX=vxlan DEVNAME=$PREFIX.$VNI ip link add $DEVNAME type vxlan id $VNI dev ens18 dstport $PORT nolearning ip addr add $VXIP dev $DEVNAME ip link set dev $DEVNAME address $VXMAC ip link set $DEVNAME up
  • vxlan-02
    • VNI=99 PORT=4899 VXIP=192.168.231.0/32 VXMAC=aa:bb:cc:dd:ee:01 PREFIX=vxlan DEVNAME=$PREFIX.$VNI ip link add $DEVNAME type vxlan id $VNI dev ens18 dstport $PORT nolearning ip addr add $VXIP dev $DEVNAME ip link set dev $DEVNAME address $VXMAC ip link set $DEVNAME up
  • vxlan-03
    • VNI=99 PORT=4899 VXIP=192.168.232.0/32 VXMAC=aa:bb:cc:dd:ee:02 PREFIX=vxlan DEVNAME=$PREFIX.$VNI ip link add $DEVNAME type vxlan id $VNI dev ens18 dstport $PORT nolearning ip addr add $VXIP dev $DEVNAME ip link set dev $DEVNAME address $VXMAC ip link set $DEVNAME up
 
配置 route 表
命中 vxlan2, 和 vxlan3 的 子网通过 vxlan device 转发,并设置下一跳为对应的 vxlanip
vxlan1ip=192.168.230.0 vxlan2ip=192.168.231.0 vxlan3ip=192.168.232.0 vxlan1mac=aa:bb:cc:dd:ee:00 vxlan2mac=aa:bb:cc:dd:ee:01 vxlan3mac=aa:bb:cc:dd:ee:02 node1ip=10.0.0.230 node2ip=10.0.0.231 node3ip=10.0.0.232
  • vxlan-01
    • ip route add $vxlan2ip/24 via $vxlan2ip dev $DEVNAME onlink ip route add $vxlan3ip/24 via $vxlan3ip dev $DEVNAME onlink
  • vxlan-02
    • ip route add $vxlan1ip/24 via $vxlan1ip dev $DEVNAME onlink ip route add $vxlan3ip/24 via $vxlan3ip dev $DEVNAME onlink
  • vxlan-03
    • ip route add $vxlan1ip/24 via $vxlan1ip dev $DEVNAME onlink ip route add $vxlan2ip/24 via $vxlan2ip dev $DEVNAME onlink
       
配置 ARP 表
这一步理论上不需要手动配置,可以通过 vxlan 的多播模式达到目的,但本篇没有使用 vxlan 的多播模式组网,需要手动配置
  • vxlan-01
    • ip neighbor add $vxlan2ip lladdr $vxlan2mac dev $DEVNAME ip neighbor add $vxlan3ip lladdr $vxlan3mac dev $DEVNAME
  • vxlan-02
    • ip neighbor add $vxlan1ip lladdr $vxlan1mac dev $DEVNAME ip neighbor add $vxlan2ip lladdr $vxlan2mac dev $DEVNAME
  • vxlan-03
    • ip neighbor add $vxlan1ip lladdr $vxlan1mac dev $DEVNAME ip neighbor add $vxlan3ip lladdr $vxlan3mac dev $DEVNAME
       
配置 FDB 转发表
当我们配置号 arp 和 route 之后,拿到了需要访问的 ip 和mac地址,但是不知道哪里由这个 mac 地址,此时我们需要配置 fdb 转发表将其关联起来
 
  • vxlan-01
    • bridge fdb add $vxlan2mac dev $DEVNAME dst $node2ip bridge fdb add $vxlan3mac dev $DEVNAME dst $node3ip
  • vxlan-02
    • bridge fdb add $vxlan1mac dev $DEVNAME dst $node1ip bridge fdb add $vxlan3mac dev $DEVNAME dst $node3ip
  • vxlan-03
    • bridge fdb add $vxlan2mac dev $DEVNAME dst $node2ip bridge fdb add $vxlan1mac dev $DEVNAME dst $node1ip
       
       
至此,网络应该互通,测试一下吧
 
root@vxlan-01:~# ping -c1 192.168.231.1 PING 192.168.231.1 (192.168.231.1) 56(84) bytes of data. 64 bytes from 192.168.231.1: icmp_seq=1 ttl=64 time=0.660 ms --- 192.168.231.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.660/0.660/0.660/0.000 ms root@vxlan-01:~# ping -c1 192.168.232.1 PING 192.168.232.1 (192.168.232.1) 56(84) bytes of data. 64 bytes from 192.168.232.1: icmp_seq=1 ttl=64 time=0.534 ms --- 192.168.232.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.534/0.534/0.534/0.000 ms root@vxlan-01:~# docker run -it --rm busybox sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:c0:a8:e6:02 brd ff:ff:ff:ff:ff:ff inet 192.168.230.2/24 brd 192.168.230.255 scope global eth0 valid_lft forever preferred_lft forever / # ping 192.168.231.1 PING 192.168.231.1 (192.168.231.1): 56 data bytes 64 bytes from 192.168.231.1: seq=0 ttl=63 time=0.732 ms 64 bytes from 192.168.231.1: seq=1 ttl=63 time=0.461 ms
Tips: wireshark 可以直接对抓取的 udp 数据包进行 decode 成 vxlan 数据结构,如果需要排查会非常方便。
 
 

© Zzde 2020 - 2024