一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Linux VXLAN的原理和用途

 點點閱 2024-06-27

VXLAN協(xié)議

VXLAN是Virtual eXtensible Local Area Network的縮寫,RFC 7348的標題“A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks”,說明了VXLAN是一個在傳統(tǒng)Layer 3網絡上架設出來的Layer 2 overlay網絡。RFC Abstract如下:

This document describes Virtual eXtensible Local Area Network (VXLAN), which is used to address the need for overlay networks within virtualized data centers accommodating multiple tenants.  The scheme and the related protocols can be used in networks for cloud service providers and enterprise data centers.  This memo documents the deployed VXLAN protocol for the benefit of the Internet community.

在下面的場景中有兩服務器,由三層物理網絡連接。這兩臺服務器可能在同一個機架上,或者在不同的機架上,亦或在物理距離相距甚遠的不同數(shù)據(jù)中心里。有4個VxLAN overlay網絡,標識分別為VNI 22, 34, 74, 98。來看看Server 1上的虛擬機VM1-1和Server 2上的虛擬機VM2-4,它們屬于相同的標識為VNI 22的VXLAN overlay網絡。虛擬機并不知道overlay網絡,也不知道VxLAN報文的封裝和解封過程,因為這些過程都由物理服務器上的VTEP完成??吹竭@里,即使你沒聽說過VTEP這個概念,也大概知道它的作用了吧,VTEP (VXLAN Tunnel End Point), An entity that originates and/or terminates VXLAN tunnels,VTEP負責VxLAN的封裝和解封裝。

這種部署方法是基于物理機能夠感知VXLAN協(xié)議,從而可以作為VxLAN的封裝和解封點(VTEP) 。另外一種部署方法是把VTEP設備的位置放在網絡設備中,比如交換機,可以作為一個VXLAN網絡來負責VxLAN報文的封裝和解封。在數(shù)據(jù)中心的部署中,物理機作為VTEP的部署方式能更好地和物理網絡設備解耦,并且更加方便運維。

Linux上對VXLAN的支持

快速搭建和理解VXLAN的方法之一就是利用Linux。從內核3.7版本開始,Linux就開始支持VXLAN。到了內核3.12版本,Linux對VXLAN的支持已經完備,支持單播和組播,IPv4和IPv6。利用man查看ip的link子命令,可以查看是否有vxlan type,如下:

$ man ip-link

搜索vxlan,可以看到如下描述,可以利用ip link add增加類型為VXLAN的link。

VXLAN Type Support
For a link of type VXLAN the following additional arguments are supported:

ip link add DEVICE type vxlan id VNI [ dev PHYS_DEV ] [ { group | remote } IPADDR ] [ local { IPADDR | any } ] [ ttl TTL ] [ tos TOS ] [ dstport PORT ] [ srcport MIN
MAX ] [ [no]learning ] [ [no]proxy ] [ [no]rsc ] [ [no]l2miss ] [ [no]l3miss ] [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ] [ ageing SECONDS ] [ maxad‐
dress NUMBER ] [ gbp ]

下面的實驗在如下環(huán)境中完成:

  • 操作系統(tǒng)版本:CentOS Linux release 7.4.1708 (Core)
  • 內核版本:3.10.0-693.2.2.el7.x86_64
  • 云虛機vm1 eth0網絡接口IP 172.31.0.106,云虛機vm2 eth0網絡接口IP 172.31.0.107

場景1: 最簡單的點對點VXLAN

創(chuàng)建簡單的點對點VXLAN環(huán)境非常簡單。如下圖所示,只需要在兩個機器(物理機或者虛擬機都可以,本實驗中是云上的虛擬機環(huán)境)中各創(chuàng)建一個vxlan類型的網絡接口即可,vxlan類型的接口vxlan1可以作為上文中提到的VTEP。

