七天用Go写个docker(网络篇)

0.docker网络实现

docker网络分为两部分,一部分是docker与宿主机之间的通信,另一部分是docker与外部网络之间的通信。docker与宿主机之间的通信是通过veth和bridge虚拟网络接口实现的,而与外部网络通信是通过 iptables 流量转发实现的。

1. veth和bridge

veth是一个虚拟的网络设备,它都是成对出现的,你可以把它理解成马里奥里面的水管,马里奥从一个水管进去,会从另一个水管里面出来,在这里,马里奥就是流量,这两个水管就是一对veth,我们看下实际操作

  1. 先创建两个网络namespace

    ip netns add ns1
    ip netns add ns2
  2. 创建一对Veth

    ip link add veth1 type veth peer name veth2
  3. 为网络ns1和ns2设置veth

    ip link set veth1 netns ns1
    ip link set veth2 netns ns2
  4. 设置 veth1、veth2的网络地址

    ip netns exec ns1 ifconfig veth1 172.15.0.1/24 up
    ip netns exec ns2 ifconfig veth2 172.15.0.2/24 up
  5. 将ns1的流量默认从veth1中流出

    default代表0.0.0.0/0 即在ns1中的流量都经过veth1的网络设备流出

ip netns exec ns1 route add default dev veth1

通过上面5步,我们就将一头水管(veth1)安在了 ns1 上,另一头水管(veth2)安在了 ns2 上,并且设置了ns1的流量从veth1中流出,这样从ns1里面流出的流量都会经过veth1流向veth2, 也就是流到 ns2上。这样就实现了ns1和ns2的网络互通。

测试一下,我们在ns1中去ping ns2的ip地址看是否可以ping通

可以看到,已经完全可以ping通了,证明通过veth我们已经将这两个隔离的namespace的网络打通了。

bridge

bridge也就是网桥,它是一个非常简单的玩意,你可以把它理解成一个交换机,只不过它只有两个口,并且是一个虚拟的网络设备。

  1. 创建一个网桥
    brctl addbr br0
  2. 挂载网络设备
    brctl addif br0 eth0
    brctl addif br0 veth1
  3. 配置路由规则
    # 将宿主机上的某个网段请求路由到br0的网桥上
    route add –net 172.15.0.2/24 dev br0
    我们将网桥br0一端挂在了eth0网卡上,另一端挂在了 veth1 上这样流量就能从宿主机流到我们的隔离的ns1上

2. iptables

解决了容器的namesepace与宿主机之间的通信,我们看下如何解决ns与外部网络的通信,我们知道,ns的ip地址是我们自己定义的,这样当ns去访问外部网络时,外部网络是不认识这个请求包里面的源地址的,而外部网络也没办法去访问我们ns里面的ip地址,因为它只认识我们宿主机的ip地址。这时我们就需要用到iptables了。

2.1 MASQUERADE

iptables中的MASQUERADE功能可以帮助我们更改请求包的源地址,这样当ns请求外部网络时,我们把源地址改成我们宿主机的是不是就可以了,看下实际配置:

  1. 打开ip转发
    sysctl -w net.ipv4.conf.all.forwarding=1
  2. 对ns1中发出的包添加地址转换(更换源地址)
    iptables -t nat -A POSTROUTING -s 172.15.0.0/24 -o eth0 -j MASQUERADE

2.2 DNAT

iptables中的DNAT功能可以修改我们请求包的目的地址,并将请求转发到我们目的地址上面,这样当外部网络访问我们宿主机的某个端口时,我们将该包的目标地址改成我们ns的地址,直接转发到我们ns里面是不是就可以了,看下实际配置:

将宿主机上80端口的请求转发到ns1的ip上

iptables -t nat -A POSTROUTING -p tcp —dport 80 -j DNAT —to destination 172.15.0.1:80
附言

以上内容都是我自己的理解,如果理解的有偏差欢迎大家一起留言讨论,针对 iptables 我后续会出一系列教程教大家如何使用这个神器,后续文章都会首发于我微信公众号,欢迎大家关注

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!