超过四分之一的 Google 员工使用内部数据中心托管的虚拟桌面。这种本地部署的产品位于公司网络中,允许用户从世界任何地方远程开发代码、访问内部资源和使用 GUI 工具。在其最显著的特点中,虚拟桌面实例可以根据手头的任务调整大小,具有持久的用户存储,并且可以在公司数据中心之间移动以跟随出差的 Google 员工。
直到最近,我们的虚拟桌面都托管在使用名为 Ganeti 的自研开源虚拟集群管理系统的 Google 公司网络上的商用硬件上。今天,这项重要且对 Google 至关重要的工作负载在 GCP(Google Cloud Platform)上运行。本文讨论了迁移到 GCP 的原因,以及如何完成迁移。
虽然 Ganeti 运行成本低廉、可扩展且易于与 Google 的内部系统集成,但运行 DIY 全栈虚拟化平台也存在一些明显的缺点。由于在 Ganeti 上运行虚拟桌面需要管理从硬件到 VM 管理器的组件,因此该服务的特点是:
• 扩展平台容量的交付周期长。
• 大量且持续的维护开销。
• 考虑到所涉及技术的广度和深度,团队人员配置困难。
• 底层硬件的资源浪费,考虑到典型 Google 员工的工作时间为每天 8-10 小时。
• Google 多个部门在虚拟化领域的重复工作。
总而言之,这些问题减少了负责改进产品的团队可用的时间和资源。为了解决这些问题,团队于 2016 年初开始将 Google 的顶级企业工作负载迁移到 GCP。
迁移规划包括几个独立的阶段。总的来说,此处描述的规划阶段大约花费了三到四个月,并涉及大约 15 个主题专家组的参与。
此阶段阐明了将我们的虚拟桌面重新平台化到 GCP 的核心业务和工程案例。在云端追求虚拟桌面的首要原因包括:
• 大幅减少工程运维负担。
• 改善用户体验。
• 降低平台总体拥有成本。
• 希望改进 GCP。
下一步是研究用户及其需求。确定了主要用户——虚拟桌面所有者、平台 SRE(站点可靠性工程师)和平台安全经理——并对其进行了调查,以确定他们的典型工作流程。利用这些信息,迁移团队编写了与实现无关的用户旅程。为了执行有效的差距分析,并在设计阶段减少偏差,团队有意识地以纯粹功能性的方式描述用户旅程。
根据收集的调查回复和使用模式,团队将客户用户旅程(按技术领域和用户类型)分组,并将其优先级划分为标记为 alpha、beta 和正式发布的功能带。
与里程碑定义并行,团队将需求分组为七个相关工作流,例如网络和配置。每个工作流都分配了一名技术负责人、一名项目负责人和一名骨干人员。每个团队都是虚拟的,根据需要从各个汇报线招募,以解决工作领域的问题。事实证明,这种组织形式和相关的矩阵管理提供的灵活性对于项目的演进至关重要。
一旦形成,每个工作流都会检查其领域中的关键用户旅程,并研究在 GCP 上实现这些故事的可行性。为此,团队通过阅读产品 GCP 文档并运行“快速失败”原型设计冲刺,对每个用户旅程执行差距分析。在整个过程中,收集了可能的实现方案,并根据复杂性、可行性以及(最重要的是)Google 外部的客户可以多容易地实现此解决方案进行评级。
每当迁移团队得出“仅限 Google”的解决方案时,它都会向 GCP 团队提交功能请求,要求提供也适用于 Google 外部客户的解决方案,特别是如果其他企业客户对该功能感兴趣。通过这种方式,团队试图“像客户一样行事”,以努力使平台为企业做好准备。如果 GCP 产品团队无法及时为发布里程碑交付功能,他们会实施桥接解决方案,这些解决方案优先考虑公众可以使用的解决方案(例如,Forseti Security),而不是仅限 Google 的变通方法。
在设计方案到位且实施方向确定后,团队在中央项目管理工具中为每个工作流创建了详细的工作计划。工作按客户用户旅程组织,任务按目标、关键结果和季度分解。深入到这种详细程度提供了足够的信息来估计每个工作流所需的人员配置,了解流之间的相互依赖性,并根据需要微调组织。
规划完成后,团队准备开始实施迁移的技术细节。本节介绍三个主要的工作方面。
在 GCE(Google Compute Engine)上运行桌面服务的许多网络挑战至少部分地通过 BeyondCorp 计划 得到了解决。在 BeyondCorp 模型中,访问控制基于有关给定设备和用户的已知信息,而不是基于特权网络中的位置。当网络信任不再是访问控制决策的因素时,许多服务可以从公司网络外部轻松访问——通常通过公司笔记本电脑,但现在也可以从 GCE 上适当管理和编目的主机访问。
对于远程访问应用程序的企业,如果他们利用传统的 VPN(虚拟专用网络),那么在移动桌面或其他服务时,他们将有不同的网络体验。一种典型的策略是在云项目中设置 Cloud VPN,并与本地设备对等,以桥接网络。
设备身份验证通常使用部署在主机上的客户端证书执行。当用户收到物理机器(甚至特权公司网络上的虚拟机)时,用户最初可以登录并请求证书,因为公司网络保留了同步登录策略所需的特权级别。出于安全原因,将此级别的网络特权扩展到公共云 IP 范围是不可取的。
为了弥合这一差距,Google 开发了一个(现在公开的)API 来验证实例的身份。该 API 使用 JWT(JSON Web Tokens;JSON 是 JavaScript 对象表示法数据交换格式)来证明实例属于预先授权的 Google Cloud 项目。当实例首次启动时,由该 API 提供的 JWT 之一可以交换为客户端证书,用于证明设备身份,从而解除几乎所有正常通信路径的阻塞(包括同步用户授权的登录策略)。
一旦客户端证书到位,就可以通过 BeyondCorp/身份感知代理访问 Google 应用程序,就像它们是任何其他面向 Internet 的服务一样。为了使云桌面能够访问代理(和其他 Internet 端点),团队设置了 NAT(网络地址转换)网关,以将来自实例的流量转发到云项目外部的目标。结合起来,这些方法允许用户无缝访问内部资源和公共互联网,而无需每个实例都具有公共路由的 IP 地址。
设计配置方案的第一步是规划交付满足用户需求的最终产品所需的一切。Compute Engine 实例需要达到一定的信任、安全、可管理性和性能水平,才能让用户像往常一样执行他们的工作——开发、测试、构建和发布代码。根据这些要求,团队使用了以下具体原则来指导其余的设计。
用户与云桌面的交互方式应类似于他们与公司网络上主机的交互方式。 用户应该能够使用他们正常的身份验证机制。他们还应该能够使用相同的工具来检查机器统计信息或报告他们用于物理桌面或 Google 传统虚拟桌面平台的问题。
实例必须安全地编目。 作为配置过程的第一步,引导主机清单。随着主机的使用,会收集进一步的清单数据,既用于可靠性监控,也用于通知访问控制决策。
Google 的公司网络使用多个清单系统,交叉引用以验证此类访问请求(有关 BeyondCorp 清单过程的更多背景信息,请参阅 BeyondCorp:企业安全的新方法 和 BeyondCorp:Google 的设计到部署)。因此,公司系统在配置过程中需要一些元数据,以指示特权虚拟桌面创建请求。然后将此元数据与从 Google Cloud API 提取的清单数据交叉引用,以便评估是否符合安全策略并断言信任。
实例必须安全地管理。 主机必须能够安全地下载构建其授权策略所需的信息,以便只有允许的用户才能访问。主机还必须能够更新由操作系统安装驱动的软件包和配置,并且必须能够将日志发送到中央位置,以便可以检测到异常行为或与安装相关的问题。
必须根据用户规范创建实例,并带有约束。 实例应配置足够的资源供用户有效地完成工作,但也应设置上限,以防止用户随意创建高规格/高成本的设备。用户可以选择在哪里构建他们的实例(通常在靠近他们物理位置的区域;灾难恢复原因可能决定不同的位置)。
由于需要在公司系统中管理和编目设备,因此一旦桌面迁移到云端,就有两种创建新实例的选项:
• 代表请求者创建云桌面实例。
• 允许用户与云原生界面交互以创建和操作他们的实例。在这种情况下,有必要观察这些更改并在公司工具中进行相应的更新。
团队决定采用第一种方法,并将现有的虚拟机管理工具与 Compute Engine 集成。因此,他们可以根据用户的请求执行更复杂的业务逻辑。
围绕 Compute Engine 配置过程构建的工作流程主要侧重于将请求用户提供的数据以及有关用户的已知数据(组成员身份、职位)转换为可以传递给 Compute Engine 的请求。然后可以在创建过程中跟踪实例,以及任何首次启动操作系统更新和配置,以确保向用户交付可用的机器。
Google 对公司主机使用基于 Debian 的内部管理 Linux 发行版,称为 gLinux。在其公司网络上,gLinux 通过在首次启动时加载引导环境来安装。根文件系统的大部分从 tarball 中解压,然后 Debian 安装程序执行实际安装。
在云端,此过程从 gLinux 发布工具创建的映像开始,该映像上传到云存储并 导入到 GCE。从此映像创建磁盘会导致完全可运行和可启动的文件系统。您可以直接从映像磁盘启动,并且只需在首次启动时执行一些小的修改即可使其完全可用:文件系统扩展以填充磁盘的完整跨度,主机名更新,并执行一些其他 GCE 特定的修改。
为了避免在不同平台上维护和测试单独行为的负担,团队需要最大限度地减少对 Compute Engine 上 gLinux 的特定自定义。幸运的是,这项工作只需要很少的修改,其中大部分集中在 DNS(域名系统)名称解析上。例如,许多在 Google 公司网络上运行的应用程序需要的公司 DNS 区域在网络外不可用。为了解决此需求,团队引入了一个 DNS 解析器,该解析器在每个实例内部运行,以通过 BeyondCorp 代理通过 HTTP 将内部 DNS 区域的请求代理回公司服务器。
在认真开始迁移到 GCP 之前,团队在初始功能集准备就绪时进行了 alpha 和 beta 推广。alpha 版本的目标用户约为 100 人,而 beta 版本的目标用户约为 1,000 人。
为了评估这两个版本的成功,跟踪了以下指标,并将其与 Google 现有的公司平台统计数据进行了比较:
• 寻呼负载。 一旦我们将虚拟桌面迁移到云端,寻呼负载下降了 95%,这在很大程度上归功于 GCP 提供的平台抽象。虽然团队维护着大量的物理服务器、存储单元、网络设备和支持软件,以在公司网络上运行虚拟桌面,但 GCE 消除了所有这些担忧。
• 中断负载。 最初,迁移到云端导致中断增加,这是由于系统的新颖性(这也导致产品错误报告相应增加)。在最初的激增之后,中断负载降至公司网络上托管虚拟桌面时经历的量的 20%。
• 登录率。 迁移前后的 7 天和 30 天登录率相当。
为了告知未来里程碑的路线图,团队还在 alpha 和 beta 版本期间通过以下两个主要途径收集数据:
• 用户报告的反馈。 用户以工单、错误报告、电子邮件和口口相传的形式提供的反馈提供了一个需要修复的项目列表。团队提交了错误以跟踪每个列表项,按严重程度、受影响的用户数量和汇总的客户偏好进行优先级排序。最后一个指标通过为高级用户提供 100 个“功能点”来衡量,以便他们根据自己的意愿分配功能点。然后可以将这些指标用于指导开发优先级。
• 调查。 调查衡量了用户群的主观印象,目的是改进营销。例如,关于云端虚拟桌面与公司网络虚拟桌面的相对性能的主观反馈是分歧的(而实际上,云端的性能更优越)。作为回应,团队强调并更大力地向客户推广基准测试结果,希望促使更客观的评估。调查还有助于量化对转型的担忧,最值得注意的是围绕性能、用户数据迁移以及在给定用户工作流程不受支持时回滚到公司网络托管产品的能力。
根据调查反馈,团队强调了以下方面,以使迁移到云端对用户具有吸引力:
• 改进的 VM 规格。 向用户提供了标准 CPU、RAM 和磁盘规格的大幅增加。
• 一键式个人数据迁移。 迁移过程一开始就很容易,并且自动化了用户工作流程中最耗时的部分:复制个人数据。
• 轻松回滚。 迁移过程允许用户回滚到他们公司托管的实例,这些实例在迁移到云端之前只是被关闭了。未使用的公司托管实例在 90 天的宽限期后被删除。
• 对公司的影响。 明确阐述对 Google 的成本降低有助于让用户确信他们正在为公司做正确的事情。
在从 alpha 和 beta 推广中收集数据和反馈后,团队准备继续进行到云端的全面迁移。本节详细介绍了迁移过程的主要功能。
一旦配置系统为新用户准备就绪,大约 20,000 名虚拟桌面用户必须迁移到新产品。团队简要考虑了一种简单的策略,即简单地将每个用户的磁盘移动到新的云实例中,但管理现有平台的经验指向了略有不同的方向。
有时,旧平台会遇到故障,需要大量工作才能使用户的实例恢复全部功能。随着对实例的增量自动修改的累积,这种故障变得越来越常见。为了避免不必要的运维负担,团队在这些情况下的默认首要响应是询问用户是否需要相关磁盘上的数据。在很多情况下,答案是否定的,因为用户的磁盘上没有任何重要数据。根据来自公司网络托管虚拟桌面的这种强烈(但轶事)信号,团队将迁移到云端的基础建立在用户参与的以旧换新概念之上,而不是传统的幕后迁移。
为了执行这样的以旧换新计划,团队制定了两个工作流程管道:一个用于处理用户明确表示不需要移动数据(或可以自行移动数据)的情况;另一个用于处理需要移动所有数据的异常情况。前者(也是最常见的)情况只需要执行两个简单的任务:关闭原始实例并创建一个名称相似的新实例。这种方法需要的工程工作量最少;使用的计算、带宽和存储资源最少;并为用户从传统有状态磁盘中获得的收益提供了强烈的信号。
Google 雇佣了大量的工程师;如果你给工程师一台 Linux 机器,很有可能这台机器会被定制到极致。对于这些情况,团队希望提供一种使用新平台的途径,该途径不会迫使所有用户都迁移自己的数据。但是,团队警惕为可能无法满足的边缘情况设定“神奇迁移”的期望。
对于请求数据迁移的用户,最佳选择是将他们的主目录就地移动到新的云实例,并提供其整个操作系统的磁盘备份。虽然这种策略复制了 gLinux 系统上已经存在的大量操作系统数据,但这意味着团队可以继续进行,而无需担心重要文件未传输,直到几个月后才被注意到。
实际上传以直接的方式进行。对于每个用户请求,作业执行系统都会创建一个签名的 Google Cloud Storage URL,该 URL 授权持有者在一段时间内对存储桶执行 HTTP PUT 请求。为了确保长时间运行的上传作业不会因工作流程系统部署而中断,旧虚拟化平台上的 Upstart 脚本会处理上传。上传完成后,云工作实例启动以通过将用户数据合并到黄金主映像的副本上来创建新的磁盘映像。
beta 阶段显示了对云端托管虚拟桌面的高需求,因此团队希望确保全面发布充分预测到需求。为了避免旧虚拟化平台上的网络链路和团队处理大量请求的能力不堪重负,用户不允许自行请求以旧换新。相反,以旧换新首先提供给最有可能需要它们的用户:那些磁盘使用率低可能不需要移动整个磁盘的用户,以及实例托管在旧硬件上的用户。通过这种方式,团队可以平衡容量限制,并精确地定位机器位置可以最大程度减少运维负担的用户群体。一旦用户实际开始使用该平台,对云桌面的高需求意味着用户希望更早地选择加入。尝试在没有明确邀请的情况下创建新的云桌面实例是向这些用户发送以旧换新邀请的信号。
虽然最初对新服务的反响是积极的,但一些障碍给用户造成了轻微的不便,并导致一些用例完全崩溃。
这些痛点中的大多数都影响了配置过程,并且主要是由于误解了 Google 清单和信任管道中的各种 SLO(服务级别目标)和延迟造成的。团队需要独立的用户意图信号,以便授予对新桌面实例的受信任访问权限,并且一旦用户通过“注册”实例(创建后)提供此信号,用户仍然需要等待几个小时实例才能被所有系统完全信任。因此,配置和测试实例需要在三到五个小时的时间内进行三次用户交互。一旦团队意识到这个问题,他们就对信任管道进行了更改,并将注册步骤折叠到初始用户请求中,从而消除了数小时的等待时间。如果团队将配置和其他操作的计时视为构建要求,他们本可以更早地进行这些改进。
崩溃的用例最终暴露了各种应用程序和用户组对网络访问的许多错误假设。例如,一些次优的实现不是使用库来检查用户是否在公司网络或生产网络上,而是依赖于主机名或 IP 空间。这些问题通常通过更新各个应用程序的代码以消除错误的假设来解决。
还有一些工作流程在技术上违反了安全策略,但获得了例外授权。云桌面默认强制执行这些策略;它鼓励用户修复他们的工作流程,而不是延续不良做法。例如,在 Google 的公司网络上,用户可以获得直接连接到某些应用程序数据库的例外。这是可行的,因为数据库服务器和用户在同一网络上。这些类型的用例应转向 BeyondCorp 网关。
与任何复杂的发布一样,开发团队在此过程中学到了许多经验教训,包括技术性和非技术性。
推送,而不是拉取。 能够控制到您系统的流量使操作变得无限简单。发现错误?停止发送邀请。一切顺利?加大力度。即使集成此功能很困难,如果可能,也值得从一开始就实施。
向用户明确说明权衡和成本。 如果您提供两个选项,并且一个选项看起来工作量较少,那么每个人都会选择更简单的选项。为了抵消这种冲动,如果一个选项成本更高,请在用户决策点公开该成本。例如,将磁盘移动到云端对用户来说很方便,但比另一种选择(简单地将公司网络托管的实例换成云托管的实例)更耗时(且成本更高)。团队将移动磁盘的成本公开为 24 小时,这远不如将公司网络托管的实例换成云托管的实例的一小时持续时间方便。仅在用户必须在两个选项之间进行选择时公开此信息就节省了估计 1.8 PB 的数据移动。
永远不要浪费收集数据的机会。 在迁移之前,团队不知道有多少比例的用户严重依赖其本地磁盘的内容。事实证明,只有大约 50% 的用户足够关心保留他们的磁盘,愿意等待 24 小时完成迁移。这对未来的服务扩展或迁移来说是一个有价值的数据点。
不要试图将“一次性”迁移变成特例。 如果您抓住机会在进行持久性更改时进行同质化,那么未来的您会感谢您的。前几代公司网络托管的虚拟桌面系统的磁盘布局与当前用于测试的模型略有不同。这不仅是生产中的一个令人不快的意外,而且几乎不可能测试,因为没有现有工具可以创建旧磁盘类型。幸运的是,在设计阶段,团队抵制了通过将用户数据放在第二个 GCE 磁盘上来“简化”数据复制阶段的冲动——这样做会使这些实例在云托管平台的整个生命周期内都成为特殊的雪花。
保持组织灵活。 将团队组织成虚拟工作流有多种好处。此策略使团队能够快速收集跨汇报链的专业知识、在整个项目中扩展和收缩团队、减少团队之间的沟通开销、为工作组分配单一的可交付成果目标以及减少团队之间的领地意识。
这是一个“做对”的机会。 迁移到云端使团队能够重新考虑团队和组织内部随着时间推移而僵化的某些实现。
由于云桌面由运行自定义映像的 Compute Engine 实例组成(自定义映像的生产成本相当低廉且 文档齐全),因此基础设施的可扩展性非常好。使用十几个实例进行试点与使用数千个实例运行相比,变化非常小,Google 在这里实施的方案应直接适用于其他较小的公司,而无需对本文详述的计划进行太多专业化处理。
虽然虚拟桌面迁移到云端并非一帆风顺,但它已取得了坚实的成功,并为进一步的工作奠定了基础。展望未来,Google 公司云迁移团队正在从事两个主要的工作方向:改善虚拟桌面体验,并使 Google 公司服务器工作负载能够在云端运行。
在桌面领域,团队计划通过开发各种补充 Google Cloud 平台的工具来帮助管理云桌面平台,从而改善服务管理体验。这些附加组件包括磁盘检查工具和舰队管理命令行工具,该工具集成了云端和其他公司系统之间的操作并进行协调。
在提高平台成本效益方面有几种可能性。在简单的频谱末端,云桌面可以自动请求空闲机器的所有者删除他们实际上不需要的实例。
最后,可以通过实施数据中心之间的自助式 VM 冷迁移来改善最终用户体验,允许出差用户将其实例重新定位到附近的数据中心,以减少到其 VM 的延迟。请注意,这些计划的范围限定为云桌面,作为客户/应用程序特定的逻辑的一部分,而不是 Google 作为一家公司为 Compute Engine 总体规划的功能。
至于服务器工作负载,团队正在借鉴云桌面的经验教训来提供迁移路径。该领域的主要技术挑战包括:
• 编目和表征公司平台。
• 创建可扩展且可审计的服务和 VM 生命周期管理框架。
• 维护多种风格的托管操作系统。
• 将 BeyondCorp 语义扩展到难以代理的协议。
• 应对一系列新的安全和合规性要求。
• 为需要数据库的服务创建高性能共享存储解决方案。
• 创建迁移工具以自动化繁琐的操作。
• 实施许多特定于服务的需求。
迁移服务器工作负载还增加了组织复杂性,即由异构的服务所有者群体组成,每个服务所有者都有来自他们支持的部门和业务职能部门的不同优先级和要求。
Titus:将容器引入 Netflix 云 Andrew Leung、Andrew Spyker 和 Tim Bozarth 在已经云原生的基础设施中采用容器 https://queue.org.cn/detail.cfm?id=3158370
遍布全球的可靠 Cron Štěpán Davidovič、Kavita Guliani ...或者我如何停止担忧并学会热爱时间 https://queue.org.cn/detail.cfm?id=2745840
虚拟化:福还是祸? Evangelos Kotsovinos 大规模管理虚拟化充满了隐藏的挑战。 https://queue.org.cn/detail.cfm?id=1889916
Matt Fata 是 Google 的站点可靠性经理,他在那里负责公司虚拟化解决方案。他之前曾担任网络工程师和 IT 支持服务台经理。
Philippe-Joseph Arida 是 Google 的技术项目经理,目前致力于使 GCP 成为企业工作负载的最佳平台。他曾在 Microsoft 工作过,并在 Oracle、Matrox 和 坦佩雷理工大学实习过。Philippe 毕业于麦吉尔大学计算机工程专业。
Patrick Hahn 是 Google 的站点可靠性工程师,也是云桌面项目的技术主管。他曾担任系统管理员,在网络开发、托管 IT 和定量金融行业工作过。
Betsy Beyer 是 Google 纽约站点可靠性工程部门的技术作家,并且是Site Reliability Engineering: How Google Runs Production Systems 和即将出版的 Site Reliability Workbook 的编辑。她之前曾为 Google 数据中心和硬件运营团队编写文档。她拥有斯坦福大学和杜兰大学的学位。
版权 © 2018 归所有者/作者所有。出版权已授权给 。
最初发表于 Queue vol. 16, no. 3—
在 数字图书馆 中评论本文
Marc Brooker, Ankush Desai - AWS 的系统正确性实践
构建可靠和安全的软件需要一系列方法来推理系统正确性。除了行业标准测试方法(如单元测试和集成测试)之外,AWS 还采用了模型检查、模糊测试、基于属性的测试、故障注入测试、确定性模拟、基于事件的模拟和执行跟踪的运行时验证。形式化方法一直是开发过程的重要组成部分——也许最重要的是,形式化规范作为测试预言机,为 AWS 的许多测试实践提供了正确的答案。正确性测试和形式化方法仍然是 AWS 的关键投资领域,这些领域的投资已经获得了丰厚的回报,这加速了这些领域的投资。
Achilles Benetopoulos - 数据中心计算机的中间表示
我们已经到了分布式计算无处不在的时代。内存中的应用程序数据大小正在超过单台机器的容量,因此需要将其分区到集群中;在线服务具有高可用性要求,只有通过将系统部署为多个冗余组件的集合才能满足这些要求;高持久性要求只能通过数据复制来满足,有时甚至跨越广阔的地理距离。
David R. Morrison - 模拟:分布式系统中未被充分利用的工具
模拟在人工智能系统的出现中发挥着巨大的作用:我们需要一种高效、快速且经济高效的方式来训练 AI 代理在我们基础设施中运行,而模拟绝对提供了这种能力。
Pat Helland - 分布式事务之外的生活
本文探讨并列举了在拒绝分布式事务的世界中,用于实现大规模关键任务应用程序的一些实用方法。主题包括对应用程序数据的细粒度片段的管理,这些片段可能会随着应用程序的增长而随着时间推移重新分区。设计模式支持在这些可重新分区的数据片段之间发送消息。