资讯专栏INFORMATION COLUMN

Rancher网络全解读

hss01248 / 1347人阅读

摘要:在每台主机上我们执行列出主机和网络接口。其它的应用服务容器每个容器有两个地址,一个属于子网,另一个属于的子网。虽然这会带来一些性能上的影响,但是可以确保的网络默认是安全的。

本文中,我们首先将Rancher部署到EC2实例上,并且添加新的主机,之后用Rancher的Catalog启动了RocketChat应用,紧接着对运行中的容器的网络接口和其他属性的进行了分析。

同时,我们简要介绍了Rancher的Overlay网络和运行在Network Agent中的辅助服务进程,并通过上面实践中收集的信息构建了Rancher集群中网络通信的概览图。

与此同时,还特别介绍了使用IPSec实现主机间的安全通信。

Rancher 是一个容器管理的完整解决方案,并且即将成为一个完整的容器管理平台。我们对在自己平台上如何处理容器间的网络进行了审慎的思考,并打算用一个简单的例子和大家分享一下Rancher中的网络。Rancher既可以被部署在单机,也能被扩展到数千个节点,在这篇文章中我们只用少量的主机和容器进行讨论。

配置并启动一个容器化的应用

首先我们要配置我们的基础设施,本文使用的是AWS。我们先在EC2上用下面的命令安装Docker并且启动Rancher部署Master节点:

curl -sSL https://get.docker.com | sh - && sudo docker run -d --restart=always -p 8080:8080 rancher/server

Rancher的server在52.40.47.157:8080上被创建好了(需要注意的是:文中涉及的IP地址指向的AWS实例已经在发文的时候被销毁了,文中所列IP仅作示例使用)。通过EC2的console,我们再新增两个主机——H1和H2,用来跑我们的应用程序容器。下图展示了我们主机的逻辑拓扑关系:一个节点用来跑Rancher的Server,另外两个跑Rancher agent:

