栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux 网络命名空间与 Docker 容器网络(三)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux 网络命名空间与 Docker 容器网络(三)

前言

在第一篇文章中,我们知道了怎样使用网桥将一个主机上的容器连接起来。

在第二篇文章中,我们知道了如何使得容器可以访问外网以及容器内的服务被外网访问。

这篇文章就讲述如何将多个主机【节点】上的容器连起来,使得它们之间可以通信,而且还可以访问外网【搭建集群】。主要内容来自这篇文章。实验的环境如下:

我们有3个节点,第一个节点称作头节点有两个接口,一个连接外网,一个连接内网。另外两个节点只有一个接口,和头节点一起连接到内网 10.141/16 。

接下来介绍两种方案。

方案一

方案一是在主机上使用网桥+NAT的方式,使得主机上上的容器可以互连且上外网,就像我们前两篇文章中介绍的那样:

与另一个主机上的容器互连

我们重点来看下如何与另一个主机的容器互连,我们搭建的实验环境如下【没有画出头节点】:

两个主机通过都在同一个局域网 10.141/16 。我们想为每个主机分配一个子网,这样每个主机都可以托管一些容器。第一个主机就给分配 172.19.35/24 网络,第二个主机分配 172.19.36/24 网络,这两个网络都在 172.19/16 网络中,于是这个集群最多支持 255 个主机【节点】。

在第一个主机的操作命令如下:

# 配置 eth0
ifconfig eth0 10.141.0.1/24
ip route add default via 10.141.255.254

# 创建网络命名空间和 veth
ip netns add ns0
ip link add veth0 type veth peer name ceth0
ip link set dev veth0 up

# 创建网桥
ip link add br0 type bridge
ip link set veth0 master br0
ifconfig br0 172.19.35.1/24 up

ip link set ceth0 netns ns0
# 配置容器内的接口IP和默认路由
ip netns exec ns0 ip link set dev lo up
ip netns exec ns0 ifconfig ceth0 172.19.35.2/24 up
ip netns exec ns0 ip route add default via 172.19.35.1

# 添加SNAT规则使得容器可以访问外网
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

第二个主机上的操作也是类似,只是出接口 eth0、网桥 IP、容器使用的 IP 不一样:

ifconfig eth0 10.141.0.2/24
ip route add default via 10.141.255.254

ip netns add ns0
ip link add veth0 type veth peer name ceth0
ip link set dev veth0 up

ip link add br0 type bridge
ip link set veth0 master br0
ifconfig br0 172.19.36.1/24 up

ip link set ceth0 netns ns0
ip netns exec ns0 ip link set dev lo up
ip netns exec ns0 ifconfig ceth0 172.19.36.2/24 up
ip netns exec ns0 ip route add default via 172.19.36.1

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

做如上操作后,两台主机上的容器可以访问自己内部的容器也可以访问外网,但是不能访问另一台主机上的容器。这是因为主机上没有添加相应的路由,在第一个主机上加上路由:

ip route add 172.19.36.0/24 via 10.141.0.2

第二个主机上加上路由:

ip route add 172.19.35.0/24 via 10.141.0.1

这样在第一个主机上的容器和第二个主机上的容器就可以互 ping 了:

root@myubuntu-1:~# ip netns exec ns0 ping 172.19.36.2        
PING 172.19.36.2 (172.19.36.2) 56(84) bytes of data.
64 bytes from 172.19.36.2: icmp_seq=1 ttl=62 time=0.146 ms
64 bytes from 172.19.36.2: icmp_seq=2 ttl=62 time=0.235 ms
^C
--- 172.19.36.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1026ms
rtt min/avg/max/mdev = 0.146/0.190/0.235/0.046 ms

root@myubuntu-2:~# ip netns exec ns0 ping 172.19.35.2    
PING 172.19.35.2 (172.19.35.2) 56(84) bytes of data.
64 bytes from 172.19.35.2: icmp_seq=1 ttl=62 time=0.228 ms
64 bytes from 172.19.35.2: icmp_seq=2 ttl=62 time=0.276 ms
^C
--- 172.19.35.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1028ms
rtt min/avg/max/mdev = 0.228/0.252/0.276/0.024 ms

由于使用了 NAT,容器内看到的源 IP 是主机上 eth0 的 IP 而不是容器的 IP 。

