微信号:gh_a523545b1d3e

介绍:深圳睿云智合科技有限公司官方订阅号

Rancher容器网络-floating ip解决方案

2016-08-04 18:05 wise2c


面临的问题

1.在为某一个stack编写Rancher catalog的时候,假设在docker-compose里指定了ports A:B,那么,cattle在调度的时将首先过滤掉所有已经占用了port A的主机;也就意味着假设用户只有4台host作为rancher agent,但是需要运行5个在外网中占用80端口的服务,这显然是不行的。


2.另一方面,客户端通过主机的IP地址来访问Stack提供的服务;一旦由于系统异常,或者微服务内部程序崩溃导致Service被重新调度到其他主机,势必导致访问Stack服务IP地址的更改。为了让客户端不被影响,常见的解决方案是通过使用Rancher提供的external-dns;如果业务在公网,有像AWS的Router-53之类的解决方案;若是自建数据中心也可以通过使用支持RFC-2136的硬件路由器等来实现DNS条目的及时刷新。从当前代码看external-dns已经支持下面的Provider了:


3.但是,通过刷新DNS的方案要么价格昂贵,要么需要自己维护一个Rancher外部的DNS Server,都存在一定缺陷。那么,有没有一种方式,既能够解决端口冲突,又能够解决stack对外服务IP变更的问题呢,答案就是今天我们的主角:floating ip!


解决方案


上一次Alan为大家分享的“关于在Rancher中使用keepalived”中就有提到VIP的概念,只是keepalived需要在Active+Passive的主机之间周期性发送心跳报文,然后基于优先级来判断将VIP绑定到哪一个host,它解决了服务迁移后,访问的目标IP地址变化的问题。而floating ip却是从另一个角度来解决问题。


熟悉openstack的人对floating ip应该都不会陌生,所谓floating ip就是为某台虚拟机绑定的一个外网IP地址。绑定之后,无论该虚拟机在openstack内被迁移到哪一台hypervisor,外网都可以通过floating ip来访问到该虚拟机。


我们再来看Rancher中是怎么引入floating ip的,首先上一张总体模块框图:

从图上我们可以看到,整个floating ip的实现,只需要两个模块,或者说两个微服务:metadata-confd, network-plugin,至于IPAM为什么不需要重新实现,我们后面会讲到。


接下来我们讲一下各个模块功能和作用

Metadata-confd:

这是一个使用了Rancher managed网络的service,通过managed网络,它按照一定的周期从Agent-Instance上polling metadata信息。采用分布式架构,每一个metadata-confd只关注属于自己Host上的容器。但是,也并非所有的container都会触发后续行为,只有该Host上带有“io.rancher.container.floating.ip” 标签的容器有被新增、删除或更新IP的时候,metadata-confd会通过docker client向docker daemon发送操作命令:

需要注意的是,这里的network均是指floating ip所在的网络。

对于metadata-confd的实现方式,除了通过通过周期性polling之外,也可以采用支持rancher backend的confd来生成map文件(包含ip <--> floating ip映射),然后使用confd里面的reload-cmd参数,指定脚本去解析和做后续处理。

当然,这里存在不少坑,大家可以下来自己研究。


FIP Network Plugin:

network plugin是按照CNM的定义来实现的一个libnetwork的remote driver;它使用host网络,遵照docker deamon发送过来的请求指令,实现网络相关的操作。

network plugin所做的事情,我们可以通过下图来理解:

原生的docker bridge driver创建了docker0网桥,然后将所有的container通过link pair挂到桥上。在network root namespace内,通过NAPT规则将对Host上特定port的访问DNAT到container的内部port。

而在Floating IP网络中,FIP network plugin创建了一个新的bridge,然后将label含floating ip的container连接到该bridge上,由于使用了与docker0 共享的default driver的IPAM,因此,FIP network bridge的IP地址段不会与docker0所在的网段重叠,从而保障container在连接了两个网段后,路由不会冲突。

