这篇文章已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已失效。

Weave 如何使用 Kubernetes 为 Scope 构建多部署解决方案

今年早些时候,Weaveworks 推出了 Weave Scope,这是一个用于可视化和监控容器化应用和服务的开源解决方案。最近,我们将托管 Scope 服务发布到早期访问计划中。今天,我们想带您了解我们最初是如何原型化该服务的,以及最终如何选择和部署 Kubernetes 作为我们的平台。

云原生架构 

Scope 在数据收集和用户交互之间已经有了一个清晰的内部界限,因此很容易将应用沿此界限拆分,将探针分发给客户,并在云端托管前端。我们按照12因素模型构建了一小组微服务,其中包括

  • 用户服务,用于管理和验证用户账户 
  • 供应服务,用于管理客户 Scope 实例的生命周期 
  • UI 服务,托管所有精美的 HTML 和 JavaScript 内容 
  • 前端服务,根据请求属性路由请求 
  • 监控服务,用于内省系统其余部分 

所有服务都构建为 Docker 镜像,在可能的情况下从头开始。我们知道我们想提供至少 3 个部署环境,这些环境应尽可能地接近一致。 

  • “飞行模式”本地环境,在每个开发者的笔记本电脑上 
  • 开发或预演环境,与生产环境使用相同的基础设施,但使用不同的用户凭证 
  • 生产环境本身 

这些是我们的应用不变性。接下来,我们必须选择我们的平台和部署模型。

我们的第一个原型 

有看似无限多的选择,以及无限多的可能组合。在 2015 年年中考察了现状后,我们决定构建一个原型,使用

  • Amazon EC2 作为我们的云平台,包括用于持久化的 RDS 
  • Docker Swarm 作为我们的“调度器” 
  • Consul 用于引导 Swarm 时的服务发现 
  • Weave Net 用于我们的网络和应用本身的服务发现 
  • Terraform 作为我们的供应工具 

这个设置定义和部署都很快,因此是验证我们想法可行性的绝佳方式。但我们很快遇到了问题。 

  • Terraform 对Docker 作为供应工具的支持非常基础,并且我们在尝试使用它驱动 Swarm 时发现了一些 bug。 
  • 很大程度上是上述问题造成的,使用 Terraform 管理 Docker 容器的零停机部署非常困难。 
  • Swarm 的存在意义在于将多节点容器调度的细节抽象到熟悉的 Docker CLI/API 命令之后。但我们得出结论,该 API 对于生产环境大规模运行时所需的各类操作而言表达能力不足。 
  • 例如,在节点故障的情况下,Swarm 不提供容错能力。 

我们在设计工作流程时也犯了一些错误。

  • 我们在构建时就为每个容器标记了其目标环境,这简化了我们的 Terraform 定义,但实际上迫使我们通过镜像仓库管理版本。这个职责应该属于调度器,而不是制品仓库。 
  • 因此,每次部署都需要将制品推送到所有主机。这使得部署变慢,回滚变得难以忍受。 
  • Terraform 旨在供应基础设施,而不是云应用。这个过程比我们期望的要慢且更具预谋性。将某个新版本发布到生产环境总共需要大约 30 分钟。 

当清楚服务具有潜力时,我们着眼于长期,重新评估了部署模型。

基于 Kubernetes 重构 

仅仅过去了几个月,但整个环境发生了很大变化。

  • HashiCorp 发布了Nomad 
  • Kubernetes 达到了 1.0 版本 
  • Swarm 即将达到 1.0 版本 

虽然我们的许多问题无需进行根本性的架构更改即可修复,但我们希望通过加入现有生态系统并利用其贡献者的经验和辛勤工作,来充分利用行业的进步。 

经过一些内部讨论后,我们对 Nomad 和 Kubernetes 进行了小规模的试用。我们非常喜欢 Nomad,但觉得将其用于我们的生产服务还为时过早。此外,我们发现 Kubernetes 的开发者对 GitHub 上的问题响应最积极。因此,我们决定选择 Kubernetes。

本地 Kubernetes 

首先,我们将使用 Kubernetes 复制我们的飞行模式本地环境。由于我们的开发者使用 Mac 和 Linux 笔记本电脑,因此本地环境的容器化非常重要。所以,我们希望 Kubernetes 组件本身(kubelet、API 服务器等)也在容器中运行。

我们遇到了两个主要问题。首先,也是最普遍的,从头开始创建 Kubernetes 集群很困难,因为它需要深入了解 Kubernetes 的工作原理,并且需要相当长的时间才能将各个组件组合在一起。local-cluster-up.sh 看起来像是 Kubernetes 开发者的工具,并且没有利用容器,而我们找到的第三方解决方案,如Kubernetes Solo,需要专用的虚拟机或平台特定。 

