下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

第三章 网络(一)

2018-02-27 薛命灯
在这一章,我们将介绍我们的 SDN、SDN 与 Docker 的集成以及我们的新基础设施架构。
在第一章中,Jonathan 提到了我们在推出新功能时需要面临网络方面的挑战,它们并不像在服务器上安装代码然后按下启动按钮那么简单。
新功能需要网络基础设施的支持:
连接性:访问服务的低延迟和高吞吐量;
数据包服务:负载均衡、网络地址转换(NAT)、虚拟私有网络(VPN)、连接性和多路广播。
搭建网络服务是网络工程师的拿手好戏,他们登录到网络设备上,输入一些命令就把事情给办了。搭建网络服务要求工程师对网络相关配置有深入的了解,在发生问题时知道该如何应对。因为存在多个数据中心,情况变得更加复杂,不同数据中心的同一种任务对于网络工程师来说是完全不一样的。
数据中心的网络基础设施变更成为推出新服务的瓶颈所在。所幸的是,在 Riot,为玩家推出的服务出现任何问题都会立即引起大家的注意。r Cluster 平台致力于解决这个瓶颈,接下来我们将深入介绍几个关键组件:叠加网络、Open Contrail 以及我们是如何与 Docker 集成的。

SDN 和叠加网络

不同的人对 SDN 有不同的看法。有些人认为 SDN 就是通过软件来定义网络配置,但在 Riot,SDN 意味着网络特性是可以通过 API 来编程的。
因为网络是可编程的,我们能够以自动化的方式在我们的网络中进行快速的部署。我们只需要一个命令就可以完成部署,完成一个网络变更从几天变成了几分钟,这样我们就有更多时间去做其他事情。
虽然网络设备已经是可编程的,但这些设备的编程接口一直在发生变化,没有一个单独的标准来约束各个设备厂商。所以,要为各种设备接口编写自动化测试就变成一项艰巨的任务。我们意识到,在硬件层之上构建一个统一的 API 抽象层对于 Riot 的网络配置弹性管理来说是至关重要的。于是,我们使用了叠加网络。
叠加网络处于已有的网络之上,运行在叠加网络中的应用程序并不知道叠加网络的存在,因为它们会认为自己是运行在一个物理网络中。如果你们熟悉虚拟机,就会知道这就有点像“物理机中的虚拟机”。一个物理网络可以托管多个虚拟网络。在一个虚拟机里,应用程序会认为自己是运行在一个物理机上,但实际上它们只拥有整个物理机的一小部分。叠加网络的概念和这个有点类似——一个物理基础设施(也就是底层网络)中存在多个虚拟网络。
我们因此可以隐藏掉物理网络的各种细枝末节,Riot 的工程师们本来就不需要了解这些细节。工程师们不会再问类似这样的问题:“它有多少个端口”、“我们的供应商是谁”或者“应该在哪里设置安全策略”。我们为工程师提供了一组统一的 API。Riot 的各个数据中心在有了这套统一的 API 之后,我们就可以在任何时候、任何地方实现自动化。我们也可以使用其他云服务供应商,比如亚马逊、Rackspace、Google Compute 等,我们的 API 仍然可以发挥它的作用。底层的物理网络硬件有可能是思科、Juniper、Arista、戴尔、D-Link、白盒的、黑盒的、一系列承载 10G 端口的 Linux 服务器,这些都不是问题。底层网络必须使用特定的方式(比如使用自动化配置模板)进行构建,这样我们就可以解开底层物理网络配置和服务配置之间的耦合。
维护底层网络也有一定的好处。关注点的分离让底层网络更自由了,它只需专注提供高可用的数据包传输,我们在升级物理网络时无需担心会影响到上层的应用程序。这简化了我们的运维工作,我们可以自由地在各个数据中心之间切换服务,而且避免了厂商锁定。
简而言之,我们认为叠加网络是个好东西。
##Open Contrail当初在评估 SDN 时,我们也调研过其他各种产品。它们有些通过集中控制器来配置物理网络,有些则更像是一个抽象层,将 API 调用转成与特定厂商相关的命令。有些解决方案需要依赖新的硬件,有些则可以运行在现有的基础设施上。有些是由大公司开发的,有些是开源项目,也有一些来自初创公司。简而言之,我们花了大量时间在调研上,要做出选择真的很难。以下是我们的主要需求点:
可以支持我们的新旧数据中心、裸机和云。 稳定的开源项目,不会突然间停止更新。 有专业人士能够提供帮助。最后我们把目光锁定在了 Juniper NetworksOpen Contrail 上。他们推出 Open Contrail 的初衷就是要将它作为一个开源项目,并且与厂商无关,适用于任何一种网络。它的核心是 BGPMPLS,这两种为人们所熟知的协议已经被证实可以处理整个互联网的规模。Juniper 当然不可能在瞬间就消失,而且在我们设计和安装第一个集群过程中,他们为我们提供了很多帮助。
Contrail 由三个主要的组件组成:中心控制器(“大脑”)、v Router(虚拟路由器)和外部网关。每个组件都是一个高可用的集群,所以个别设备的故障并不会影响到整个系统。调用中心控制器的 API 会将所有变更散播到 v Router 和网关上,然后再被转发到网络中。
叠加网络包含了一系列通道,这些通道从一个 v Router 跨越到另一个 v Router。当一个容器要与另一个容器发生交互时,v Router 首会先检查这个容器的位置在哪里,然后在计算节点之间建立通道。接收端的 v Router 检查流入的数据包,验证它们的合法性,然后再转发到目的地。如果容器要与非叠加网络中的实体发生交互,我们就会把数据包发到外部网关。外部网关将通道移除,并把数据包发送到外部网络上,保持容器 IP 原封不动。

