Docker内核技术原理(三)之Network Namespace

上一篇文章介绍了PID Namespace,这篇文章一起分享一下网络命令空间。Network Namespace是内核支持的一种网络虚拟方式,可以在一个操作系统之上创建出多个网络空间,每个网络空间都有一个独立的协议栈。网络命名可以通过用户工具ip管理。常用命令如下:

# ip net help
Usage: ip netns list  #列出所有的网络空间
       ip netns add NAME #创建网络空间
       ip [-all] netns delete [NAME] #删除网络空间
       ip netns pids NAME #查看指定空间内的进程ID
       ip [-all] netns exec [NAME] cmd ... #在空间中执行命令

注意,上面的list命令,并不会直接列出Docker容器的网络空间,因为list命令只会列出/var/run/netns 下面的网络空间,详细内容在前面的文章已经介绍了。

我们可以实操一下,创建一个网络空间,命令如下

# ip net add net1
# ip net list
net1
# ls  /var/run/netns/ 
net1

当通过ip命令行工具创建一个net1网络空间后会在/var/run/netns目录下创建一个net1的关联文件。在这个新的网络空间会有独立的网卡、ARP表、路由表、Iptables规则等网络相关属性,新的网络空间中只有一个环回网卡

# ip netns exec net1 ip add
1: lo:  mtu 65536 qdisc noop state DOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

没有任何ARP记录和路由记录

# ip netns exec net1 arp -a
#
# ip netns exec net1 ip route
#

主机网络也是在一个网络空间之中,那么主机如何与容器的网络空间通信,以及容器网络空间之间又如何通信呢?下面我们尝试通过veth(虚拟网络对)将两个网络空间连接到一起,如下图所示。


Docker内核技术原理(三)之Network Namespace

1、创建网络空间

# ip net add net2
# ip net list
net2
net1

2、创建虚拟网卡对

# ip link add type veth 

3、将网卡分别插入到两个网络空间中

 # ip link set veth1 netns net1
 # ip link set veth0 netns net2

此时在主机上面通过ip link已经看不到这个两个虚拟网卡了,他们已经分别加入到net1和net2两个网络空间中

# ip netns exec net1 ip add
1: lo:  mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
129235: veth1@if129234:  mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 9a:42:97:da:d1:91 brd ff:ff:ff:ff:ff:ff link-netnsid 1

4、分别配置两个网络空间中的网卡

通过exec命令进入命名空间,剩下的就是Linux常规网络配置。

# ip netns exec net1 ip link set veth1 up
# ip netns exec net1 ip addr add 192.168.1.1/24 dev veth1
# ip netns exec net2 ip link set veth0 up  
# ip netns exec net2 ip addr add 192.168.1.2/24 dev veth0

5、验证

# ip netns exec net2 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.027 ms

这样两个命名空间直接便可以互相通信。但我们不能给所有容器之间都建立点对点的链接,而是通过一个虚拟网桥(交换机),将不同的网络空间连接起来,如下图所示。

Docker内核技术原理(三)之Network Namespace

具体操作如下:

1、创建网桥

# brctl addbr netbr
# ip link set netbr up

2、创建虚拟网卡对

执行两次分别创建两个虚拟网卡对

# ip link add type veth

查看创建的两组网卡对,其中veth0和veth1是一对,veth2和veth3是一对。

# ip link|grep veth
36: veth0@veth1:  mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
37: veth1@veth0:  mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
38: veth2@veth3:  mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
39: veth3@veth2:  mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000

3、分别将一端插入网络空间并启动网卡

# ip link set veth0 netns net1
# ip link set veth3 netns net2
# ip netns exec net1 ip link set lo up
# ip netns exec net1 ip link set veth0 up
# ip netns exec net2 ip link set lo up
# ip netns exec net2 ip link set veth3 up

4、另一端插入网桥上

# brctl addif netbr veth1
# brctl addif netbr veth2
# ip netns exec net1 ip addr add 192.168.1.1/24 dev veth0
# ip netns exec net2 ip addr add 192.168.1.2/24 dev veth3

5、验证连通性

#  ip netns exec net1 ping  192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.123 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.071 ms

Kubernetes里面每个Pod里面都附带了一个Sandbox(Pause沙箱)容器,这个容器的目的就是提供业务容器的网络空间,业务容器启动后会加入到这个沙箱容器中,共享网络空间。我们可以通过Docker命令查看容器的网卡IP:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' 容器ID

这里需要注意,这种方式查询容器IP地址的时候,只有沙箱容器能够返回容器网络信息,而业务容器的IPAddress属性为空。

展开阅读全文

页面更新:2024-05-31

标签:目的   详细内容   内核   容器   网卡   属性   命令   原理   独立   两个   主机   通信   方式   业务   工具   技术   科技   网络   空间

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top