上一篇文章介绍了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(虚拟网络对)将两个网络空间连接到一起,如下图所示。
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
这样两个命名空间直接便可以互相通信。但我们不能给所有容器之间都建立点对点的链接,而是通过一个虚拟网桥(交换机),将不同的网络空间连接起来,如下图所示。
具体操作如下:
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
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号