按照CNM的定义,docker network plugin主要需要实现以下方法:

  • create network

  • delete network

  • create endpoint

  • delete endpoint

  • join endpoint to network

  • leave endpoint from network


  1. 而FIP network plugin除了要实现基本的功能外,还需要为floating ip添加以下功能:

  2. 当收到join endpoint to network请求时,将floating ip配置到host IP所在的接口上;更新主机的NAT规则,将所有destination IP为FIP的报文DNAT到container的内网IP;

  3. 当container销毁时,执行反向的操作。


这些修改之后,container其实还无法通过FIP回包,为什么呢?

有兴趣的可以研究一下挂载了两个network后container的路由表条目。

至于还需要如何配置,大家可以下来自己实验。


演示:


现在我们来做一个实验,看看floating ip的报文转发是如何工作的:


1.首先在Rancher catalog中选择“Wise2C Floating IP”, 从详细页面看,floating Ip这个stack不需要添加任何配置参数。启动过程中,可以看到:该stack在一个host ”vm-153-5”上启动了两个containers(在每个host上均会被调度);



2.服务启动成功后,我们到host里面可以看到,已经初始化好的network(其网段是172.18.0.0/16)


3. 然后我们再通过rancher创建一个带有标签为“io.rancher.container.floating.ip=192.168.99.200”的container。这里的IP地址就是我们希望为该container绑定的floating ip;


4. 当container启动成功后,metadata-confd会检测到该label,然后向docker daemon发送请求将该container加入到wise2c network;我们可以进入container查看interface详情来了解到。

上图中接口eth1@if9就是接入到wise2c network的接口,其IP地址属于172.18.0.0/16网段。

 5. 再来看host上的IP地址和NAT规则:其中enp0s8就是我们host的default gw对应的出口网卡,可以看到flaoting ip:192.168.99.200已经被添加到上面了;

再看主机的NAT表:


上图就是我们的network-plugin为floating ip创建的基于destination ip的DNAT规则。其中br-d62debee292b是FIP network plugin为wise2c network创建的bridge,下面的DNAT规则是将所有不来自br-d62debee292b,且目标IP地址为192.168.99.200的报文DNAT到172.18.0.2容器。

 6. 接下来就是验证网络:

在客户机(192.168.99.1)上ping floating ip:

 

到wise2c network的bridge上抓包:

可以看到,DNAT规则已经生效。

总结

我们再来整理一下使用场景:

初始化:

1.首先FIP catalog指定在所有运行了rancher agent的主机上均启动floating ip service;

2.在服务启动后,metadata-confd向docker daemon请求创建FIP network,然后开始polling rancher metadata信息;一旦发现本机上存在带FIP标签的容器,metadata-confd就向docker daemon请求将容器接入FIP network;

3.network-plugin从docker daemon收到创建FIP network和将容器接入FIP network的请求后,执行操作。在这个过程中,floating ip被添加到host上默认网关对应的网卡,并更新NAT规则,保障外网访问floating ip的流量被DNAT到容器。


容器迁移:

1.当容器从Host-A迁移到Host-B,Host-A上的docker-daemon会发起将container移出FIP network;network-plugin只需要按照leave endpoint from network的流程,逐一删除NAT规则,并移除host上的floating ip address;

2.在Host-B上执行的操作除少了创建FIP network外,其他操作流程同“初始化”。



              Wise2C               

 

❶ 点击历史信息,查看更多精彩内容

❷ 复制网址在浏览器打开:www.Wise2C.com

❸ 长按二维码,关注睿云智合



如有疑问,请回复管理员,我们将为您细心解答~

 
Wise2C 更多文章 容器内应用日志收集方案 Kubernetes In Rancher Rancher平台部署Percona XtraDB Cluster数据库集群(Galera Cluster for MySQL) 关于持续交付你准备好了吗? 重磅来袭|首届中国金融行业容器技术应用峰会
猜您喜欢 京北方与北京华信智原举行人才共建签约仪式 2013 年中国互联网业发生的最重要的事件有哪些? Scrum Master 面试题 – 你必须知道的22个Scrum基础知识点 “中国互联网+”峰会将于6月16日举行,探寻新方向┃文末有惊喜 TypeScript的崛起