在上面的環(huán)境中,注意我們將vxlan網絡接口配置上IP地址,在10.0.0.0/24網段內。在IP地址分配后,Linux系統(tǒng)的路由表就會創(chuàng)建一條路由,去往10.0.0.0/24網段的報文走網絡接口vxlan1出去。vm1上去往10.0.0.0/24的報文,在vxlan1上會做VXLAN封裝,內層地址是10.0.0.106,外層地址是172.31.0.106。VXLAN報文通過物理網絡達到對端vm2上的VETP vxlan1,在vm2的vxlan1接口上做VXLAN協(xié)議的解封裝,從而結束整個過程。

上圖是一個物理上的示意圖,在邏輯上形成的VXLAN overlay網絡環(huán)境如下圖,虛線部分示意出來的Overlay Network和VXLAN Tunnel都是邏輯上的概念。如果有容器和虛機被接入邏輯上的Overlay網絡10.0.0.0/24,它們完全不用感知底層物理網絡,看起來對端是和自己在同一個二層環(huán)境里,就是像是在VTEP設備的上面直接構建了一條VXLAN Tunnel,把Overlay網絡里的網絡接口直接在二層打通。

具體的配置只需要3條命令。如下,在vm1上執(zhí)行如下命令:

# ip link add vxlan1 type vxlan id 1 remote 172.31.0.107 dstport 4789 dev eth0
# ip link set vxlan1 up
# ip addr add 10.0.0.106/24 dev vxlan1

上面的第一條命令創(chuàng)建了一個Linux上類型為vxlan的網絡接口,名為vxlan1。

  • id: VNI標識是1。
  • remote: 作為一個VTEP設備來封裝和解封VXLAN報文,需要知道將封裝好的VXLAN報文發(fā)送到哪個對端VTEP。Linux上可以利用group指定組播組地址,或者利用remote指定對端單播地址。在實驗的云環(huán)境中默認不支持組播,這里利用remote指定點對點的對端IP地址為172.31.0.107。
  • dstport: 指定目的端口為4789。因為當Linux內核3.7版本首次實現(xiàn)VXLAN時,UDP端口還并沒有規(guī)定下來。很多廠商利用了8472這個端口,Linux也采用了相同的端口。后來IANA分配了4789作為VXLAN的目的UDP端口。如果你需要使用IANA端口,需要用dstport指定。
  • dev: 指定VTEP通過哪個物理device來通信,這里是使用eth0。

第二條命令讓vxlan1接口up起來。第三條命令給設備分配IP地址10.0.0.106, 子網掩碼為24 (255.255.255.0)。

在vm2上,利用類似方法創(chuàng)建名為vxlan1的網絡接口。

# ip link add vxlan1 type vxlan id 1 remote 172.31.0.106 dstport 4789 dev eth0
# ip link set vxlan1 up
# ip addr add 10.0.0.107/24 dev vxlan1

以上簡單的命令就完成了所有配置。用ifconfig可以看到vxlan1網絡接口,如下:

# ifconfig vxlan1
vxlan1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.0.106  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 22:2d:c4:f0:c7:29  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

看下vm1的如下路由表,去往目的網段10.0.0.0/24的報文將走vxlan1接口。

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.0.253    0.0.0.0         UG    0      0        0 eth0
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 vxlan1
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.31.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

在vm1上ping overlay網絡的對端IP地址10.0.0.107,可以ping通。

# ping 10.0.0.107 -c 3
PING 10.0.0.107 (10.0.0.107) 56(84) bytes of data.
64 bytes from 10.0.0.107: icmp_seq=1 ttl=64 time=0.447 ms
64 bytes from 10.0.0.107: icmp_seq=2 ttl=64 time=0.361 ms
64 bytes from 10.0.0.107: icmp_seq=3 ttl=64 time=0.394 ms

--- 10.0.0.107 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.361/0.400/0.447/0.042 ms

在ping包的同時,用tcpdump抓vm1 eth0網卡的包。因為報文到達eth0前經過了網絡接口vxlan1, 完成了VXLAN的封裝,所以在抓包結果里應該能看到完整的VXLAN報文。

抓包時可以只抓和對端172.31.0.107通信的報文,如下:

# tcpdump -i eth0 host 172.31.0.107 -s0 -v -w vxlan_vni_1.pcap

抓包結果如下,wireshark自動將UDP目的端口為4789的報文識別成VXLAN報文,直接顯示內層的報文,protocol為ICMP協(xié)議。如果使用Linux默認接口8472,顯示的應該是UDP協(xié)議,還需要修改wireshark的協(xié)議設置,讓其識別成VXLAN。

場景2: 容器跨主機通信

上面最簡單的點對點VXLAN實驗只是個簡答的演示,沒有太多實際工程意義,本節(jié)用容器通信來演示一個更加完整的場景。

場景描述:在vm1和vm2上各部署一個docker容器,默認情況下,一個容器宿主機上的容器能夠直接用私網IP地址通信,因為它們利用一個網橋接在一起。而不同宿主機上的容器無法直接用私網IP地址通信。k8s等docker部署軟件中的網絡組建實際上完成了這部分工作,讓不同宿主機的容器能夠直接通信。本節(jié)使用原生docker,以及在宿主機上自建的vxlan網絡接口,來打通不同宿主機上容器,讓它們可以直接利用內網IP通信。

注意:因為實驗在云上的虛擬機上完成,上面提到的容器宿主機,用的是云上的虛擬機。容器宿主機也可以是物理機,實驗效果不變。

準備docker容器

安裝docker的過程不展開了,docker官方文檔有詳細的描述。在Linux安裝了docker后,可以看到多了一個docker0的網絡接口,默認在172.17.0.0/16網段。這個是連接本地多個容器的網橋。

# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:44:e8:74:e8  txqueuelen 0  (Ethernet)
        RX packets 6548  bytes 360176 (351.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7489  bytes 40249455 (38.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

使用默認172.17.0.0/16網段,docker容器的IP地址都會從172.17.0.2開始分配。為了能使vm1和vm2上的容器使用不同的IP地址,在利用docker run啟動容器的時候需要能自定義IP地址,而利用--ip參數(shù)自定義IP地址的功能只能在自定網絡中支持,所以先創(chuàng)建一個自定義網絡,指定網段172.18.0.0/16。

# docker network create --subnet 172.18.0.0/16 mynetwork
3231f89d69f6b3fbe2550392ebe4d00daa3d19e251f66ed2d81f61f2b9184362
# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1cb284a6cb33        bridge              bridge              local
069538be0246        host                host                local
3231f89d69f6        mynetwork           bridge              local
0b7934996485        none                null                local

利用docker network ls查看,可以看到一個新的bridge網絡被創(chuàng)建,名稱為我指定的mynetwork。利用ifconfig可以看到多了一個網絡接口,名字不是dockerXX,而直接以br開頭,是一個網橋。

br-3231f89d69f6: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:97:22:a5:f9  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

創(chuàng)建一個新的容器,如下:

# docker run -itd --net mynetwork --ip 172.18.0.2 centos
16bbaeaaebfccd2a497e3284600f5c0ce230e89678e0ff92f6f4b738c6349f8d
  • --net指定自定義網絡
  • --ip指定IP地址
  • centos指定image

查看容器ID和狀態(tài),并且登錄SHELL,如下:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
16bbaeaaebfc        centos              "/bin/bash"         2 minutes ago       Up 2 minutes                            condescending_swartz
# docker exec -it 16bbaeaaebfc /bin/bash
[root@16bbaeaaebfc /]# ifconfig
bash: ifconfig: command not found

注意:docker為了創(chuàng)建容器的效率,通常都用了size很小的image,意味著很多常用工具需要安裝,比如centos image里面的ifconfig??梢岳脃um whatprovides ifconfig命令查看ifconfig輸入哪個包,查到屬于net-tools-2.0-0.22.20131004git.el7.x86_64包,直接用yum install net-tools -y安裝即可。再執(zhí)行ifconfig命令,可以看到容器eth0網卡的IP地址為172.18.0.2。

[root@16bbaeaaebfc /]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
        RX packets 3319  bytes 19221325 (18.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2015  bytes 132903 (129.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在vm2上執(zhí)行同樣的操作,在創(chuàng)建新容器的時候,指定IP地址為172.18.0.3,容器的環(huán)境即準備完畢。在vm1上的centos 容器中ping 172.18.0.3,和預期一致,是無法ping通的。

[root@16bbaeaaebfc /]# ping 172.18.0.3 -c 2
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
From 172.18.0.2 icmp_seq=1 Destination Host Unreachable
From 172.18.0.2 icmp_seq=2 Destination Host Unreachable

--- 172.18.0.3 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1000ms
pipe 2
[root@16bbaeaaebfc /]# ping 172.18.0.1 -c 2
PING 172.18.0.1 (172.18.0.1) 56(84) bytes of data.
64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from 172.18.0.1: icmp_seq=2 ttl=64 time=0.079 ms

--- 172.18.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.060/0.069/0.079/0.012 ms

創(chuàng)建VXLAN接口接入docker網橋

先來梳理下docker及docker容器在Linux宿主機網絡模塊中做的操作,梳理清楚之后會發(fā)現(xiàn)打通不同宿主機上docker容器的方法非??簡單。從宿主Linux系統(tǒng)的視角看操作系統(tǒng)中的網絡設備,總結如下:

  • docker0接口:網橋,在安裝完docker后默認被創(chuàng)建,網段是172.17.0.0/16,網橋的默認IP地址為172.17.0.1。
  • br-xxxx接口:網橋,在創(chuàng)建完自定義docker網絡完被創(chuàng)建,網段是被用戶指定的172.18.0.0/16,網橋的默認IP地址為172.18.0.1。
  • vethxxxx接口:veth網絡接口,在創(chuàng)建一個具體的docker容器后被創(chuàng)建,如果有N個運行的容器,就會有N個veth網絡接口。容器中的eth0接口和宿主機的veth網絡接口是一個veth網絡對,Linux上的veth接口作為一個端口連接入docker網橋,如docker0或其他自定義網橋。這也是為什么一個宿主機上的docker容器能夠默認通信的原因,因為它們創(chuàng)建后就被接入到了同一個網橋上。

為了方便理解,在默認網段172.17.0.0/16中創(chuàng)建2個容器,在自定義網段中上文已經創(chuàng)建了1個docker容器,利用btctl查看網橋及其接口,如下:

# brctl show
bridge name    bridge id        STP enabled    interfaces
br-3231f89d69f6        8000.02429722a5f9    no        veth2fa4c50
docker0        8000.024244e874e8    no        vethc7cd982
                                       vethd3d0c18

從上面的輸出結果可以看到,默認網橋docker0上,有vethc7cd982和vethd3d0c18兩個網絡接口接入。在定義網絡網橋br-3231f89d69f6一個端口上,veth2fa4c50網絡接口接入。這三個veth網絡接口分別連接著一個docker容器的eth0網絡接口,連接著同一個網橋的veth網絡接口vethc7cd982和vethd3d0c18默認二層能通。

有了上面的梳理和本文第一節(jié)VXLAN網絡接口的基礎知識,想必打通不同宿主機上docker容器的方法也比較清晰了。思路就是在兩個容器宿主機上各創(chuàng)建一個VXLAN接口,并且將VXLAN接口接入docker網橋的端口上,如下圖:

有了VXLAN接口的連接后,從vm1上docker容器發(fā)出的包到達docker網橋后,可以從網橋的VXLAN接口出去,從而報文在VETP(VXLAN接口)處被封裝成VXLAN報文,再從物理網絡上到達對端VETP所在的主機vm2。對端VTEP能正確解包VXLAN報文的話,隨后即可將報文通過vm2上的docker網橋送到上層的docker容器中。

具體的配置如下,在vm1上:

# ip link add vxlan_docker type vxlan id 200 remote 172.31.0.107 dstport 4789 dev eth0
# ip link set vxlan_docker up
# brctl addif br-3231f89d69f6 vxlan_docker
  • 第一條命令創(chuàng)建VNI為200的VXLAN網絡接口,名稱為vxlan_docker,參數(shù)設置和場景1中的各個參數(shù)類似。
  • 第三條命令把新創(chuàng)建的VXLAN接口vxlan_docker接入到docker網橋br-3231f89d69f6中。

在vm2上,輸入如下命令:

# ip link add vxlan_docker type vxlan id 200 remote 172.31.0.106 dstport 4789 dev eth0
# ip link set vxlan_docker up
# brctl addif br-f4b35af34313 vxlan_docker

在vm1的docker容器上再ping 172.18.0.3,結果如下,ping可以通。注意RTT的時間,ping 172.18.0.3的RTT在10^(-1)毫秒級別,ping 172.18.0.1的RTT在10^(-2)毫秒級別,前者是走物理網絡的延遲,后者是協(xié)議棧的延遲,兩者有量級上的差別。

# docker exec -it 16bbaeaaebfc ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
        RX packets 3431  bytes 19230266 (18.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2132  bytes 141908 (138.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# docker exec -it 16bbaeaaebfc ping 172.18.0.3 -c 2
PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data.
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.544 ms
64 bytes from 172.18.0.3: icmp_seq=2 ttl=64 time=0.396 ms

--- 172.18.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.396/0.470/0.544/0.074 ms
#
# docker exec -it 16bbaeaaebfc ping 172.18.0.1 -c 2
PING 172.18.0.1 (172.18.0.1) 56(84) bytes of data.
64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.18.0.1: icmp_seq=2 ttl=64 time=0.072 ms

--- 172.18.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms

最后說明,本節(jié)只是為了演示Linux VXLAN的用于而構造了這個簡單但沒有實際用處的場景,在跨主機環(huán)境的容器之間利用VXLAN從二層打通。在工程中做容器跨主機通信時有很多方面需要考慮,也有很多項目在致力于這方面的研究。比如Flannel,通過給每臺宿主機分配一個子網的方式為容器提供虛擬網絡,它基于Linux TUN/TAP,使用UDP封裝IP包來實現(xiàn)L3 overlay網絡,并借助etcd維護網絡的分配情況。Github上有項目的文檔。

Linux公社的RSS地址https://www./rssFeed.aspx

本文永久更新鏈接地址https://www./Linux/2019-03/157820.htm

linux

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲精品偷拍视频免费观看| 亚洲另类欧美综合日韩精品| 欧美日韩黑人免费观看| 精品久久综合日本欧美| 中文字幕av诱惑一区二区| 91人妻人人澡人人人人精品| 91日韩欧美国产视频| 黑人巨大精品欧美一区二区区| 免费精品一区二区三区| 国产亚洲欧美日韩精品一区| 精品国自产拍天天青青草原| 九九九热在线免费视频| 国产精品一区二区丝袜| 亚洲午夜福利视频在线| 国内欲色一区二区三区| 东京干男人都知道的天堂| 99热九九在线中文字幕| 久久少妇诱惑免费视频| 亚洲国产成人av毛片国产| 97人妻精品免费一区二区| 小草少妇视频免费看视频| 婷婷激情五月天丁香社区 | 好吊视频有精品永久免费| 出差被公高潮久久中文字幕| 成年女人午夜在线视频| 日本精品中文字幕在线视频| 丰满少妇高潮一区二区| 精品国自产拍天天青青草原 | 欧美一区二区三区高潮菊竹| 日韩不卡一区二区三区色图| 狠狠亚洲丁香综合久久| 中文字幕欧美精品人妻一区| 成人午夜激情在线免费观看 | 天堂av一区一区一区| 色婷婷视频在线精品免费观看| 激情中文字幕在线观看| 亚洲午夜av久久久精品| 精品国产亚洲免费91| 中文字幕人妻综合一区二区| 少妇人妻一级片一区二区三区 | 午夜国产精品国自产拍av|