Ghost 迁移到云服务的 6 点经验

  • 张英洁

2016 年 2 月 23 日

话题:云计算语言 & 开发架构DevOps

Ghost 是一个开源博客平台,而 Ghost(Pro) 是它的托管平台。这篇文章的作者是 Ghost 的高级 DevOps 工程师 Sebastian Gierlinger。他用简单的 6 个步骤,总结了 Ghost(Pro) 的基础设施从专用服务器迁移到 DigitalOcean Droplets 的过程。

以一年多运营 Ghost(Pro) 的经验来看,我们认为自己的下一代基础设施需要满足如下需求:

  • 能够在几分钟内对服务器扩容
  • 拥有能服务数千个博客的大内存
  • 提供强大的客户支持
  • 在不做重大重构的前提下迁移软件

任何一个项目的迁移,都以一定程度的不确定性开始。一开始就预料到所有的迁移步骤是不可能的,更不要说预料到任何一个即将遇到的问题。但鉴于这是一篇回顾文章,出于方便理解的目的,迁移过程包括以下几个大步骤:

  • 为现有的服务器基础设施建立目录
  • 确保公网安全
  • 确保专用网络安全
  • 备份数据库
  • 更新 DNS(切换到目标服务器)
  • 下线旧的运行环境

迁移后的 Ghost(Pro) 系统架构是这样的:

下面就让我们来详细看看迁移过程的 6 个步骤。

Step 1:创建目录

第一步是用配置管理工具创建一个目录,用来显示现存的服务器基础设施上运行着什么。

我们并没有一个完整的目录,包含所有安装的软件、防火墙设置和其他服务器配置。为了解决这个问题,我们引入了一个配置管理系统工具箱。配置管理的一大好处就是,一旦系统建立起来,它既可以作为记录文档,又可以用作一个部署工具。

我们考虑过几个比较流行的配置管理工具,包括 Puppet、Chef、Ansible 和 SaltStack。我们需要一个既能完成工作又不容易因为复杂性而过载的工具。最终就选择了 SaltStack。

下面是几个选择 SaltStack 的原因:

  • 它很轻量,易于安装和维护;
  • 它采用 master/minion 的架构,可以将更改从 master“推送”到 minion 端,避免了由于频繁请求可能造成的 DDoS 攻击;
  • 它拥有一个专门的主服务器,可以防止管理员和开发者直接在未受保护的生产环境部署更改;
  • Master 和 Minion 的通信采用 ZeroMQ 而不是 SSH。在处理多个加密并发连接时,ZeroMQ 使用更少的 CPU 资源,效率更高。

另一个附加的好处是 Salt Cloud,它包含在 SaltStack 里,并且和 DigitalOcean 的 API 无缝兼容,资源可以快速弹性伸缩,我们可以用命令行管理系统资源。

虽然这个新的 Ghost(Pro) 架构初始设置和配置颇花费了一些时间——大概 3 周,但 SaltStack 表现除了它强大的功能。第二步迭代配置用了大概一周,第三步部署托管平台只用了两天。

创建一个目录,并把它迁移到配置管理工具,这是一个迭代的过程,会涵盖几乎整个系统迁移的过程。除了完成迁移,创建目录还暴露了我们结构中需要改进的部分。读者如果想要尝试 SaltStack 更多功能,请参考使用手册:123.

Step 2:确保公网安全

第二步是为了确保平台内部服务器的公网防火墙安全。

以前,只有我们面向公众的服务器可以通过外网访问;其他服务,比如 APP 和数据库服务,只能通过专用网络访问。迁移到 DigitalOcean 的云端后,所有服务器都有一个公共 IP 地址,我们必须解决这项新的安全隐患。

我们给内部服务器的公网设置了一个 iptables 规则,能够拦截除了 SSH 加密通信的其他所有连接。我们自己的服务器用的是 Ubuntu,所以用 UFW 作为 iptables 的管理界面。

和其他基础设施一样,防火墙配置是通过 SaltStack 完成的,方便于我们统一管理。

Step 3:确保专用网络安全