方案二

下面介绍方案二,它的思路很新颖,不使用网桥和 NAT ,仅仅使用路由。

就是实现下面的效果:

下面介绍下主机1上如何操作:

容器与主机互连

它不使用网桥,而是使用链路本地地址 169.254.1.1,具体而言:

  • 添加默认路由下一跳为 169.254.1.1
  • 添加到 169.254.1.1 的从 ceth0 出的路由
  • 在 veth0 上开启代理 ARP
  • 在 ceth0 配置主机IP,掩码为32位

这样到主机的数据包就走三层了。相当于 veth0 是个三层接口!

具体操作如下:

ifconfig eth0 10.141.0.1/24
ip route add default via 10.141.0.254

ip netns add ns0
ip link add veth0 type veth peer name ceth0
ip link set dev veth0 up


ip link set ceth0 netns ns0
ip netns exec ns0 ip link set dev lo up
# 注意掩码是32位!
ip netns exec ns0 ifconfig ceth0 172.19.35.2/32 up

# 配置ARP代理等
echo 1 > /proc/sys/net/ipv4/conf/veth0/rp_filter
echo 1 > /proc/sys/net/ipv4/conf/veth0/route_localnet
echo 1 >/proc/sys/net/ipv4/conf/veth0/proxy_arp
echo 0 >/proc/sys/net/ipv4/neigh/veth0/proxy_delay
echo 1 >/proc/sys/net/ipv4/conf/veth0/forwarding

# 添加到 169.254.1.1 的路由
ip netns exec ns0 ip route add 169.254.1.1 dev ceth0 
# 添加默认路由
ip netns exec ns0 ip route add default via 169.254.1.1

ip route add 172.19.35.2 dev veth0 scope link

这样容器就可以与主机互 ping 了:

root@myubuntu-1:~# ip netns exec ns0 ping 10.141.0.1
PING 10.141.0.1 (10.141.0.1) 56(84) bytes of data.
64 bytes from 10.141.0.1: icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from 10.141.0.1: icmp_seq=2 ttl=64 time=0.063 ms
^C
--- 10.141.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1014ms
rtt min/avg/max/mdev = 0.029/0.046/0.063/0.017 ms

主机2上的操作也是类似。

不同主机上的容器互连

和方案一一样,在主机 1 加一条路由:

ip route add 172.19.36.0/24 via 10.141.0.2

主机 2 加一条路由:

ip route add 172.19.35.0/24 via 10.141.0.1
连到外网

方案一连到外网是在主机上配置 NAT 规则,方案二的话不同的地方是在头节点配置
NAT 规则:

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE -s 172.19.0.0/16

并且添加合适的路由:

ip route add 172.19.35.0/24 via 10.141.0.1
ip route add 172.19.36.0/24 via 10.141.0.2

这样所有容器之间的访问都没有NAT!达到了我们要的效果。

个人疑问:第一种方案使用这种方式也可以做到不需要在各自的主机配置 NAT,使容器访问外网,效果不是一样的吗?

Docker Swarm

这里引用作者的原话:

What I showed in the last section is basically how Docker sets up its bridge networking. The routing rules to make the containers see each other come from me. What Docker Swarm and other networking solutions for Docker use instead is usually overlay networking, like VXLAN. VXLAN encapsulate layer 2 Ethernet frames within layer 3 UDP packets. This provides layer 2 visibility to containers across hosts. I didn’t show this approach because the routing rules were simpler, and also because I prefer the Calico approach【第二种方案】, that I will present in this section.

大意是说 Docker Swarm 在不同主机间容器互连使用的方案是 overlay 网络,比如 VXLAN。
为什么不使用 NAT 的方案更好?作者是这么说的

Some of you may already know Kubernetes. It’s the most popular (any my favorite) container orchestrator. What it basically does is providing declarative APIs to manage containers. Restarts upon failures, replicas’ scaling, upgrading, ingress, and many other things can be managed automatically by Kubernetes. For all this magic to happen, Kubernetes imposes some restrictions on the underlying infrastructure. Here is the section about the networking model:

  • all containers can communicate with all other containers without NAT
  • all nodes can communicate with all containers (and vice-versa) without NAT
  • the IP that a container sees itself as is the same IP that others see it as.
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/828554.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号