虛擬網卡
==虛擬網卡(Virtual Network Interface,簡稱vNIC) 是一種在軟件層面模擬的網卡設備,不依賴于物理硬件,而是通過操作系統或虛擬化技術實現網絡通信功能。==它允許計算機在虛擬環境中模擬物理網卡的行為,用于連接虛擬網絡或與物理網絡交互。
核心特點
1.軟件模擬
- 通過軟件算法模擬物理網卡的功能,如數據包的接收、發送、MAC地址處理等。
- 無需物理硬件支持,可在無物理網卡的設備上運行。
2.靈活配置
- 用戶可自由設置虛擬網卡的IP地址、MAC地址、子網掩碼等參數。
- 支持動態調整網絡配置,適應不同場景需求。
3.跨平臺兼容
- 可在Windows、Linux、macOS等操作系統上運行。
- 常見于虛擬機(如VMware、VirtualBox)、容器(如Docker)、云服務(如AWS、Azure)等場景。
虛擬網卡:TUN/TAP
TUN/TAP 是 Linux 內核中提供的兩種虛擬網絡設備,用于在用戶空間程序和內核網絡棧之間傳輸數據。
1.TUN(網絡層虛擬設備)
- 工作層次:網絡層(第三層)。
- 處理數據:IP 數據包。
- 特點:
模擬一個網絡層接口,允許用戶空間程序接收和發送 IP 層的數據包。
常用于 VPN 應用,將網絡流量從一個遠程網絡重定向到本地虛擬網絡接口。
沒有 MAC 地址,僅處理 IP 層數據,無法進行二層操作(如發送 ARP 包或以太網廣播)。
2.TAP(鏈路層虛擬設備)
- 工作層次:數據鏈路層(第二層)。
- 處理數據:以太網幀。
- 特點:
模擬一個以太網接口,允許用戶空間程序發送和接收以太網幀。
通常用于虛擬機網絡、橋接網絡、虛擬交換機等場景,以模擬完整的二層網絡通信。
擁有 MAC 地址,可以處理二層數據幀,支持二層廣播和 MAC 層功能。
工作機制
數據傳輸:數據在用戶空間和內核之間通過設備文件(如 /dev/net/tun)傳輸。
- 用戶空間 → 虛擬設備 → 內核網絡棧:用戶空間程序通過文件描述符將數據(IP 包或以太網幀)寫入 TUN/TAP 設備,內核接收到數據后,根據設備類型(TUN 或 TAP)將數據包發送到內核網絡棧的對應層。
- 內核網絡棧 → 虛擬設備 → 用戶空間:當內核網絡棧收到外部網絡的數據包,并且這些數據包的目標是虛擬網絡設備時,內核會將這些數據包發送到 TUN 或 TAP 設備,設備接收到數據后,通過文件描述符將數據傳遞到用戶空間。
VPN應用程序例子
應用程序通過tun設備對外發送數據包后,tun設備就會把數據包通過字符設備發送給VPN應用程序,VPN接收到數據包,重新封裝出新的報文;然后通過協議棧發送到物理網卡上;
虛擬網卡tun實戰
1.查看當前的物理網卡,eth0就是我們的物理網卡
ifconfig
通過ip link
命令 創建一個虛擬網卡
ip tuntap add dev tun0 mod tun
查看網卡信息,新添加的虛擬網卡默認是DOWN
狀態.需要用-a 參數顯示
ifconfig -a
激活網卡
ip link set tun0 up
再次通過ifconfig
查看,可以看到網卡狀態UP
了;
分配ip地址
ip addr add 10.5.0.1/24 dev tun0
通過ifconfig
進行查看
此時說明我們的虛擬網卡已經添加好了,通過 del 可以刪除網卡
ip tuntap del dev tun0 mod tun
虛擬網卡:veth
使用 tun/tap 設備傳輸數據需要經過兩次協議棧,不可避免地會有一定的性能損耗,
所以引入了新的網卡實現方式 veth.
veth(Virtual Ethernet)是一種虛擬網卡設備,在 Linux 內核中實現,用于在兩個網絡命名空間之間創建點對點連接。
- 成對出現:veth 設備總是成對出現,例如 veth0 和 veth1,它們之間形成一個虛擬的以太網連接。
- 網絡命名空間隔離:veth 設備的一端可以放置在一個網絡命名空間中,另一端放置在另一個網絡命名空間中,從而實現不同命名空間之間的通信。
- 數據傳輸:從一個 veth 設備發送的數據包會直接傳輸到其對端的 veth 設備,就像在物理以太網中通過網線連接的兩臺設備一樣。
工作原理
- 內核網絡棧處理:veth 設備的數據傳輸由 Linux 內核的網絡棧處理。當一個 veth 設備接收到數據包時,內核會將數據包直接傳遞給其對端的 veth 設備,而不會經過物理網絡接口。
- 高效通信:由于 veth 設備之間的通信在內核中完成,沒有物理網絡接口的開銷,因此通信效率非常高。
虛擬網卡veth實戰
查看當前網卡信息
ifconfig
創建兩個網絡空間
ip netns add ns1ip netns add ns2ip netns list
ns2
ns1
創建一個虛擬網卡對
ip link add veth11 type veth peer name veth12
執行 ifconfig -a
可以看到網卡多了 2 個
將網卡挪到不同的命名空間中
sudo ip link set veth11 netns ns1
sudo ip link set veth12 netns ns2
激活我們的網卡
ip netns exec ns1 ip link set veth11 up
ip netns exec ns2 ip link set veth12 up
設置ip地址
ip netns exec ns1 ip addr add 10.5.0.1/24 dev veth11
ip netns exec ns2 ip addr add 10.5.0.2/24 dev veth12
相互ping一下
ip netns exec ns1 ping 10.5.0.2
ip netns exec ns2 ping 10.5.0.1
刪除網絡命名空間
ip netns del ns1
ip netns del ns2
弊端:隨著網絡設備的增多,網絡連線的復雜程度將成倍增長。
虛擬交換機
在現實生活中,一臺設備往往與多臺設備進行通信,路由器很好的解決了這個問題,將設備通過路由器的二層交換,那么設備就能通過路由器IP分配來進行通信;
Linux Bridge
最主要的功能就是二層交換,是對現實的虛擬機進行模擬;
Linux Bridge
,由brctl
命令創建和管理。
實戰
創建三個 netns,三對 veth pair,分別一端在 netns 中,另一端連接在網橋上;
新建網絡命名空間
root@VM-8-12-ubuntu:~# ip netns add ns1
root@VM-8-12-ubuntu:~# ip netns add ns2
root@VM-8-12-ubuntu:~# ip netns add ns3
創建 veth 對
root@VM-8-12-ubuntu:~# ip link add veth2-ns type veth peer name veth2-br
root@VM-8-12-ubuntu:~# ip link add veth1-ns type veth peer name veth1-br
root@VM-8-12-ubuntu:~# ip link add veth3-ns type veth peer name veth3-br
將 ns 一段的網卡移入到命名空間
root@VM-8-12-ubuntu:~# ip link set dev veth1-ns netns ns1
root@VM-8-12-ubuntu:~# ip link set dev veth2-ns netns ns2
root@VM-8-12-ubuntu:~# ip link set dev veth3-ns netns ns3
啟動網卡,并配置 ip,開啟本地回環,
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip link set veth1-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip link set veth2-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip link set veth3-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip addr add 10.100.0.11/24 dev veth1-ns
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip addr add 10.100.0.12/24 dev veth2-ns
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip addr add 10.100.0.13/24 dev veth3-ns
測試網絡聯通性,此時是不通的
root@VM-8-12-ubuntu:~# ip netns exec ns3 ping 10.100.0.11
PING 10.100.0.11 (10.100.0.11) 56(84) bytes of data.
^C
--- 10.100.0.11 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2037ms
創建網橋
root@VM-8-12-ubuntu:~# brctl addbr testbr0
root@VM-8-12-ubuntu:~# ifconfig -a
啟動網橋
ip link set testbr0 up
配置ip地址
ip addr add 10.100.0.1/24 dev testbr0
將veth的另一端打開
ip link set veth1-br up
ip link set veth2-br up
ip link set veth3-br up
將veth的另一端與網橋連接上
brctl addif testbr0 veth1-br
brctl addif testbr0 veth2-br
brctl addif testbr0 veth3-br
嘗試ping一下
ip netns exec ns3 ping 10.100.0.11
ip netns exec ns2 ping 10.100.0.13
如果發現不能轉發,原因是 linux 加入了 bridge_netfilter
。需要開啟允許通過:
iptables -A FORWARD -i testbr0 -j ACCEPT
釋放空間
ip link del veth1-br
ip link del veth2-br
ip link del veth3-br
ip link del testbr0
ip netns del ns1
ip netns del ns2
ip netns del ns3