第三步是用 VPN 确保所有服务器专用网络的安全。

DigitalOcean 的专用网络允许同一数据中心的 Droplets 彼此通信。这个特点非常棒,它在基础设施内保证了高带宽和低延时,专用网络被共享给数据中心所有的 Droplets,包括那些属于其他 DigitalOcean 客户的 Droplets。这就是说,专用网络保护我们不会被接入一般的互联网连接,但可能接入其他不属于我们的 Droplets。

我们选择配置 VPN 来确保服务器专用网络的安全,它提供的加密和身份认证正是我们所需要的。我们选了 Tinc VPN,因为它有网状路由布局,这意味着它的流量会尽可能直接发送到目标主机。它允许通过直连的 Droplets 发送流量,而不必直接与请求者相连。不像 OpenVPN 那样把 VPN 管理复杂化,我们的 VPN 更像是个传统的专用网络。

就像防火墙配置一样,我们用 SaltStack 集中管理 VPN 配置。这样就可以在所有服务器中自动更新 Tinc VPN 的配置,从而保证了所有 VPN 网络的正确和及时更新。

Step 4:启动数据库备份

第四步是设置备份来迁移数据库。

最初,我们计划在数据库迁移期间把 Ghost(Pro) 下线。这样暂停一下,我们就可以保持数据的连续性,并为 MySQL 数据库备份。然后我们再把备份传到新数据库服务器上,最后重置一下就能完成数据库迁移。然而,分析完现有数据后,我们发现这并不可行。我们有大约 500G 的数据库,这意味着预计需要 6 小时的下载时间,还不包括任何意外的错误。服务下线那么长时间是不能接受的。我们需要其他解决方案。

我们决定首先迁移备份数据库,这样可以保证在迁移数据的一致性,同时也能保证数据库迁移过程中线上服务不中断。下面简述备份步骤:

  1. 配置 Master/Slave 备份

    把原始数据库服务器设置为 master,新数据库服务器设为 slave。这意味着从原始数据库系统到新架构的数据库备份是单向的。

  2. 测试新基础设施

    用这样的 master/slave 设置,就可以测试了,看我们新的 Ghost(Pro) 系统是不是和原有设置保持一致。所有测试完成后,我们删除了新的数据库服务器(slave)数据来为下一步做准备。

  3. 配置 Master/Master 备份

    新数据库服务器测试后,我们开启了 master/master 备份,这意味着所有的数据变更是双向的。一旦开启 master/master 备份,原始数据库被迁移到新服务器上,新的基础设施准备就绪了。更多关于数据库迁移的教程,请参考12

Step 5:更新 DNS 记录

第五步是更新 DNS 记录,以此把新基础设施投入使用。

更新 DNS 记录有时候会出现问题,因为 DNS 生效需要时间。如果处理得当,生效时间是几个小时,用户可以使用新老系统。我们使用 CloudFlare 管理 DNS 条目,它支持实时修改 DNS,这样我们就能避免可能出现的问题了。

当准备启用新系统时,我们执行了以下步骤。首先,更新 ghost.org,使它指向新的核心服务器;然后,测试运行;最后,更新 ghost.io,使它指向新缓存服务器,再多测试几次。

Step 6:下线旧的运行环境

最后一步就是下线旧运行环境中的服务器。所有服务都运行在新的 DigitalOcean 中,我们不再需要原来的专用服务器基础设施了。淘汰旧的设备能大大节省我们的开支。

在关停旧的基础设施前,我们需要停掉新旧数据库服务器的备份。

结语

把 Ghost(Pro) 平台从专用服务器迁移到 DigitalOcean 非常成功。我们希望分享自己的经验,因为我们知道业务迁移是很多项目面临的一个挑战。我们希望自己迁移到 DigitalOcean 的分享对其他准备迁移的项目能有借鉴意义。

本文编译自:How Ghost Migrated From Dedicated Servers to DigitalOcean


感谢魏星对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群InfoQ 好读者(已满),InfoQ 读者交流群(#2)InfoQ 好读者)。

云计算语言 & 开发架构DevOps