云抽象旨在简化云开发,但开发者常因害怕失控、历史经验和 NIH 综合症而犹豫。好的抽象应提供透明度和“逃生舱口”,如 Nitric 生成可审查的 Terraform 配置。拥抱云抽象,如 IaC 工具,可将精力集中于业务创新,加速开发和部署,并保证环境一致性。
译自:Tackling the Fears and Risks of Cloud Abstractions
作者:Rak Siva
云开发发展迅速,带来了越来越多的服务、配置文件和复杂性。作为回应,新一代基于意图、开发者优先的云抽象已经出现,以简化我们在云中构建的方式。这些框架允许你在高层次上声明你需要什么,并处理如何配置它。
然而,许多云开发者和工程负责人犹豫是否要接受这些抽象。为什么?通常可以归结为害怕失去控制,以及过去使用“泄漏”工具的经验、对性能的担忧、坚持自己的舒适区或非我发明(NIH)综合症。
保持谨慎是很自然的。毕竟,我们已经花费多年时间来掌握基础设施即代码(IaC)工具(Terraform、CloudFormation、原始SDK、YAML)以实现完全控制。将钥匙交给自动化层可能会感觉像是一个冒险的飞跃。
通常,我们讨论抽象的好处,而没有承认或解决恐惧和风险。让我们正面应对一些关于云抽象的最常见的恐惧。
“如果我不是自己配置每个资源,我真的能控制吗?”
这是从原始 Terraform 或 CloudFormation 迁移到更高级别工具时的一个常见问题。传统的 IaC 让你能够控制(几乎)每个旋钮,但随之而来的是大量的复杂性。真正的恐惧不是关于控制,而是关于透明度。工程师们担心抽象会隐藏重要的细节,使基础设施更难信任或调试。
但是,一个好的抽象不会剥夺控制权;相反,它会将你的注意力转移到重要的事情上。与其手工制作每个 IAM 策略,不如表达应用程序的需求,然后由框架来处理粘合。
以下是使用 Nitric 的一个简单示例:
from nitric.resources import api, bucket
from nitric.application import Nitric
from nitric.context import HttpContext
main_api = api("main_api")
images = bucket("images").allow("reading")
@main_api.get("/file/<name>")
async def get_file(ctx: HttpContext):
url = await images.file(ctx.req.params["name"]).download_url(expiry=3600)
ctx.res.json({"download_url": url})
Nitric.run()
这个小片段包含足够的信息,让我们知道如何设置 API 端点、存储桶、权限、路由和计算。虽然隐藏了,但控制仍然存在,因为你可以覆盖用于生成结果 IaC 的 Terraform,而无需接触你的应用程序代码。 例如,假设你查看此代码,你的第一个问题是“如何设置 API 网关超时?”我的回应问题是“你多久更改一次每个项目的此设置?”如果答案是“很多”,那么抽象应该能够将此配置提升到你的应用程序配置或 config。但是,如果答案是“很少/从不”,那么将其作为模块中的默认设置会更合适。
这就是“真正的”控制的样子:在自动化样板文件的同时做出具有高度影响力的决策,并允许你仅在需要时自定义底层基础设施。
我们许多人都带着过去尝试抽象但不太顺利的伤疤。也许你尝试过 PaaS 或一个花哨的新框架,它承诺处理一切,但是当出现问题时,你仍然不得不挖掘多层复杂性。这就是经典的“泄漏抽象”问题。
“所有非平凡的抽象,在某种程度上,都是泄漏的。”
— Joel Spolsky,Stack Overflow 的 CEO 和联合创始人
没有抽象是完美的,最终,在规模化和边缘情况下,一些底层细节会渗透出来。对于云开发者来说,这表现为那些痛苦的时刻,即你的高级工具不支持特定的配置或抛出一个不透明的错误,并且你被迫盲目地排除原始基础设施的故障。难怪人们会变得谨慎。
但是,重要的是要意识到为什么早期的抽象会泄漏,以及现代方法如何解决这个问题。许多第一代云抽象(想想早期的 serverless 框架或过于简单的基于 GUI 的云构建器)本质上是云 API 上的薄包装器。一旦你走出幸福的道路,你就会撞到墙。 现代的开发者优先平台已经从这些经验中吸取了教训。它们往往是开源和透明的。你通常可以检查抽象层在底层做了什么。例如,Nitric会生成一个Terraform配置(通过Terraform CDK),你可以导出并在需要时进行审查。这意味着如果某些东西的行为不如预期,你不是在调试一个黑盒子;你实际上可以看到框架产生的中间IaC。这是对信任的巨大提升。
好的抽象提供了逃生舱口和扩展点(正如我们在上面看到的覆盖模块)。目标是当抽象不能直接支持边缘情况时,你可以扩展它而不是放弃它。将此与强制你完全打破抽象的泄漏抽象进行对比(例如手动修补工具外部的某些东西)。通过扩展或注入自定义逻辑的能力,抽象本身不会因新的需求而“破坏”;它会弯曲以适应它们。
非我发明综合症与其说是一种技术恐惧,不如说是一种文化恐惧。工程团队,尤其是非常有能力的团队,通常认为他们的需求是独特的,并且他们可以内部构建一个更好的解决方案,而不是使用外部抽象或平台。你可能会听到这样的说法:“为什么要使用这个框架?我们可以自己编写所有这些脚本,并将其完美地定制到我们的环境中。”或者,“我们不想依赖外部工具;让我们构建我们自己的轻量级版本。”这是一种自己动手的本能,源于自豪感、控制欲,或者有时是对通用工具是否适合你的特殊情况的怀疑。
“许多公司都患有非我发明综合症,提出自定义解决方案而不是选择第三方工具。”
— Mykyta Protsenko, Netflix
虽然DIY方法在一些真正独特的场景中可能很有用,但更多时候它会导致重新发明轮子,浪费时间解决已经解决的问题。这种倾向可能会使团队陷入无休止的内部工具维护中,这些工具永远无法完成或记录。如果你的开发人员花费数月时间构建内部部署框架,那么他们就没有时间交付业务功能。
“停止在无差别的繁重工作上花钱(和时间)。”
— Werner Vogels, Amazon
当涉及到云基础设施时,请考虑你团队的核心竞争力。编写和维护内部云平台真的是你业务的差异化因素吗?如果你是云提供商或销售开发者工具,也许是?否则,可能不是。对于大多数产品公司来说,差异化因素是他们提供的应用程序或服务,而不是部署它的定制脚本。
那么,当你可以利用现有的框架并回到构建产品功能时,为什么要投入大量精力呢?使用抽象,尤其是开源的抽象,也意味着你可以从用户社区中受益。错误由其他人发现和修复,新功能由贡献者添加,你可以聘请可能已经熟悉它的工程师。使用专有的内部工具,你将独自承担全部负担。
需要明确的是,“非我发明”并不是盲目接受任何现成的工具。你仍然应该评估解决方案的成熟度和社区。当一个抽象满足你80%到90%的需求时,通常明智的做法是在此基础上构建,而不是从头开始创建自己的抽象。
“我更喜欢别人为我解决问题”
— Linus Torvalds, Linux内核的创建者和首席开发者
将抽象视为杠杆。正如高级编程语言和库让我们用更少的代码行完成更多的工作一样,云抽象让我们用更少的YAML和脚本完成更多的工作。它们使我们从一遍又一遍地重新实现相同的模式中解放出来。它们将我们的注意力从管道转移到产品。
当你不再需要担心应该转动哪个旋钮来启用集成,或者如何格式化IAM策略时,你可以将这些精力投入到你所在领域的创新中。因此,团队可以更快地行动,更自信地部署,并且减少“它在我的机器上可以工作”的麻烦,因为平台可以保证跨环境的一致性。