1 Linux底層虛擬化設備介紹
1.1 tun/tap
tun和tap是Linux操作系統內核中的虛擬網絡設備,實現tun/tap設備的內核模塊為tun。
tap等同於一個以太網設備(網卡),工作在數據鏈路層,tun模擬了網絡層設備(點對點設備),工作在IP層,利用tun/tap驅動可以將tcp/ip協議處理好的網絡分包傳遞給使用tun/tap的進程。
可以理解為用戶空間程序可像向物理口發送報文那樣向tun/tap口發送報文,tun/tap設備發送(或注入)報文到OS協議棧(這里是指虛擬機的OS協議棧),就像報文從物理端口收到一樣。
在Linux內核中添加了一個tun/tap虛擬網絡設備的驅動程序和一個與之相關的字符設備/dev/net/tun,字符設備tun作為用戶空間(qemu進程運行的空間)和內核空間交換數據的接口。 用戶空間中的應用程序比如qemu程序可以通過該字符設備來與內核中的tun/tap驅動程序進行交互。當內核將數據包發送到虛擬網絡設備時,數據包被保存在設備相關的一個隊列中,直到用戶空間程序通過打開的字符設備tun的描述符讀取時,它才會被拷貝到用戶空間的緩沖區中,其效果就相當於,數據包直接發送到了用戶空間(host的用戶空間,不是虛擬機的用戶空間)。
tun/tap驅動程序中包含兩部分:字符設備驅動(用來在宿主機上用戶空間和內核空間互相傳遞信息的)和網卡驅動(也在內核層)。利用網卡驅動部分接受來自tcp/ip協議棧的網絡分包並發送或者反過來將接收到的網絡分包傳給協議棧處理。而字符設備驅動則將網絡分包在內核與用戶態之間傳送,模擬物理鏈路的數據接收和發送。tun/tap驅動很好的實現了兩種驅動的結合。
tap一般用於作為虛擬機的虛擬網卡設備,tun一般用以vpn隧道。
tap/tun 通過實現相應的網卡驅動程序來和網絡協議棧通信,可以把tun/tap看成數據管道,它一端連接主機協議棧,另一端連接用戶程序,可以把用戶層程序看做是網絡上另一台主機,他們通過tap虛擬網卡相連。一般的流程和物理網卡和協議棧的交互流程是一樣的,不同的是物理網卡一端是連接物理網絡,而 tap/tun 虛擬網卡一般連接到用戶空間。
TUN和TAP設備區別在於他們工作的協議棧層次不同,TAP等同於一個以太網設備,用戶層程序向tap設備讀寫的是二層數據包如以太網數據幀,tap設備最常用的就是作為虛擬機網卡。TUN則模擬了網絡層設備,操作第三層數據包比如IP數據包,openvpn使用TUN設備在C/S間建立VPN隧道
虛擬機通過虛擬網卡與向外網發送數據例子:
(1)虛擬機通過其網卡eth0向外發送數據,從主機角度看,就是用戶層程序qemu-kvm進程使用文件描述符(FD)26向字符設備/dev/net/tun寫入數據 P2 --> write(fd,...) --> N
(2)文件描述符26與虛擬網卡tap0關聯,也就是說主機從tap0網卡收到數據 N --> E
(3)tap0為網橋br0上一個接口,需要進行Bridging decision以決定數據包如何轉發 E --> D
(4)P2是與外部網絡其它主機通信,因此br0轉發該數據到em2.100,最后從物理網卡em2發出 D --> C --> B -- > A
可以看出在這個過程中,虛擬機發出的數據通過tap0虛擬網卡直接注入主機鏈路層網橋處理邏輯中,然后被轉發到外部網絡,數據包沒有穿過主機協議棧上層,因此主機上工作在內核協議棧IP層的iptables是無法過濾虛擬機數據包的
Tun設備舉例:
TUN設備連接的是主機內核協議棧IP層
(1)客戶端使用openvpn訪問web服務(圖中沒有畫出客戶端,在外部網絡里)
(2)客戶端啟動openvpn client進程連接openvpn server
(3)server下發路由條目到客戶端機器路由表中,同時生成虛擬網卡tun1(tun設備,openvpn client進程與openvpn server一樣會注冊tun虛擬網卡,server中則注冊的是tun0虛擬網卡)
(4)客戶端通過瀏覽器訪問web服務
(5)瀏覽器生成的數據包在協議棧IP層進行路由選擇,決定通過虛擬網卡tun1發出
(6)虛擬網卡tun1另一端連接用戶層openvpn client進程
(7)openvpn client進程收到原始請求數據包
(8)openvpn client封裝原始請求數據包,通過udp協議發送vpn封包到openvpn server上的9112端口 A -- > T --> K --> R --> P1
(9)openvpn server上的openvpn進程收到vpn封包,解包,使用文件描述符6寫數據到/dev/net/tun P1 --> write(fd,...) --> N
(10)文件描述符6與虛擬網卡tun0關聯,主機從tun0網卡收到數據包 N --> H ---> I
(11)主機進行Routing decision,根據數據包目的IP(用戶訪問web網站IP地址)從相應網卡發出 I --> K --> T --> M --> A
可以看出其實就是兩端的服務進程對一個數據包封包解包過程,達到一個中間人的功能,服務端的web收到的包已經是經過解壓的了,所以經常看到用此種技術來給公司分部訪問總部內網服務,同時因為加了路由條目,以此讓通道獨立且數據流方向確定,加上SSL協議實現對數據包進行加密從而使得數據傳輸安全,傳包則使用了常見的udp或tcp協議來傳輸。
1.2 LinuxBridge
Bridge是工作在Linux內核協議層二層的虛擬交換機,模擬了物理交換機的功能,可以添加若干個網絡設備到Bridge的接口上,添加到Bridge上的設備被設置為只接收二層數據幀並且轉發所有收到的數據包到Bridge中,Bridge內部維護了一個MAC表,從而可以將數據包轉發到其它接口上或者發往上層協議(或者丟棄和廣播)。
被添加到Bridge上的網卡是不能配置IP的,工作在數據鏈路層,對路由系統是不可見的,但可以給網橋配置IP地址。網橋只有設置了IP才能作為路由接口設備,參與IP層的路由選擇,才有可能將數據包發往上層協議棧。
舉例說明Bridge處理數據包流程,外部網絡(A)發往虛擬機qemu-kvm (P2)過程數據流向:
(1)首先數據包從em2(B)物理網卡進入,之后em2將數據包轉發給其vlan子設備em2.100
(2)經過Bridge check(L)發現子設備em2.100屬於網橋接口設備,因此數據包不會發往協議棧上層(T),而是進入bridge代碼處理邏輯,從而數據包從em2.100接口(C)進入br0
(3)經過Bridging decision(D)發現數據包應當從tap0(E)接口發出,此時數據包離開主機網絡協議棧(G),通過用戶空間進程qemu-kvm打開的字符設備/dev/net/tun(N)將數據包發往用戶空間
(4)qemu-kvm進程執行系統調用read從字符設備讀取內核層發送過來的數據包
(5)數據流走向A –>B –>C –>E –>G –>N –>P2
如果是從網卡em1(M)進入主機的數據包,經過Bridge check(L)后,發現em1非網橋接口,則數據包會直接發往(T)協議棧IP層,從而在Routing decision環節決定數據包的去向(A –> M –> T –> K)
上面第(3)步有一個Bridging decision的操作,這是根據數據包MAC地址來作出一些決策:
(1)包目的MAC為Bridge本身MAC地址(當br0設置有IP地址),從MAC地址這一層來看,收到發往主機自身的數據包,交給上層協議棧(D –> J)
(2)廣播包(目的地址是廣播地址),轉發到Bridge上的所有接口(br0,tap0,tap1,tap…)
(3)單播&&存在於MAC端口映射表,查表直接轉發到對應接口(比如 D –> E)
(4)單播&&不存在於MAC端口映射表,泛洪到Bridge連接的所有接口(br0,tap0,tap1,tap…)
(5)數據包目的地址接口不是網橋接口(連接到網橋的接口沒有一個是目的地址的就會出現這情況了,比如廣播泛洪沒人回應),橋不處理,交給上層協議棧(D –> J)
1.3 Veth-pair
首先了解下Linux網絡命名空間概念,Linux內核提供了6種類型的命名空間:pid,net(網絡命名空間),mnt,uts,ipc和user,Linux網絡命名空間只是Linux命令空間中的一種,網絡命名空間有自己獨立的網絡資源,比如網卡接口、路由表、iptables規則等。
命名空間將全局系統資源包裝到一個抽象中,該抽象只會與命名空間中的進程綁定,從而提供資源隔離(命名空間和cgroups(一種計量和限制機制,可以理解為類似配額管理的東西)是軟件集裝箱化(Docker)的大部分新趨勢的主要內核技術之一)。
可以使用ip netns命令創建網絡命名空間:
ip netns add ns1
VETH設備總是成對出現,送到一端請求發送的數據總是從另一端以請求接收的形式出現。veth工作在L2數據鏈路層,veth-pair設備在轉發數據包過程中並不篡改數據包內容。
veth的工作原理是:VETH會改變數據的方向並將其送入內核網絡子系統,完成數據的注入,而在另一端則能讀到此數據,有點類似於管道。
veth-pair常常用來連接兩個網絡命名空間
疑問:
(1)Openstack是怎么給的mac和ip地址
Openstack定義了port概念,並記錄在數據庫里,port可以看做是虛擬交換機上的一個端口,port上定義了MAC地址(虛擬機里顯示的mac地址,不是宿主機上tap里顯示的地址(這個tap只有在虛擬機啟動時才創建掛載,關閉后就刪除掉的))和IP地址,當instance的VIF(虛擬網卡)綁定到port時,port就將MAC地址和IP地址分配給VIF,內核根據port提供的信息來創建tap,
一般看到網橋創建后,如果上面就創建了一個tap設備,該tap設備是dhcp的(計算節點上沒有dhcp服務,所以計算節點上執行brctl show會沒有dhcp對應的tap設備)
2 Neutron的網絡模式介紹
網絡模式有local模式、flat模式、vlan模式、vxlan模式和gre模式
2.1 Local網絡模式
該網絡模式不會與宿主機的任何物理網卡相連,每個local網絡都會維護一個bridge,同一個local網絡下的虛擬機的網卡都會連接到同一個bridge下,所以只有同宿主機的同local網絡下的虛擬機之間能夠相互通信,其它都是隔離的。
2.2 Flat網絡模式
Flat網絡是不帶tag的網絡,要求宿主機的物理網卡直接與網橋連接,這也就是說每個flat網絡需要獨占一個物理網卡。
Openstack創建一個網絡后通常都需要創建一個子網,即指明該網絡的IP池和網關,並且設置是否要支持dhcp服務等。如果支持dhcp服務那么也會有一個tap接口連接到網橋中用以數據包通信來提供dhcp服務。比如剛創建的flat網絡如果勾選了dhcp服務,那么brctl里就能看到該flat網絡對應的網橋里除了物理網卡設備連接外,還有一個tap也連接着,它就是dhcp服務的tap。
計算節點是沒有dhcp服務的,所以它是沒有多一個設備連接到計算節點的網橋上的,但是在計算節點上的虛擬機在獲取IP和MAC時,它可以通過控制節點上的dhcp服務來獲取,因為他們在同一個network上,計算節點上發出的dhcp請求廣播包在控制節點的網橋上也是可以收到的,然后由控制節點的網橋上的dhcp服務的設備接收並處理。
控制節點和計算節點各一個虛擬機分別連接到同一個flat網絡時:
可以看到這兩個虛擬機通信時是通過了物理網卡之間的連接進行的通信,假設是計算節點的虛擬機ping控制節點的虛擬機,首先數據包在計算節點的網橋里沒找到目的端口由eth1將數據包發出去,計算節點的eth1和控制節點的eth1假設是在同一個交換機上(如果不是,則會走路由由網關進行數據包轉發),該數據包會進行廣播,控制節點的eth1收到該數據包發現目的IP有在自己網橋上,並將該數據包發給網橋上對應的接口即控制節點的虛擬機的tap。
疑問:
(1)為啥flat網絡的物理網卡沒有設置ip,怎么出外網的?
物理網卡連接到了網橋接口中,連接的口相當於是交換機的trunk口,通向外網的包會從這個物理網口出去。這里還是二層的數據包轉發,不用設置IP。
2.3 Vlan網絡模式
Vlan network是帶tag的網絡,是實際應用最廣泛的網絡類型。
直接看下圖:
可以看到我們創建了兩個vlan,100和101,一端連接到網橋接口上,另外一端連接到物理網卡eth1上,以eth1.100舉例,VM0和VM1的數據包從eth1出去時是帶着tag為100的標簽的,同理VM2的則是帶着tag為101的標簽,這些標簽是在經過eth1.100(或eth1.101)時打上的標簽。因為物理網口eth1經過了兩個vlan段,所以它所連接的交換機的口應該設置成trunk口,而不是Access口。
創建eth1.100和eth1.101可以使用vconfig來創建,
看下兩個物理主機下的情況:
可以看見計算節點和控制節點的網橋名是一致的,表明是同一個私有網絡。但因為vlan的隔離,vlan100和vlan101的虛擬機是不能相互通信的,如果需要通信需要三層的轉發,也就是可以通過虛擬路由來實現。
疑問:
(1)為啥在某台機器網絡是8網段,網關是8.1,要在一個交換機上設置了vlan 8才可以通外網呢?
我覺得應該是在交換機上設置的一個約定,比如你的數據包從這個端口出(假設一開始所有端口都是vlan 1的),那么它會檢查你的ip是不是符合它設置的1網段的,如果不是那么直接丟棄,所以通不了外網。
舉例:
交換機有2個vlan
int vlan10
ip add 10.1.1.2 255.255.255.0
ip default-gateway 10.1.1.1
int vlan 20
ip add 20.1.1.2 255.255.255.0
ip default-gateway 20.1.1.1
看個實際的操作截圖例子:
可以看到對於每一個vlan其都有設定對應的網絡地址。且還有設置網關,這里設置一個網關不用說是要在交換機上配置成這個網關,它只需簡單的比如增加一條路由項:ip route 192.168.8.1 192.168.1.1,那么它出外網是就是把它路由到了192.168.1.1上去處理了(簡單理解就是這里設置網關只是為了告訴交換機怎么轉發這個數據包出去)。
所以上面的vlan 8和ip是不是8網段是沒有絕對關系的,一切都要看交換機里的設置,是它判斷vlan 8里的設定(比如設定可能是ip addr 192.168.8.2 255.255.255.0)是不是跟你包的ip在同一網段。如果vlan 8里的設定是ip addr 192.168.9.2 255.255.255.0,那你的ip是192.168.8.100/24是出不了的。
(2)為啥兩個網卡設置了相同網段后,有一個網絡會不通了?
我們觀察到的現象就是后面的那個是可以ping通的,原因在於路由表
你用route命令查看路由變,可以看到類似以下這樣的表項:
192.168.8.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
192.168.8.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
當外面ping eth1對應的IP的時候,當一個ping包到達后要回應時,它總是從eth2出去的(但其實我們是要eth1出去的),但eth2的IP並不是我們ping的包了
解決方法可以是改路由表項,比如專門為eth1建一個路由表項:
192.168.8.100 0.0.0.0 255.255.255.0 U 0 0 0 eth1
或者給每個網卡分配單獨的路由表。並且通過 ip rule 來指定:
(3)具體tag記錄在哪個位置
記錄在以太網幀上,是數據鏈路層的概念
以太網幀格式:
|-----------------------------------------------------------------------------|
| DMAC(6bytes) | SMAC(6bytes) | Ether-Type(2bytes) | DATA |
|-----------------------------------------------------------------------------|
802.1Q VLAN定義了有tag的數據幀的封裝格式,即在以太網幀頭中插入了4個字節的VLAN字段。
帶VLAN TAG的以太網幀格式 :
|------------------------------------------------------------------------------------------ --- --- ---|
| DMAC(6bytes) | SMAC(6bytes) | Ether-Type(0x8100) | VLAN(4bytes) | DATA |
|------------------------------------------------------------------------------------------ --- --- ---|
VLAN TAG的格式 :
|---------------------------------------------------------------------------------|
| PRI(3bits) | CFI(1bit) | TAG(12bits) | Ether-Type(2bytes) | DATA |
|---------------------------------------------------------------------------------|
PRI:幀優先級,就是通常所說的802.1p。
CFI:規范標識位,0為規范格式,用於802.3或EthII。
TAG:就是我們通常說的VLAN ID
Ether-Type:標識緊隨其后的數據類型。
2.4 Vxlan網絡模式
vxlan是overlay網絡,overlay網絡是指建立在其它網絡上的網絡。
目前linux-bridge只支持vxlan,open vswitch則可支持vxlan和gre網絡。
Vxlan的全稱是Virtual eXtensible Local Area Network,它也是提供以太網二層服務的。
相比Vlan,Vxlan的優勢:
(1)支持更多的二層網段:VLAN使用12bit標記vlan id(最多支持4094個),Vxlan使用24bit標記vxlan id(vnid,支持16777216個)
(2)能更好利用已有網絡路徑:VLAN為了避免環路使用了Spanning Tree Protocol導致有一半網絡路徑不可用,vxlan則利用UDP包通過三層傳輸,可以使用所有路徑。
(3)避免物理交換機MAC表耗盡:由於采用隧道機制,交換機無需在MAC表中記錄虛擬機的信息
Vxlan的包格式是在鏈路層包前面加上8字節的Vxlan Header(vnid占24位):
通過UDP的傳輸,Vxlan能夠在三層網絡上建立一條二層的隧道。
Vxlan使用VTEP進行Vxlan的解包和封包,每個VTEP都會有一個IP接口,配置一個IP地址,VTEP使用該IP來封裝鏈路幀包且通過該IP傳輸和接收Vxlan數據包。
兩端的 VTEP IP 作為源和目標 IP
VTEP的實現可以是硬件的,也可以是軟件的,軟件方面的實現:
(1)帶Vxlan內核模塊的Linux
(2)Open vSwitch
實現方式:
(1)Vxlan內核模塊創建一個監聽端口為8472的UDP Socket
(2)在Socket上接收到Vxlan包后進行解包並根據vxlan id轉發到對應的vxlan interface上,比如vxlan-34(也是連接到網橋上的一個設備),由它把包傳給網橋,網橋再發送給虛擬機。
(3)在Socket上接收到要發出去的數據包時則將其封裝為UDP包並從網卡發出
Vxlan數據包轉發流程:
Host-A和Host-B可以看作是兩個Host上的虛擬機和vxlan-id設備的結合體,VTEP-1和VTEP-2是Vxlan內核模,vxlan-id設備一端連接網橋,一端與內核模塊的VTEP通信。
(1)虛擬機A向虛擬機B發送數據時,數據經過VTEP-1時,VTEP-1從自己的映射表中找到MAC-B對應的VTEP-2設備,以該設備的IP和MAC作為目標IP和MAC來封裝,並且加上Vxlan頭部。
(2)數據經過路由到達VTEP-2之后進行解包,依次去掉外層MAC頭,外層 IP 頭,UDP 頭 和VXLAN頭。VTEP-2 依據目標 MAC 地址將數據包發送給虛擬機B(這里其實是先轉發到網橋上,然后網橋轉發給對應的虛擬機)
兩個主機間同vxlan id間通信圖:
2.5 配置文件的配置參數值對應的意義解釋
配置文件:/etc/neutron/plugins/ml2/ml2_conf.ini
tenant_network_types:指明租戶允許創建的網絡類型為vxlan類型
mechanism_drivers:指明支持的策略驅動類型,比如除了linuxbridge,還可以是openvswitch,l2population是用來提升vxlan網絡模式效率的,其實就是讓各主機的VTEP能記錄虛擬機的MAC對應的是哪個主機上的VTEP,這樣就不用廣播arp找虛擬機的MAC了。
type_drivers:指明支持的網絡模式類型,用來在服務啟動時加載對應的網絡模式driver的代碼。
配置文件:/etc/neutron/plugins/ml2/linuxbridge_agent.ini
enable_vxlan:是否開啟vxlan模式
local_ip:指明VTEP設備的IP
l2_population:是否開啟該策略優化
這里是指明用eth2來作為provider network的網口
3 Neutron中的dhcp服務的工作原理
Neutron的dhcp服務是通過dhcp agent服務實現的,它部署在網絡節點上,該服務使用了開源的dnsmasq來實現dhcp功能的,dnsmasq是一個提供DHCP和DNS服務的開源軟件。
Dnsmasq和openstack里的network是一對一的關系,一個dnsmasq可以為一個network里的多個subnet提供服務。
查看我們系統里的dnsmasq服務:
紅框中的--dhcp-hostsfile選項指定的是記錄了已分配的虛擬機的IP和對應的MAC地址,其內容如下:
紅框中的--interface選項指定的是提供DHCP服務的interface,用來監聽虛擬機發來的請求。
我們可以看到它的interface名是ns-de2b2a68-ac,使用ip addr好像沒有看到有該設備的存在,那是因為該設備是在其它namespace里,不在宿主機的namespace里(root namespace),但網橋是在root namespace里,dhcp的設備在另外一個namespace里,該怎么連通呢,答案是使用veth-pair來聯通,就是又一對接口,一個在dhcp的namespace,一個在root namespace,這樣就連通起來了。
可以使用ip netns list命令查看所有namespaces(紅框里的就是我們的dhcp的interface所在的namespace):
列出該namespace下的網絡設備:
ip netns exec qdhcp-dddab6ab-4799-4ba6-bb44-a94b531de34e ip addr:
這里怎么看ns-de2b2a68-ac對應的另外一個veth是誰呢,可以這樣看:
從上圖的紅框中我們看到該設備名后面還有@if28,這個28是該設備接口的index,我們還看倒這個設備的前面還有個”2:”,代表它的另外一個veth是設備接口index為2的,我們可以使用如下命令過濾獲取:
ip link show | grep 28
可以知道對應的設備名是tapde2b2a68-ac
可以看到該設備另一端是連在網橋上的:
疑問:為啥需要這么麻煩搞多一個namespace呢?
答案是因為這樣才能讓不同network的子網可以重疊,而每個dhcp服務的namespace的獨立的網絡棧就不會受到影響,因為dhcp服務們有自己的route table,firewall rule,network interface device等。
一個虛擬機獲取其IP和MAC的過程舉例:
(1)當為虛擬機分配一個網卡時,會為它創建一個port,該port會包含該網卡的MAC和IP(記錄在數據庫里),這些信息也會同步到dnsmasq的host配置文件里
(2)當虛擬機啟動時,會發出DHCPDISCOVER廣播,網橋上的tapde2b2a68-ac收到后通過veth pair傳到dhcp的namespace中的ns-de2b2a68-ac設備上
(3)Dhcp服務在ns-de2b2a68-ac設備上監聽到了該請求數據包,然后查它的host文件並把對應的網絡信息比如IP和MAC等返回回去,以DHCPOFFER 消息的形式返回回去
(4)虛擬機收到該DHCPOFFER 消息后回復DHCPREQUEST 表示接受此DHCPOFFER
(5)Dnsmasq收到DHCPREQUEST 后發送DHCPACK確認消息,分配過程結束
拓撲圖:
4 虛擬路由器原理
我們知道兩個不同子網如果需要連通在二層上是不能實現的,那么就需要三層的介入,即數據包的路由,這個功能由路由器設備實現。可以使用物理的路由,也可以使用虛擬路由來實現。
虛擬路由的實現由L3 agent服務負責,它的實現原理是使用IPtables定義轉發規則。
L3 agent服務運行在網絡節點上。跟dhcp服務實現思想類似,為了讓不同network的子網可以重疊,所以一個route也會創建一個namespace,然后創建一對veth-pair分別連接兩個namespace來通信。因為一般是連接的兩個子網,所以會有兩個網關設備被創建在router的namespace里,所有會創建兩對veth-pair,然后在router的namespace再設定路由規則,使得到達兩個網關設備的數據包能夠互相路由,這樣數據包就能通了。
舉例:
兩個子網分別是172.16.100.0/24和172.16.101.0/24,網關分別是172.16.100.1和172.16.101.1
查看router里面的設備:
ip netns exec qrouter-1f9c082f-9d97-471f-a41b-afe90fd62c0d ip a
可以看到兩個子網的網關IP都在這個network namespace里。
查看router里面的路由規則:
ip netns exec qrouter-1f9c082f-9d97-471f-a41b-afe90fd62c0d route -n
有上面兩條紅線標着的路由規則,這兩個子網間的數據包就可相互路由了。
拓撲圖:
因為浮動IP也是跟私有網絡的子網的所連接的router有關的,這里擴展下浮動IP的工作原理:
浮動IP其實是依附於在router的namespace空間上的,浮動IP與私有網絡的IP是一一對應的,假設虛擬機A的私有網絡的IP是172.16.100.12,分配給它的浮動IP是192.168.100.236,則這兩個IP在router的namespace里是有設定一些NAT轉換規則的。如下:
ip netns exec qrouter-1f9c082f-9d97-471f-a41b-afe90fd62c0d iptables -t nat -S
可以看到這里設定了SNAT規則和DNAT規則,起到的作用就是:
(1)當router接收到從外網發來的包,如果目的地址是floating IP 192.168.100.236,將目的地址修改為虛擬機的的IP 172.16.100.12。這樣外網的包就能送達到虛擬機了
(2)當虛擬機發送數據到外網,源地址 172.16.100.12 將被修改為 floating IP 192.168.100.236
所以浮動IP它並不是attach到虛擬機里去了,只是在虛擬路由器的namespace里做了一些NAT。
疑問:
(1)為什么還未指定路由器給交換機連接時,交換機設定的網關ip是不可用的
答案是這些元數據只是記錄在數據庫里,並沒有真正配置到路由器上,待創建router后,這個網關地址就會配置到router的interface上