网络命名空间允许进程使用自己的TCP/IP网络栈,包含网卡,路由表,socket。
创建网络命名空间对应Clone标记为CLONE_NEWNET
。ip netns可以用于创建永久的网络命名空间,是通过挂载 /proc/self/ns/net
到/var/run/netns/${name_of_namespace}
实现。
ip netns add ${YOUR_NAMESPACE_NAME}
通过strace命令分析,是通过调用unshare和mount挂载实现创建永久化network namespace:
$ strace ip netns add test
unshare(CLONE_NEWNET) = 0
mount("/proc/self/ns/net", "/var/run/netns/two", 0x453b25, MS_BIND, NULL) = 0
接下来创建一个veth pair对,一端连接容器的网络命名空间one
, 一段连接主机命名空间,并给容器端veth分配ip。
ip netns add one
veth pair 是一个简单的两端设备,网络包从A端流入,都会从对应B端流出。
# veth0 <-> veth1
ip link add veth0 type veth peer name veth1
ip link set veth1 netns one
ip netns exec one ifconfig veth1 10.1.1.1/24 up
one
内网络接口ip# 启动网络接口
$ ifconfig veth0 10.1.1.2/24 up
$ ip netns exec one 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: veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 12:32:e8:e2:47:67 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.1.1/24 brd 10.1.1.255 scope global veth1
valid_lft forever preferred_lft forever
inet6 fe80::1032:e8ff:fee2:4767/64 scope link
valid_lft forever preferred_lft forever
veth1@if4
对应主机的网络接口4:
# 主机网络namespace
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
# .... omit for brevity
4: veth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0e:02:24:aa:4b:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.1.1.2/24 brd 10.1.1.255 scope global veth0
valid_lft forever preferred_lft forever
inet6 fe80::c02:24ff:feaa:4baa/64 scope link
valid_lft forever preferred_lft forever