network namespace 的增删改查功能已经集成到了 Linux 的 ip 工具集的 netns 子命令中,因此在 Linux 系统中,对 network namespace 的操作主要使用 ip netns 命令
$ ip netns help Usage: ip netns list ip netns add NAME ip netns set NAME NETNSID ip [-all] netns delete [NAME] ip netns identify [PID] ip netns pids NAME ip [-all] netns exec [NAME] cmd ... ip netns monitor ip netns list-id
新的 network namespace 创建后,可以使用 ip netns exec 命令进入 namespace,做网络配置或者查询的工作。
ip netns exec 命令只能根据 network namespace 的名称进入 namespace
以下命令查询 netns1 的 network namespace 的 IP 地址信息
$ ip netns exec netns1 ip add 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
默认的 network namespace 除了附带一个 lo 网卡外,没有任何其他网络设备,并且此 lo 接口还处于 DOWN 的状态,因此此回环网卡也是不可访问的。
$ ip netns exec netns1 ping 127.0.0.1 connect: Network is unreachable
在此示例中,如果想启用本地回环地址,首先需要进入 namespace,将本地回环网卡的状态修改为 UP
$ ip netns exec netns1 ip linkset dev lo up $ ip netns exec netns1 ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever $ ip netns exec netns1 ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.021 ms ^C --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.021/0.021/0.021/0.000 ms
$ ip link list 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:e7:c0:27 brd ff:ff:ff:ff:ff:ff 5: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff 6: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff
使用以下命令修改 veth pair 状态和配置 ip 地址信息
$ ip linkset dev veth0 up $ ip linkset dev veth1 up $ ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:e7:c0:27 brd ff:ff:ff:ff:ff:ff 5: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff 6: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff $ ifconfig veth0 192.168.10.10/24 $ ifconfig veth1 192.168.10.11/24 $ ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever
5: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff inet 192.168.10.11/24 brd 192.168.10.255 scope global veth1 valid_lft forever preferred_lft forever inet6 fe80::44d5:d3ff:feda:b880/64 scope link valid_lft forever preferred_lft forever 6: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff inet 192.168.10.10/24 brd 192.168.10.255 scope global veth0 valid_lft forever preferred_lft forever inet6 fe80::58b4:83ff:fe22:2b99/64 scope link valid_lft forever preferred_lft forever
$ ip netns exec newnetns1 ip link 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 6: veth0@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff link-netnsid 1 $ ip netns exec newnetns2 ip link 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 5: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff link-netnsid 0 $ ip netns exec newnetns1 ip add 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 6: veth0@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff link-netnsid 1 $ ip netns exec newnetns2 ip add 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 5: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff link-netnsid 0
配置 ip 地址信息,并测试 2 个 network namespace 是否能 ping 通
$ ip netns exec newnetns1 ifconfig veth0 up $ ip netns exec newnetns2 ifconfig veth1 up $ ip netns exec newnetns1 ifconfig veth0 192.168.10.10/24 $ ip netns exec newnetns2 ifconfig veth1 192.168.10.11/24 $ ip netns exec newnetns1 ip add 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 6: veth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 5a:b4:83:22:2b:99 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.10.10/24 brd 192.168.10.255 scope global veth0 valid_lft forever preferred_lft forever inet6 fe80::58b4:83ff:fe22:2b99/64 scope link valid_lft forever preferred_lft forever $ ip netns exec newnetns2 ip add 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 5: veth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 46:d5:d3:da:b8:80 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.10.11/24 brd 192.168.10.255 scope global veth1 valid_lft forever preferred_lft forever inet6 fe80::44d5:d3ff:feda:b880/64 scope link valid_lft forever preferred_lft forever $ ip netns exec newnetns2 ping 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. 64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.071 ms
--- 192.168.10.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms
$ ip link add name br0 type bridge $ ip linkset br0 up $ ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:e7:c0:27 brd ff:ff:ff:ff:ff:ff 7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ether ca:80:61:e4:98:94 brd ff:ff:ff:ff:ff:ff
除了使用 ip link 命令管理网桥外,还可以使用 bridge-utils 里面的 brctl 命令管理网桥设备,例如创建名为 br0 的 bridge 设备
$ yum install -y bridge-utils $ brctl help never heard of command [help] Usage: brctl [commands] commands: addbr <bridge> add bridge delbr <bridge> delete bridge addif <bridge> <device> add interface to bridge delif <bridge> <device> delete interface from bridge hairpin <bridge> <port> {on|off} turn hairpin on/off setageing <bridge> <time> set ageing time setbridgeprio <bridge> <prio> set bridge priority setfd <bridge> <time> set bridge forward delay sethello <bridge> <time> set hello time setmaxage <bridge> <time> set max message age setpathcost <bridge> <port> <cost> set path cost setportprio <bridge> <port> <prio> set port priority show [ <bridge> ] show a list of bridges showmacs <bridge> show a list of mac addrs showstp <bridge> show bridge stp info stp <bridge> {on|off} turn stp on/off $ brctl addbr br0
以下命令演示创建 veth pair 并将其中的一端连接到 br0
ip link add veth0 type veth peer name veth0_p ip add add 172.17.0.2/24 dev veth0 ip add add 172.17.0.3/24 dev veth0_p ip link set veth0 up ip link set veth0_p up
ip link set dev veth0 master br0
常见问题
network namespace 网卡配置 ip 后无法 ping 通本机网卡
示例操作如下,主要为创建 network namespace,添加网卡,配置 IP
$ ip netns add testns $ ip link add veth0 type veth peer name veth0_p $ ip linkset veth0 netns testns $ ip netns exec testns ip link 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 9: veth0@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether ae:c7:2f:73:31:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0 $ ip netns exec testns ip add add 10.10.1.1/24 dev veth0 $ ip netns exec testns ip linkset veth0 up $ ip netns exec testns ping 10.10.1.1 PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data. ^C --- 10.10.1.1 ping statistics --- 4 packets transmitted, 0 received, 100% packet loss, time 3054ms
如上操作,为 network namespace 创建了网卡并配置了 IP,网卡处于 UP 状态,但是配置的 IP 在本机无法 ping 通。
原因为 回环网卡 lo 处于 DOWN 状态,启用 lo,重新 ping,可以正常 ping 通本地 IP
$ ip netns exec testns ip linkset lo up $ ip netns exec testns ping 10.10.1.1 PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data. 64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=0.031 ms 64 bytes from 10.10.1.1: icmp_seq=2 ttl=64 time=0.023 ms ^C --- 10.10.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1060ms rtt min/avg/max/mdev = 0.023/0.027/0.031/0.004 ms
2 个 network namespace 配置后无法 ping 通
示例操作如下
创建 netwrk namespace
ip netns add ns1 ip netns add ns2
创建 veth pair 并分配给 netwrk namespace
ip link add veth1 type veth peer name veth1_p ip link add veth2 type veth peer name veth2_p ip link set veth1 netns ns1 ip link set veth2 netns ns2
为 veth 网卡配置 IP 并启用
ip addr add 10.10.10.1/24 dev veth1_p ip link set veth1_p up
ip addr add 10.10.20.1/24 dev veth2_p ip link set veth2_p up
ip netns exec ns1 ip addr add 10.10.10.2/24 dev veth1 ip netns exec ns1 ip link set veth1 up ip netns exec ns2 ip addr add 10.10.20.2/24 dev veth2 ip netns exec ns2 ip link set veth2 up
$ ip netns exec ns1 ping 10.10.20.2 PING 10.10.20.2 (10.10.20.2) 56(84) bytes of data. 64 bytes from 10.10.20.2: icmp_seq=1 ttl=63 time=0.084 ms 64 bytes from 10.10.20.2: icmp_seq=2 ttl=63 time=0.037 ms ^C --- 10.10.20.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1062ms
查看指定类型的网卡
要查看系统上网卡属于哪种类型,可以通过以下命令查看
$ ip link show type vxlan 6: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8951 qdisc noqueue state UNKNOWN mode DEFAULT group default link/ether ce:8c:56:84:e1:7a brd ff:ff:ff:ff:ff:ff $ ip link show type veth 2350: veth2fd77154@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8951 qdisc noqueue master cni0 state UP mode DEFAULT group default link/ether 5a:02:6c:65:c8:5f brd ff:ff:ff:ff:ff:ff link-netnsid 0 2352: vethfef50370@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8951 qdisc noqueue master cni0 state UP mode DEFAULT group default link/ether 3a:1c:0b:4f:af:b2 brd ff:ff:ff:ff:ff:ff link-netnsid 2 $ ip link show type bridge 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:48:54:ca:75 brd ff:ff:ff:ff:ff:ff 2349: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8951 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 26:4e:46:b2:2a:4c brd ff:ff:ff:ff:ff:ff