如何用Kubernetes建立CDN


image
趁着假期,翻译了一篇文章,已经发表在dockerone。

kubeCDN:基于Kubernetes的自托管CDN。GitHub: https://github.com/ilhaan/kubeCDN。

在这篇文章中,将讨论为什么要有CDN服务,如何用Kubernetes建立CDN服务,然后重点讨论kubeCDN的设计和实现,它是一个用于简化多地域部署Kubernetes集群并且提供CDN服务的工具,以便在全球范围内部署高可用的服务。

用户越多,问题就越多

互联网改变了人们交流观点和分享信息的方式。然而,这种传递信息的方式并不尽完美。因为互联网已经成为用户获取信息的第一站,任何阻碍或减缓用户获取信息的方式都让人不爽。我们都经历过为了等待加载完共享文档或者视频流而不得不等待几秒或几分钟的"煎熬"。这种"煎熬", 会影响用户体验,用户会寻求其他的替代方案。没有任何公司会想因为这种差的用户体验而失去用户,但是避免这种问题,会有些技术上的挑战。

就像下面的图,用户一直在等待,等待…
Suffering

用户感知到互联网服务延迟的主要原因是运行服务的服务器距离用户比较远。如果服务器在上海,而用户在纽约,那距离上增加的延迟会导致数据获取较慢,用户体验变差。

图:用户距离服务器越远,延迟就越大
image

将服务器部署到离用户位置更近的地方可以减少这种延迟,但这样做并不是那么容易,因为管理全球基础设施资源需要投资很大。

解决方案:内容分发网络(CDN)

克服上述问题的一种方法是使用第三方CDN提供商。像Akamai、CloudFlare和Fastly这样的CDN提供商将企业在一个地区建立的基础设施服务扩展至全球,让全球用户受益。

CDN提供商通过在其全球不同节点(PoPs)之间缓存静态内容,减少用户的访问时延。这些PoPs由若干边缘服务器组成,为请求静态资源(如:图片)的用户提供缓存。如果没有找到请求的资源,则边缘服务器将从源服务器或就近的服务器获取资源。这种方式减少了不同地域的用户访问服务的时延。

越多更多的关于CDN的知识,参考

CDN服务商的问题

尽管CDN提供商提供了一种方便的解决方案,但是这种方式也存在一定的问题。

第一个问题是安全问题。用第三方的CDN服务商,开始依赖外部服务来确保用户获得最佳体验,最重要的是失去了对用户数据安全性的控制。第三方CDN提供商系统中的漏洞(比如2017年的这个漏洞)会对用户的安全和隐私造成严重影响。

第二个问题,CDN提供商可能并不总是考虑你的最佳利益,他们会优先考虑他们的利润而不是你的服务质量。

最重要的问题是CDN服务商可以拿到你的业务数据。CDN服务商可以确定你的用户的所在位置、用户使用服务的时间以及他们使用何种设备访问服务。这样的业务数据对你的竞争对手非常有价值,而向第三方泄露信息会使你的业务有客户流失的风险。

对于许多团队来说,这些利弊可能值得使用CDN服务商的便利性。然而,对许多顶尖的工程团队,比如Netflix和LinkedIn,已经决定在内部解决这个问题。如果想做同样的事情并构建自己的CDN,就尝试用kubeCDN。

kubeCDN

kubeCDN可以解决上述的问题。kubeCDN是一个基于Kubernetes的自托管CDN。作为一个自托管的解决方案,可以维护对基础设施的完全控制。它消除了第三方CDN服务商的需要,并拥有了对从服务器到用户设备的数据流的控制。

架构设计

kubeCDN使用Terraform在选定的区域部署EKS和AWS基础资源。Route53,用于在多个区域之间路由用户,而ExternalDNS用于在部署新服务时自动创建DNS记录。

下图演示了在kubeCDN中如何使用Terraform。
image

Terraform用于部署kubeCDN所需的基础设施,Route53用于将用户流量路由到特定区域。如下面的图,在两个AWS区域us-east-1和us-west-2中分别部署了一个视频服务器,在Route53上为区域设置一个托管区域,并为部署集群的每个区域设置了记录。使用基于延迟的路由策略将用户路由到延迟最低的区域。在这个演示中,用户总是被路由到地理上最近的区域。然而,情况并非总是如此。internet上的延迟可能随时间而变化,Route53使用这些度量值来确定在实现路由策略时将用户路由到何处。

image
上面的图展示了Route53如何使用两个区域中创建的集群来路由用户流量。旧金山的用户被路由到us-west-2中的集群,而不是us-east-1中的集群,因为到us-west-2提供了较低的延迟。

Route53上还有其他一些路由策略,可以与kubeCDN一起使用,以适应各种应用程序需求。具体参考

解决的问题

kubeCDN使基础设施服务可以在几分钟内轻松地扩展到全球不同地域。部署上述所述的集群所需的基础设施大约需要15分钟,与使用AWS控制台进行手动部署相比,效率有了显著的提高。