其次,容器化的 Kubernetes 仍然缺少几个重要的组件。遵循官方 Kubernetes Docker 指南构建的集群非常基础,没有证书或服务发现。我们还遇到了一些可用性问题(#16586#17157),通过提交补丁并从 master 分支构建我们自己的hyperkube 镜像来解决。 

最终,我们通过创建自己的供应脚本解决了问题。它需要执行一些操作,例如生成 PKI 密钥和证书以及供应 DNS 插件,这些尝试了几次才成功。我们还了解到一个提交将证书生成添加到 Docker 构建中,因此短期内事情可能会变得更容易。 

AWS 上的 Kubernetes 

接下来,我们将 Kubernetes 部署到 AWS,并将其与 AWS 其他组件连接起来。我们想快速将服务投入生产,并且只需要支持 Amazon,因此我们决定不使用 Weave Net,而是使用现有的供应解决方案。但我们肯定会在近期重新考虑这个决定,通过 Kubernetes 插件利用 Weave Net。 

理想情况下,我们会使用 Terraform 资源,我们找到了一些:kraken(使用 Ansible)、kubestack(与 GCE 耦合)、kubernetes-coreos-terraform(过时的 Kubernetes)和coreos-kubernetes。但它们都基于 CoreOS 构建,这是我们一开始想避免的额外移动部分。(在下一次迭代中,我们可能会试用 CoreOS。)如果您使用 Ansible,主仓库中有可用的 playbook。还有社区驱动的 Chef cookbookPuppet module。我预计社区在这方面会快速发展。 

唯一其他可行的选择似乎是 kube-up,它是一系列脚本,用于在各种云提供商上供应 Kubernetes。默认情况下,kube-up 在 AWS 上会将 master 和 minion 节点放入它们自己的 VPC 或虚拟私有云中。但我们的 RDS 实例是在区域默认 VPC 中供应的,这意味着从 Kubernetes minion 到数据库的通信只能通过VPC 对等连接或手动打开 RDS VPC 的防火墙规则来实现。 

要使流量通过 VPC 对等连接传输,您的目标 IP 需要位于目标 VPC 的私有地址范围内。但事实证明,从同一 VPC 外部的任何地方解析 RDS 实例的主机名会得到公有 IP。并且执行解析很重要,因为 RDS 保留因维护而更改 IP 的权利。这在之前的基础设施中从来不是问题,因为我们的 Terraform 脚本简单地将所有内容放在同一个 VPC 中。所以我想尝试在 Kubernetes 中做同样的事情;kube-up 脚本表面上通过指定 VPC_ID 环境变量支持安装到现有 VPC,所以我尝试将 Kubernetes 安装到 RDS VPC。kube-up 似乎成功了,但通过 ELBs 进行的服务集成中断,并且通过 kube-down 进行的拆卸停止工作。过了一段时间后,我们认为最好让 kube-up 保持其默认设置,并在 RDS VPC 中打开一个洞。 

这是我们遇到的几个问题之一。每个问题都可以单独解决,但使用 shell 脚本供应远程状态固有的脆弱性似乎是实际的根本原因。我们完全期望 Terraform、Ansible、Chef、Puppet 等软件包会继续成熟,并希望尽快切换。 

撇开供应不谈,Kubernetes/AWS 集成有很多很棒的地方。例如,正确类型的 Kubernetes 服务会自动生成 ELBs,Kubernetes 在这方面做了很好的生命周期管理。此外,Kubernetes 领域模型——服务、PodReplication Controller标签和选择器模型等等——是连贯的,并且似乎给予用户恰到好处的表达能力,尽管定义文件确实倾向于不必要地重复。kubectl 工具很好用,尽管初看令人畏惧。特别是滚动更新命令非常出色:这正是我期望这种系统应有的语义和行为。事实上,一旦 Kubernetes 启动并运行,它就只是工作了,而且完全按照我期望的方式工作。这是一件大事。 

结论 

经过几周与机器的搏斗,我们成功解决了所有集成问题,并已将一个相当健壮的基于 Kubernetes 的系统投入生产。 

  • 由于复杂的架构和尚不成熟的供应生态,供应 Kubernetes 很困难。但这正显示出改善的迹象。 
  • Kubernetes 非可选的安全模型需要时间才能掌握。 
  • Kubernetes 领域语言与问题领域非常匹配。 
  • 我们对运行应用更有信心了(速度也快了很多)。 
  • 我们非常高兴成为不断壮大的 Kubernetes 用户群的一员,尽可能地贡献问题和补丁,并从当今最令人兴奋的软件所依赖的开源开发良性循环中受益。 

Weave Scope 是一个开源解决方案,用于可视化和监控容器化应用和服务。要获得托管 Scope 服务,请在 scope.weave.works 申请早期访问计划邀请。