Linux网络虚拟化 名称空间和veth

本文假设已经具备基本的路由交换基础。个人学习记录,欢迎指正。

Network namespace是linux内核提供的进行网络隔离的功能,每一个名称空间内有自己独立的网络协议栈,有自己独立的路由表等。Docker容器网络的实现和隔离就是通过网络名称空间实现的。

操作网络名称空间

# 添加
[root@localhost ~]# ip netns add ns1

# 查看
[root@localhost ~]# ip netns list
ns1

[root@localhost ~]# ip netns show
ns1

# 在名称空间内执行命令
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

# 进入名称空间
[root@localhost ~]# ip netns exec ns1 bash

# 执行命令,查看该名称空间的网卡信息
[root@localhost ~]# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

# 退出名称空间
[root@localhost ~]# exit
exit

# 删除
[root@localhost ~]# ip netns delete ns1

FAQ

Docker容器的网络名称空间怎么查看?

默认网络名称空间提供的入口文件在/var/run/netns/目录下,ip netns 命令默认也是读取的该目录下的入口文件。 Docker重新指定了该目录在/var/run/docker/netns/,所以如果想使用默认的ip netns命令管理docker的网络名称空间,只需要做一个软链到 /var/run/netns/就可以

# 测试环境使用,将docker容器的网络名称空间软链到/var/run/netns/ 并显示显示容器名
test -d /var/run/netns || mkdir /var/run/netns
for container in $(docker ps -a| awk '{print $NF}'| grep -v 'NAMES'); \
do \
ln -s $(docker inspect $container| grep SandboxKey| awk -F '"' '{print $4}') /var/run/netns/$container; \
done
ip netns list

veth

Virtual ethernet interface是一个虚拟的以太网接口,在linux中veth和普通网卡是一样对待的。veth总是成对出现的,被称为veth pair,可以简单的理解我们现实世界中的网线,一条网线有两个水晶头,主要进行设备间的互联互通。

操作veth

# 添加
ip link add veth1 type veth peer name veth2

# 查看
ip add
ip link show type veth

# 默认veth是down状态,所以需要up
ip link set veth1 up

# 配置ip
ip addr add 1.1.1.1/32 dev veth1

# 修改mac地址
ip link set veth1 addr ee:ee:ee:ee:ee:ee

# 将veth移动到其他网络名称空间
ip netns add ns1
ip link set dev veth1 netns ns1 

# 删除,只要删除任意一端,整个veth pair即删除
ip link del veth2

模拟两台主机同网段通信

# 拓扑情况
# 两台终端通过一条网线互联
# 终端使用网络名称空间来模拟

# 新建两个名称空间
ip netns add ns1
ip netns add ns2

# 新建一条veth pair
ip link add veth1 type veth peer name veth2

# 分别将veth pair的两头插入终端
ip link set dev veth1 netns ns1
ip link set dev veth2 netns ns2

# 配置终端内网卡信息
ip netns exec ns1 ip addr add 10.0.12.1/24 dev veth1
ip netns exec ns1 ip link set veth1 up
ip netns exec ns2 ip addr add 10.0.12.2/24 dev veth2
ip netns exec ns2 ip link set veth2 up

# 测试两台终端互通
ip netns exec ns1 ping 10.0.12.2 -c 4

# 查看终端网络配置情况
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:6e:c4:c9:6b:75 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 10.0.12.1/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::506e:c4ff:fec9:6b75/64 scope link
       valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: veth2@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d2:2c:22:bb:e4:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.12.2/24 scope global veth2
       valid_lft forever preferred_lft forever
    inet6 fe80::d02c:22ff:febb:e499/64 scope link
       valid_lft forever preferred_lft forever

# 通信抓包信息
[root@localhost ~]# ip netns exec ns2 tcpdump -i veth2 -ne
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth2, link-type EN10MB (Ethernet), capture size 262144 bytes
11:02:16.500486 52:6e:c4:c9:6b:75 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 10.0.12.2 tell 10.0.12.1, length 28
11:02:16.500511 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype ARP (0x0806), length 42: Reply 10.0.12.2 is-at d2:2c:22:bb:e4:99, length 28
11:02:16.500515 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 1, length 64
11:02:16.500538 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 1, length 64
11:02:17.524159 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 2, length 64
11:02:17.524190 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 2, length 64
11:02:18.549011 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 3, length 64
11:02:18.549041 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 3, length 64
11:02:19.572310 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype IPv4 (0x0800), length 98: 10.0.12.1 > 10.0.12.2: ICMP echo request, id 1201, seq 4, length 64
11:02:19.572336 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype IPv4 (0x0800), length 98: 10.0.12.2 > 10.0.12.1: ICMP echo reply, id 1201, seq 4, length 64
11:02:21.749109 d2:2c:22:bb:e4:99 > 52:6e:c4:c9:6b:75, ethertype ARP (0x0806), length 42: Request who-has 10.0.12.1 tell 10.0.12.2, length 28
11:02:21.749178 52:6e:c4:c9:6b:75 > d2:2c:22:bb:e4:99, ethertype ARP (0x0806), length 42: Reply 10.0.12.1 is-at 52:6e:c4:c9:6b:75, length 28

FAQ

机器上有很多veth pair,怎么确定另一端是在哪个网络名称空间内

通过使用ip a命令查看网卡配置信息的时候,是可以看到网卡最前边是有一个编号,这个就是网卡的唯一索引,然后看网卡名称veth2@if4,if4表示的就是对端的索引号为4。

主意:网卡的索引号在同一个名称空间内是唯一的,什么意思呢,也就是说如果你在其他网络名称空间内创建了veth然后移动到另外一个或者默认网络名称空间内,就会搞的很混乱。所以一般我们都是在默认名称空间内创建veth然后移动到其他名称空间,这样就比较好识别。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值