除了易于扩展之外,kubeCDN还可以通过在低用户活动期间分解区域来优化基础设施成本。当预算紧张时,为了确保最大的盈利能力,这种基础设施成本优化水平可能是至关重要的。

开发的挑战

和其他项目一样,在开发kubeCDN时遇到了一些问题。下面将描述两项比较难解决的问题。

Terraform 代码重构

kubeCDN中用于将EKS集群部署到某个区域的Terraform代码是基于HashiCorp 单独创建的代码库。尽管代码非常清晰,有详细的说明,但它不能进行多区域部署。部署的区域都是硬编码的,需要为每个所需区域复制存储库。这是一个繁琐的手工过程,很容易由于人为错误导致配置错误。它还将导致管理结构的随意性,使监测基础设施和优化成本变得困难。

重构Terraform代码是解决这个问题的一种方法,但是,挑战在于如何进行重构。在阅读了相关的文章并查看了另一个具有类似需求的开源项目之后,认为下面所示的结构是现阶段组织项目基础设施部分的最佳方式。

├── terraform              (Dir containing all infrastructure code) 
    ├── cluster            (EKS cluster components) 
    │   ├── main.tf
    │   ├── outputs.tf
    │   ├── rbac.yaml
    │   └── variables.tf
    ├── main.tf            (Main .tf file where regions are specified) 
    └── variables.tf
                           (Some files have been removed for brevity)

在上面显示的目录结构中,main.tf是指定所有所需区域的地方。区域部署使用以下代码段定义:

module "<name-for-region-deployment>" {
	source = "cluster"
	region = "<AWS-region>"
}

这使得在一个配置文件中轻松定义新区域成为可能,而这个配置文件也易于管理。

ExternalDNS的问题

ExternalDNS是一个通过Kubernetes资源动态配置DNS记录的工具。可以与DNS服务商(如Route53等)对接。当将新服务部署到Kubernetes集群(例如web服务器)时,ExternalDNS创建DNS记录,以便使用公共DNS服务器发现web服务器。

对于kubeCDN,计划使用ExternalDNS为不同的区域部署自动创建DNS记录,并配置Route53使用基于延迟的路由策略将用户路由到延迟最低的区域。虽然能够做到这一点,但必须解决一些与ExternalDNS有关的问题,这些问题无法完全自动化不同区域服务的DNS记录的动态配置。

kubeCDN的改进

开发kubeCDN只用了三周的时间,还有非常大的改进空间,其中有几个方面的改进方向可以让它更加强大。

不同云服务商的支持

目前,kubeCDN仅基于AWS。这主要是因为Insight的Fellows在项目中可以使用AWS。对多个云服务商(如GCP和Azure)的支持,会避免仅使用一个云服务商,在云服务商宕机时造成的问题。

目前,kubeCDN是用AWS提供的eks管理的Kubernetes服务。要支持其他云服务商的支持,需要满足以下条件之一:

  • 合并对所有云服务商的Kubernetes服务。虽然这将简化部署,但是将不同的托管服务合并到kubeCDN中将非常困难。
  • 使用自定义Kubernetes部署。这将涉及使用kops安装一个自定义Kubernetes集群,使用来自所选云服务商的基础设施。

尽管kops安装Kubernetes的方式,从长期考虑似乎是最佳的选择,但需要大量的开发工作。即便如此,采用kops的Kubernetes安装在未来将为kubeCDN带来较大的灵活性。

多地域的自动伸缩

虽然在全球范围内扩展基础设施可以极大提高用户体验,但是在许多地方,并没有必要7*24小时地运行服务。从盈利的角度来看,移除一个地区的基础设施,并让该地区为数不多的(或者可以忽略不计的)用户有较多的延迟,会带来成本的一定降低。

为了实现这一点,需要一个监视方案来监视所选的度量。当该指标在某个区域达到预定义的阈值时,可以移出该地域的基础设施服务。如果某个特定区域的用户出现峰值,则可以使用类似的阈值在预先定义的区域中自动启动扩展该地域的基础设施服务。

预定义区域列表

kubeCDN使得将EKS集群部署到新区域变得很容易。但是,有比当前为每个区域复制三行代码的方法更好的方法来实现这一点。在文件中列出所需区域是一种更简洁的方法。

该特性可以将与前面提到的多地域自动伸缩特性很好地结合在一起。向kubeCDN提供两个区域列表,其中一个区域的基础设施服务需要连续运行,另一个区域可以自动伸缩,这将极大地简化基础设施服务管理。

总结

kubeCDN简化了Kubernetes集群的跨地域配置,并可以方便的扩展。由于是自托管的,kubeCDN允许适应独特的基础设施需求,并为基础设施的管理提供了强大的灵活性。

然而,有些限制和增强的功能可以让kubeCDN成为更健壮的工具。其中一些已经在这篇文章中讨论过了。影响未来kubeCDN另一个主要因素是Kubernetes项目本身的改进。预计,随着Kubernetes Federation的成熟,未来kubeCDN的功能和特性将发生巨大的变化。

原文链接: How to build your own CDN with Kubernetes 翻译:范浩