集成 Docker

如果我们无法在叠加网络中运行容器,那么之前所提到的一切都只是一种臆想。Contrail 是一款虚拟 SDN 产品,它需要与容器编配器集成在一起,才能达到调度计算实例的目的。Contrail 已经通过 Neutron APIOpen Stack 进行了集成,不过我们使用了自己的编配器 Admiral,所以我们也需要进行自定义集成。另外,ContrailOpen Stack 的集成最初是为虚拟机而设计的,而我们现在需要把它应用在 Docker 容器上。我们与 Juniper 合作,开发了一个叫作“Ensign”的服务,它运行在每一台主机上,负责集成 AdmiralDockerContrail
为了解释我们如何将 DockerContrail 集成在一起,需要先了解一下 Linux 网络。Docker 使用了 Linux 内核的网络命名空间来隔离容器,防止它们互相访问。网络命名空间实际上是一个独立的网络技术栈——网络接口、路由表、iptable 规则。一个网络命名空间中的这些元素只会被应用于在该命名空间中启动的进程。这与文件系统的 chroot 有点类似,只不过它指的是网络。
在开始使用 Docker 时,我们有四种方式来配置网络命名空间。宿主网络模式:Docker 将进程置于宿主网络命名空间中,是完全不隔离的。桥接网络模式:Docker 创建了一个 Linux 桥,将容器网络命名空间连接到宿主网络中,同时管理着从宿主网络到容器的 NAT iptable 规则。
From 网络模式:Docker 使用另一个容器的网络命名空间。无网络模式:Docker 创键一个没有接口的网络命名空间,也就是说,进程无法连接到命名空间外部。
无网络模式通常用于第三方网络集成,与我们的场景非常契合。在启动容器之后,第三方实体可以将必要的组件安插到网络命名空间中,将容器连接到网络。不过,这里有一个问题:容器需要事先启动,而且在刚开始的一段时间内是没有网络的。这对于应用程序来说不是什么好事,因为它们都想知道容器在启动时的 IP 地址是什么。虽然 Riot 的开发人员可以通过重试的方式解决这个问题,但我们不想给他们添加太多麻烦。另外,很多第三方容器无法处理该问题,我们也无法改变他们。所以,我们需要一个全盘的解决方案。
为了解决这个问题,我们借鉴了 Kubernetes 的一些想法,引入了 " 网络 " 容器的概念," 网络 " 容器会在主容器之前启动。我们以无网络模式启动该容器,在分配到 IP 地址之后再启动主应用容器,然后使用 From 网络模式将主应用容器连接到网络容器的网络命名空间中。这样一来,应用程序在启动时就有了可运行的网络栈。
在物理主机上启动一个新容器时,v Router 会为它分配一个虚拟 NIC、一个全局唯一的 IP 地址以及路由和安全策略。这与默认的 Docker 网络配置非常不一样,因为同一台主机上的容器共享同一个 IP 地址,而其它们之间可以自由地发生交互。这有悖于我们的安全策略,因为我们要求应用程序之间是不能发生交互的。为每个容器分配单独的 IP 地址简化了我们的网络配置和安全策略,同时避免了容器共享 IP 地址给我们带来的复杂性。
SDN 和基础设施自动化之路并不平坦,而在我们前面仍然有一段很长的路要走。我们已经学会了如何构建自助服务网络、如何调试叠加网络的连接问题、如何应对新故障。我们跨越两代网络架构部署了 SDN,并将它与好几个 " 遗留 " 数据中心集成在一起。我们花了很多精力进行自动化,学会如何确保系统的可信度。Riot 的工程师现在每天基于这个自助工作流来开发、测试和部署他们的服务,它俨然已经成为他们开发工具箱中必不可少的工具。
更多内容,请点击《英雄联盟 | 在线服务运维之道》阅读专题全部文章。
 写留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。