虛擬化網絡都是基於netns實現,不管是昨日的openstack,還是今日的docker。
ip netns
ip-netns - process network namespace management
A network namespace is logically another copy of the network stack, with it's own routes, firewall rules, and network devices.
網絡名稱空間是網絡棧的一個邏輯副本,有自己的路由、防火牆規則、和網絡設備。
By convention a named network namespace is an object at /var/run/netns/NAME that can be opened. The file descriptor resulting from opening /var/run/netns/NAME refers to the specified network namespace. Holding that file descriptor open keeps the network namespace alive.
通常網絡名稱空間是一個位於/var/run/netns/NAME的可打開對象,保持這個文件可打開可以保持網絡名稱空間存活。
The convention for network namespace aware applications is to look for global network configuration files first in /etc/netns/NAME/ then in /etc/.
For example, if you want a different version of /etc/resolv.conf for a network namespace used to isolate your vpn you would name it /etc/netns/myvpn/resolv.conf.
用法
ip [ OPTIONS ] netns { COMMAND | help }
ip netns list - show all of the named network namespaces 列出所有名稱空間
ip netns add NETNSNAME - create a new named network namespace 創建一個新的名稱空間
ip netns delete NETNSNAME - delete the name of a network namespace 刪除一個名稱空間
ip netns exec NETNSNAME cmd ... - Run cmd in the named network namespace 在網絡名稱空間中執行系統命令
ip [-all] netns exec [ NAME ] cmd ... - Run cmd in the named network namespace.
If -all option was specified then cmd will be executed synchronously on the each named network namespace.
ip link
用到netns,就不得不說到ip-link
ip-link - network device configuration
用法
ip [ OPTIONS ] link { COMMAND | help }
顯示設備屬性
ip link show - display device attributes
dev NAME:specifies the network device to show. (default) 如果不指定設備,則顯示所有設備信息
up:only display running interfaces. 只顯示啟動的接口
添加虛擬設備
ip link add - add virtual link
link DEVICE:specifies the physical device to act operate on. 指定在哪個物理設備上操作
NAME:specifies the name of the new virtual device. 指定新虛擬設備的名稱
TYPE:specifies the type of the new device. 指定新設備的類型
Link types:
vlan - 802.1q tagged virtual LAN interface
veth - Virtual ethernet interface 虛擬網絡接口(一對)
vcan - Virtual Local CAN interface
dummy - Dummy network interface
ifb - Intermediate Functional Block device
macvlan - virtual interface base on link layer address (MAC)
can - Controller Area Network interface
bridge - Ethernet Bridge device 網橋設備
刪除虛擬設備
ip link delete - delete virtual link
DEVICE:specifies the virtual device to act operate on.
TYPE:specifies the type of the device.
dev DEVICE:specifies the physical device to act operate on.
設置設備屬性
ip link set - change device attributes
dev DEVICE:specifies network device to operate on.
up and down:change the state of the device to UP or DOWN. 啟動或關閉網卡
multicast on or multicast off:change the MULTICAST flag on the device. 啟用或禁用組播
name NAME:change the name of the device. 修改網卡名稱。需要先donw掉網卡,不然會提示busy。
This operation is not recommended if the device is running or has some addresses already configured.
alias NAME:give the device a symbolic name for easy reference. 為網卡設置別名
mtu NUMBER:change the MTU of the device. 設置MTU大小,默認為1500
netns NETNSNAME:move the device to the network namespace associated with name NETNSNAME. 將接口移動到指定的網絡名稱空間
這里單獨說一下veth設備
veth設備是成對出現的,一端連接的是內核協議棧,一端彼此相連。一個設備收到協議棧的數據,會將數據發送另一個設備上去。
大概結構如下:
+----------------------------------------------------------------+
| |
| +------------------------------------------------+ |
| | Newwork Protocol Stack | |
| +------------------------------------------------+ |
| ↑ ↑ ↑ |
|..............|...............|...............|.................|
| ↓ ↓ ↓ |
| +----------+ +-----------+ +-----------+ |
| | eth0 | | veth0 | | veth1 | |
| +----------+ +-----------+ +-----------+ |
|192.168.1.11 ↑ ↑ ↑ |
| | +---------------+ |
| | 192.168.2.11 192.168.2.1 |
+--------------|-------------------------------------------------+
↓
Physical Network
示例
創建一對虛擬網卡,新建的網卡默認都是關閉的,名稱空間里的回環網卡lo默認也是關閉的。
# ip link add kk type veth peer name vkk
# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.251.53.190 netmask 255.255.248.0 broadcast 10.251.55.255
ether 00:16:3e:00:3c:24 txqueuelen 1000 (Ethernet)
RX packets 516917 bytes 522231637 (498.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 410017 bytes 29372384 (28.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
kk: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether 32:24:c6:46:81:ac 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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 0 (Local Loopback)
RX packets 37561 bytes 3506524 (3.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37561 bytes 3506524 (3.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vkk: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether 92:92:2c:df:be:bd 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
創建一個名稱空間
# ip netns add test
# ip netns list
將虛擬網卡vkk移動到名稱空間,這時vkk就查看不到了
# ip link set vkk netns test
# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.251.53.190 netmask 255.255.248.0 broadcast 10.251.55.255
ether 00:16:3e:00:3c:24 txqueuelen 1000 (Ethernet)
RX packets 516917 bytes 522231637 (498.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 410017 bytes 29372384 (28.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
kk: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether 32:24:c6:46:81:ac 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
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 0 (Local Loopback)
RX packets 37561 bytes 3506524 (3.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37561 bytes 3506524 (3.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
進入名稱空間,發現剛才的虛擬網卡已經在名稱空間里面了。
# ip netns exec test bash
# ifconfig -a
lo: flags=8<LOOPBACK> mtu 65536
loop txqueuelen 0 (Local Loopback)
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
vkk: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether 92:92:2c:df:be:bd 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
另外,要使名稱空間能和本地和外部通信,需要使用網橋,這里不細說了。