为了方便描述容器间的网络,我们需要先启动一个容器化的应用服务。用Rancher的Catalog创建应用非常方便,这里我们选择Rocket Chat。Rocket Chat的应用模板有三个容器镜像组成,分别是:mongo、rocketchat和hubot。启动之后Rocket Chat被分配到:52.11.188.233:3000(关于更详细的关于Rancher Catalog的攻略可以阅读这里:http://docs.rancher.com/ranch...)。

探索基础设施

Rocket Chat跑起来后,我们用Rancher UI来对H1和H2的情况一探究竟。点击Infrastructure标签页看看有哪些容器跑在宿主机上:

图中可以看出,rocketchat容器被调度到H1上了,剩下的两个容器:mongo和hubot被调度到H2上。截图中我们还能看到每个节点都运行着一个network agent(注意:只有当有容器被调度到当前宿主机后,network agent才会被创建)。各个容器的IP地址如截图中所示——这些IP对于我们后面讨论很重要。

我们可以下载machine config文件以获得主机更详细的信息:

解压下载下来的machine configs之后,我们可以找到主机的私钥和公钥以及一些其他相关的配置文件。用私钥我们ssh到主机。在每台主机上我们执行ifconfig列出主机IP和网络接口。下面是在H1上的结果(精简后的),可以看到docker0网桥的IP(172.17.0.1)和eth0接口地址(172.31.38.255):

`ubuntu@leo-alpha-h1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:64:4e:c0:c6
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:64ff:fe4e:c0c6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1114933 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1437072 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:198587596 (198.5 MB)  TX bytes:1813282482 (1.8 GB)
eth0      Link encap:Ethernet  HWaddr 02:b8:4d:31:40:f3
          inet addr:172.31.39.255  Bcast:172.31.47.255  Mask:255.255.240.0
          inet6 addr: fe80::b8:4dff:fe31:40f3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:2187296 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1382626 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
         RX bytes:2627031496 (2.6 GB)  TX bytes:277190533 (277.1 MB)`

在H2上重复上面的过程,获得相似的结果:docker0的IP是172.17.0.1,物理网卡eth0的地址是172.31.38.133。

接下来,我们深挖每台主机上运行的容器的状态并查看每个网络接口上的IP地址。在H1上我们用sudo docker ps 和 sudo docker exec:

ubuntu@leo-alpha-h1:~$ sudo docker ps | awk "{print $1"	"$2}"
CONTAINER    ID
b6a27f5fd2fe rocketchat/rocket.chat:latest
f0cd5839d719 rancher/agent-instance:v0.8.1
132d6ad0c6b9 rancher/agent:v1.0.1

ubuntu@leo-alpha-h1:~$ sudo docker exec -it b6a27f5fd2fe /bin/bash
rocketchat@b6a27f5fd2fe:/app/bundle$ ip addr
17: eth0:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:14:82:66:7d:fd brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.42.64.98/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::14:82ff:fe66:7dfd/64 scope link
       valid_lft forever preferred_lft forever
ubuntu@leo-alpha-h1:~$ sudo docker exec -it f0cd5839d719 /bin/bash
root@f0cd5839d719:/# ip addr
11: eth0:  mtu 1500 qdisc noqueue state UP group default
    link/ether 02:14:82:82:b0:68 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.42.162.246/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet 169.254.169.250/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::14:82ff:fe82:b068/64 scope link
       valid_lft forever preferred_lft forever

在H2上重复上述过程,我们得到了在H1和H2上运行着的容器的信息:

HOST Container Name MAC Address IP addresses
H1 rocket.chat 02:14:82:66:7d:fd 172.17.0.5/16
10.42.64.98/16
H1 agent-instance 02:14:82:82:b0:68 172.17.0.2/16
10.42.162.246/16
169.254.169.250/32
H2 hubot 02:14:82:36:a4:6c 172.17.0.5/16
10.42.42.48/16
H2 mongo 02:14:82:2d:a0:55 172.17.0.4/16
10.42.148.239/16
H2 agent-instance 02:14:82:ab:9d:5d 172.17.0.2/16
10.42.69.59/16
169.254.169.250/32

从上表中我们发现每个容器都有一个网络接口eth0。除此之外,Rancher的network agent容器(上表中的agent-instance)用三个IP地址:一个属于Docker的子网(172.17.X.X),一个属于Rancher的子网(10.42.X.X),以及第三个属于链路本地地址子网(169.254.X.X)。其它的应用服务容器(hubot、mongo、rocketchat)每个容器有两个IP地址,一个属于Docker子网,另一个属于Rancher的子网。

Hops and Traceroutes

让我们继续了解下Rancher中容器间的数据通信。从mongo 容器 ping hubot 容器(这俩是在同一台宿主机上):

root@ad4e749d2658:/# ping -c4 hubot
PING hubot.rocket-chat.rancher.internal (10.42.42.48): 48 data bytes
56 bytes from 10.42.42.48: icmp_seq=0 ttl=64 time=0.041 ms
56 bytes from 10.42.42.48: icmp_seq=1 ttl=64 time=0.046 ms
56 bytes from 10.42.42.48: icmp_seq=2 ttl=64 time=0.075 ms
56 bytes from 10.42.42.48: icmp_seq=3 ttl=64 time=0.060 ms
--- hubot.rocket-chat.rancher.internal ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.041/0.055/0.075/0.000 ms
root@ad4e749d2658:/#

网络从mongo容器可达hubot容器,从traceroute的结果也可以确认两者直接只有一跳:

root@ad4e749d2658:/# traceroute hubot
traceroute to hubot (10.42.42.48), 30 hops max, 60 byte packets
 1  ip-10-42-42-48.us-west-2.compute.internal (10.42.42.48)  0.029 ms  0.012 ms  0.015 ms
root@ad4e749d2658:/#

我们再看下从mongo容器到rocketchat容器的traceroute结果(两者在不同的主机上):

root@ad4e749d2658:/# traceroute rocketchat
traceroute to rocketchat (10.42.64.98), 30 hops max, 60 byte packets
 1  * * *
 2  ip-10-42-162-246.us-west-2.compute.internal (10.42.162.246)  1.391 ms  1.229 ms  1.168 ms
 3  ip-10-42-64-98.us-west-2.compute.internal (10.42.64.98)  1.137 ms  1.108 ms  1.086 ms
root@ad4e749d2658:/#

上面的结果中可以看出从mongo到rocketchat容器有三跳,并且中间经过了IP地址为10.42.162.246的网络,这个正是在H1上运行着的network agent的地址。

Mongo容器中的ARP Table和IPSec

我们从mongo容器中看下此时的ARP table:

root@ad4e749d2658:/# cat /proc/net/arp
IP address HW type Flags HW address Mask Device
169.254.169.250 0x1 0x2 02:14:82:ab:9d:5d * eth0
10.42.64.98 0x1 0x2 02:14:82:ab:9d:5d * eth0
10.42.69.59 0x1 0x2 02:14:82:ab:9d:5d * eth0
10.42.42.48 0x1 0x2 02:14:82:36:a4:6c * eth0
172.17.0.1 0x1 0x2 02:42:6c:a6:5e:b8 * eth0
root@ad4e749d2658:/#

在ARP table中rocketchar容器的IP地址10.42.64.98的MAC地址是02:14:82:ab:9d:5d,这和在H2上运行着的network agent eth0的MAC地址是一样的。

让我们看下IPSec的信息:

root@9cdde771152c:/# swanctl --list-conns
conn-52.11.188.233:
  local:  %any
  remote: 52.11.188.233
  local pre-shared key authentication:
  remote pre-shared key authentication:
  child-52.11.188.233: TUNNEL
    local:  0.0.0.0/0
    remote: 0.0.0.0/0
root@9cdde771152c:/#

从结果中我们可以看出H2和H1之间有一条加密的通信通道52.11.188.233。上述结果的逻辑关系可由下图所示:

Rancher中的Overlay网络

我们通过查看H1和H2上容器的IP地址可以看出,Docker分配的IP地址在不同的主机上并不是唯一的。例如,相同的IP地址172.17.0.5在H1上分配给了rocketchat容器,而在H2上则被分配给了hubot容器,所以多带带使用Docker分配的IP不能获得唯一的地址。为了解决这个问题,Rancher给集群中运行着的每一容器分配了一个唯一的IP地址,本文例子中的地址是从从ranher的默认子网10.42.0.0/16分配而来。

IPSec

在Rancher看来,安全性是头等重要的事情!根据Rancher的设计,Rancher的集群的环境既可以公有云也可以是私有云,所以就不能对主机间的通讯信道做任何假设。我们希望从主机流出的数据是安全的,因此我们选择用IPSec去构建主机间的完整网络拓扑。虽然这会带来一些性能上的影响,但是可以确保Rancher的网络默认是安全的。未来的版本里我们可能会提供选项关闭IPsec。

Rancher用strongSwan来配置IPSec。其中strongSwan的组件Charon daemon用来实现IKEv2协议。如果想要看完整的拓扑细节,我们可以用命令swanctl:

root@f0cd5839d719:/# swanctl --list-sas
conn-52.11.198.155: #71, ESTABLISHED, IKEv2, 2146471635b90a25:1dc18102c0c48357
  local  "172.17.0.2" @ 172.17.0.2
  remote "172.17.0.2" @ 52.11.198.155
  AES_CBC-128/AES_XCBC_96/PRF_AES128_XCBC/MODP_2048
  established 524s ago, rekeying in 12694s
  child-52.11.198.155: #1, reqid 1234, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
    installed 459878s ago
    in  cb2952a7,      0 bytes,     0 packets
    out c0992075,      0 bytes,     0 packets
    local  0.0.0.0/0
    remote 0.0.0.0/0
conn-52.11.198.155: #70, ESTABLISHED, IKEv2, ff2a5d9495f14efe:dda2d2a6df6a1cf3
  local  "172.17.0.2" @ 172.17.0.2
  remote "172.17.0.2" @ 52.11.198.155
  AES_CBC-128/AES_XCBC_96/PRF_AES128_XCBC/MODP_2048
  established 8076s ago, rekeying in 5913s
  child-52.11.198.155: #2, reqid 1234, INSTALLED, TUNNEL-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
    installed 459859s ago
    in  cf604805, 13790077094 bytes, 11532487 packets
    out cb46151e, 776570467 bytes, 9019180 packets
    local  0.0.0.0/0
    remote 0.0.0.0/0
Network Agent 服务

如果在Network Agent容器中列举所有在跑的进程,我们可以看到几个关键的服务在运行:rancher-dns,rancher=net等。rancher-net进程是Rancher网络服务的核心,它的作用是用strongSwan 和 charon创建IPSec网络。rancher-net的源代码可以在https://github.com/rancher/ra...查看。类似的,rancher-dns服务的职责是解析容器的名字和IP地址,其代码可以在https://github.com/rancher/ra...查看。

通过应用容器内的/etc/resolv.conf文件我们可以看到容器的nameserver指向NetworkAgent的地址169.254.169.250。

rocketchat@b6a27f5fd2fe:/app/bundle$ cat /etc/resolv.conf
search us-west-2.compute.internal rocket-chat.rancher.internal rocketchat.rocket-chat.rancher.internal rancher.internal
nameserver 169.254.169.250
总结

本文中,我们首先将Rancher部署到EC2实例上,并且添加新的主机,之后用Rancher的Catalog启动了RocketChat应用,紧接着对运行中的容器的网络接口和其他属性的进行了分析。

同时,我们简要介绍了Rancher的Overlay网络和运行在Network Agent中的辅助服务进程,我们通过上面实践中收集的信息构建了Rancher集群中网络通信的概览图。

与此同时,还特别介绍了使用IPSec实现主机间的安全通信。

接下来......

Rancher中即将到来的几点对于网络的改进:

采用CNI/libnetwork 接口

目前网路中由于给每个容器引入了第二个IP地址,对于一些只能使用网卡第一个IP地址的应用带来了一些问题。我们打算改用CNI/libnetwork的方案,这样可以保证容器只有的默认网络接口只有一个IP地址。于此同时,用户也可以方便的使用社区中很多其他的网络技术。

VXLAN支持

对于Rancher原生网络,我们打算除了IPSec外添加对VXLAN的支持。

多网络

在接下来的发行版中,我们打算为每一个Rancher支持的环境提供多个相互之间隔离的网络。

期待您的反馈!

希望这篇文章可以对您深入了解Rancher的网络提供有价值的信息。一如既往,您的任何问题和困惑都可以通过论坛 https://forums.rancher.com 或者微信公众号(@RancherLabs )联系我们,我们的社区有里一群优秀和充满激情的小伙伴期待与您的沟通!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26770.html

相关文章

  • Rancher v1.2:网络架构解读

    摘要:在之前的版本上,用户时常抱怨的网络只有,没有其他选择。而容器社区的发展是十分迅猛的,各种容器网络插件风起云涌,欲在江湖中一争高下。同样是基于,使用提供的,网络配置信息以方式注入。 在之前的Rancher版本上,用户时常抱怨Rancher的网络只有IPsec,没有其他选择。而容器社区的发展是十分迅猛的,各种容器网络插件风起云涌,欲在江湖中一争高下。Rancher v1.2版本中与时俱进,...

    0x584a 评论0 收藏0
  • Rancher v1.2:网络架构解读

    摘要:在之前的版本上,用户时常抱怨的网络只有,没有其他选择。而容器社区的发展是十分迅猛的,各种容器网络插件风起云涌,欲在江湖中一争高下。同样是基于,使用提供的,网络配置信息以方式注入。 在之前的Rancher版本上,用户时常抱怨Rancher的网络只有IPsec,没有其他选择。而容器社区的发展是十分迅猛的,各种容器网络插件风起云涌,欲在江湖中一争高下。Rancher v1.2版本中与时俱进,...

    tinysun1234 评论0 收藏0
  • Rancher 1.5解读:企业级使用,ready!

    摘要:元数据性能增强通过缓存元数据信息,我们大大增强了的元数据服务。这减少了数据库抖动,也减少了传递到每个元数据服务的元数据需要占用的空间。由于许多服务都依赖于元数据,当然这也取决于用户具体的实现方式您应该可以明显感受得到性能的整体提升。 Rancher容器管理平台1.5版已正式与大家见面了。此版本中的各项增强功能,均旨在让Rancher能够更好地支持企业级生产环境中的使用。 在新版本中,额...

    cartoon 评论0 收藏0
  • 如何利用Docker构建基于DevOps的自动CI

    摘要:三私有代码库阿里云使用引言使用肯定离不开和代码的集成。本着代码可靠性,服务器稳定性,功能扩展性综合对比,我们选择使用阿里云的库。 来自用户的DevOps实践分享,分享从开发代码到生产环境部署的一条龙操作的实践及经验, 包含工具技术的选型及考量、私有代码库与私有镜像库的应用等。 (一)容器服务的Rancher选型 1、为什么说是下一代核心技术 从互联网的多次变革说起,早期的C/S架构,到...

    stormzhang 评论0 收藏0
  • Kubernetes仪表盘和外部IP代理漏洞及应对之策

    摘要:近期,仪表盘和外部代理接连被发现存在安全问题。本文将更深入解读这两个安全漏洞的原理会对您的部署造成的影响以及相应的应对之策。在中,仪表盘作为每个集群环境的一部分包含在内但是,部署不受影响,因为充当了仪表盘的身份验证授权和代理。 近期,Kubernetes仪表盘和外部IP代理接连被发现存在安全问题。针对这两个漏洞,Kubernetes发布了相应的补丁版本供会受漏洞影响的用户解决问题。本文...

    everfly 评论0 收藏0

发表评论

0条评论

hss01248

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<