一.docker网络底层基础
https://juejin.cn/post/6905955407676571655
network namespace
network namespace 是 linux 内核提供的功能,是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。
ip netns 是 ip命令的一个自命令,和 network namespace 有关的操作都是在ip netns下进行的,可以通过 ip netns help
可以查看相关操作的帮助信息。
[vagrant@localhost ~]$ 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
使用 "ip netns add
namespace名称" 可以创建一个network namespase, 如果相同名字的 namespace 已经存在,则会报 Cannot create namespace
的错误。
ip netns
命令创建的 network namespace 会出现在 /var/run/netns/
目录下,如果需要管理其他不是 ip netns
创建的 network namespace,只要在这个目录下创建一个指向对应 network namespace 文件的链接就行。
[vagrant@localhost ~]$ sudo ip netns add net1
[vagrant@localhost ~]$ cd /var/run/netns
[vagrant@localhost netns]$ ls
net1
对于每个 network namespace 来说,都会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。ip netns exec
命令可以在对应的 network namespace 中执行命令,比如我们要看一下这个 network namespace 中有哪些网卡。
[vagrant@localhost ~]$ sudo ip netns exec net1 ip addr
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
每个 namespace 在创建的时候会自动创建一个 lo
的 interface,它的作用和 linux 系统中默认看到的 lo
一样,都是为了实现 loopback 通信。如果希望 lo
能工作,不要忘记启用它:
[vagrant@localhost ~]$ sudo ip netns exec net1 ip link set lo up
[vagrant@localhost ~]$ sudo ip netns exec net1 ip addr
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
两个network namespace 之间通信
有了不同 network namespace 之后,也就有了网络的隔离,默认情况下,network namespace 是不能和主机网络或者其他 network namespace 通信的。
linux 提供了veth pair, 来实现网络之间的通信.可以把 veth pair 当做是双向的 pipe(管道),从一个方向发送的网络数据,可以直接被另外一端接收到;或者也可以想象成两个 namespace 直接通过一个特殊的虚拟网卡连接起来,可以直接通信。
使用 ip link add type veth
可以创建一对 veth pair ,需要注意的是 veth pair 无法单独存在,删除其中一个,另一个也会自动消失。
下面我们来通过一对"veth pair"来实现两个network namespace之间的通信
1.创建两个network namespace分别命名为net1, net2
[vagrant@localhost ~]$ sudo ip netns add net1
[vagrant@localhost ~]$ sudo ip netns add net2
[vagrant@localhost ~]$ sudo ip netns list
net2
net1
2. 使用"ip link add type veth" 命令创建一对 "veth pair": veth0和veth1
[vagrant@localhost ~]$ sudo ip link add type veth
[vagrant@localhost ~]$ sudo ip link
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 32:45:a7:42:31:e7 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 4a:e8:98:00:13:12 brd ff:ff:ff:ff:ff:ff
新创建的veth pair是"D