[译] 云原生编程语言 Pulumi 开源宣言

2018 年 6 月 18 日 Joe Duffy 在他的博客中宣布开源了云原生编程语言 Pulumi。

声明
此文为个人翻译,仅供参考,不代表我个人立场。翻译过程中可能有删改或遗漏,如需了解原文,请自行查阅。如有疏漏,欢迎指正。
查看本文大纲

2018 年 6 月 18 日 Joe Duffy 在他的博客中宣布开源了云原生编程语言Pulumi。这是继Ballerina之后我看到的另一款云原生编程语言,他们之间有一些共同的特点,例如都是为了支持多种云环境,基于不可变基础设施和基础设施即代码的理念构建,使云原生应用的集成更加方便,但也有一些不同,Ballerina 是直接创建了一个基于 JVM 的语言,而 Pulumi 是为不同编程语言构建了 SDK。

下文是对 Hello, Pulumi!一文的翻译。

今天我们发布了 Pulumi,这是一款开源的云开发平台。有了 Pulumi,您可以使用自己最喜欢的编程语言来开发云应用程序,可以直接跨过底层的基础设施即代码直接开发更高效更具生产力的现代容器和 serverless 应用。一年多前我们发起了 Pulumi,我们都为自己在这一年多取得的成绩感到惊讶。这是我们开源的第一步,也是我们做出的一步重大跨越,我们期望与您分享我们的成就。

Pulumi 支持多语言、混合云环境、完全可扩展。初期支持 JavaScript、TypeScript、Python 和 Go 语言,支持 AWS、Azure、GCP 云平台,另外还支持所有兼容 Kubernetes 的公有云、私有云和混合云。Pulumi 实现了一种单一、一致的编程模型,一组编程工具,可管理所有以上环境,丰富的生态系统支持大量可复用的包。使用真实的语言来改变一切。

TL;DR 有了 Pulumi,38 页的手动操作说明将变成了 38 行代码。25000 行 YAML 配置变成了使用真实编程语言的 500 行语句。

Pulumi 的整个运行时、CLI、支持的库都可以在 GitHub 上免费下载。我们的团队正急切的等待您的反馈。与此同时,我需要告诉您一些关于 Pulumi 的事情,为什么我们会创造它。

为什么创造 Pulumi?

我的背景是 100% 在开发者工具上。我是.NET 的早期工程师,设计了其中的并发和异构部分,领导的分布式操作系统的变成平台,管理微软语言小组,包括开源和使.NET Core 跨平台。因为这些背景,进入云领域我有自己的见解。

我发现的东西显然无法吸引我。

2016 年年末的时候我就开始跟我的朋友也是共同创始人 Eric Rudder 开始构思 Pulumi,那时候容器和 serverless 已经甚嚣尘上,但是距离落地还为时尚早。云的能力十分惊人,但是至今将使用它还是十分困难。

对于每一个 serverless 函数来说,我都要写几十行的 JSON 或者 YAML 配置。要链接到一个 API 端点,我还要学习晦涩的概念,执行一系列复制 - 粘贴的低级工作。如果我想在本机上运行一个小的集群的话,那么 Docker 还是很棒的,但是如果要在生产上使用的话,那么就要手动管理 etcd 集群,配置网络和 iptables 路由表,还有一系列与我的应用程序本身不相干的事情。不过 Kubernetes 的出现至少让我可以配置一次下次就可以跨云平台重用,但这还是会分散开发人员的精力。

我认为我还算一个经验丰富的工程师,已经在软件行业从业 20 年了,但是当我想要将自己的代码部署到云中的时候,我感觉自己就像是个傻子。真是太令人悲哀了!如果我掌握了这些能力,那么是世界就会出触手可及。我总是在淌这浑水,处理云的复杂性,而我真正想做的是花时间来创造业务价值。

关于编程的许多方面都经历了类似的转变过程:

  • 在 80 年代初,我们使用汇编语言对微处理器进行了编程。最终,编译器技术进步了,我们可以同时处理多种常见的架构。像 FORTRAN 和 C 这样的 Low-level 的编程语言开始兴起。
  • 在 90 年代初期,我们直接针对低级别操作系统原语进行编程,无论是 POSIX 系统调用还是 Win32 API,并进行手动内存和资源管理。最终,语言运行时技术和处理器速度提升到了可以使用更高级别语言的状态,如 Java。除了动态语言之外,这种趋势已经加速,如 JavaScript 统治了 Web。
  • 在 21 世纪初期,我们的编程模型中的共享内存并发性最好是原始的(我花了很多时间在这个问题上)。现在,我们简单地假设 OS 具有高级线程共享、调度和异步 IO 功能,以及编程到更高级别的 API,例如任务和承诺。

我相信云软件也在进行类似的转变。从构建单一应用程序到构建真正的云优先分布式系统,我们正处在一场巨变中。然而,当海啸发生之前,人们几乎不知道它正在发生。

从上面的角度来看,使用“配置”情况是有道理的。在虚拟机的早期,我们利用现有的应用程序并将它们扔在栅栏上,以便有人添加一点 INI 或 XML 粘合剂,让它们在虚拟机内部运行,以实现更灵活的管理。随着我们将这些相同的虚拟机“提升并转移到云中”,这种配置方法一直伴随着我们。这将我们带到了大致正确的边界。

使用这种相同类型的配置表示基于容器的微服务、serverless 和细粒度托管服务之间的关系导致了异常的复杂性。将应用程序转变为分布式系统应该是事后的想法。事实证明,云覆盖了您的架构和设计。表达架构和设计的最好的方式是使用代码,使用真正的编程语言编写抽象,重用和优秀的工具。

早些时候,Eric 和我采访了几十个客户。我们发现,开发人员和 DevOps 工程师都普遍感到幻灭。我们发现了极端的专业化,即使在同一个团队中,工程师也不会使用同一种语言。最近几周我已经听到了这个消息,我期待有一天会出现 NoYAML 运动。

专业化是一件好事,我们希望我们最优秀和最聪明的云计算架构师晋升到 DevOps 和 SRE 的高级职位,但团队必须能够在合作时使用相同的语言。因为没有共同的通用语言导致了团队之间的物理隔离,而不是根据策略和环境分工。Pulumi 的目标是为人们提供解决这个问题所需的工具。

Pulumi 是什么?

Pulumi 是一个支持多语言和混合云开发平台。它可以让您使用真实语言和真实代码创建云计算的各个方面,从基础设施到应用程序本身。只需编写程序并运行它们,Pulumi 就能帮你完成出其余部分。

Pulumi 的中心是一个云对象模型,与运行时相结合以了解如何以任何语言编写程序,理解执行它们所需的云资源,然后以强大的方式规划和管理您的云资源。这种云运行时和对象模型本质上是与语言、云中立的,这就是为什么我们能够支持如此多的语言和云平台。更多支持正在路上。

Pulumi 采用了基础设施即代码以及不可变基础设施的概念,并可让您从您最喜欢的语言(而不是 YAML 或 DSL)中获得自动化和可重复性优势。在部署它们之前,您可以对变更进行区分,并且我们会对谁更改了什么以及何时更改进行完善的审计追踪。核心模型因此是陈述性的。

使用真正的语言可以带来巨大的好处:

  • 熟悉:不需要学习新的定制 DSL 或基于 YAML 的模板语言
  • 抽象:正如我们喜爱的编程语言那样,我们可以用更小的东西来构建更大的东西
  • 共享和重用:利用现有的语言包管理器共享和重用这些抽象,无论是与社区、团队内部共享
  • 表现力:充分利用您的编程语言,包括异步、循环和条件
  • 工具:通过使用真正的语言,我们可以即时访问 IDE、重构、测试、静态分析和编排等等
  • 生产力:将以上所有好处加在一起,一起将变得更快,我们也会变得更快乐

当提供原始云资源时,这些好处当然最重要,但是我们在团队中发现,您只能使用抽象。这包括在函数中包装事物以消除样板并创建引入更高级别概念的自定义类,通常将它们打包并重复使用。

例如,此代码在 AWS 中创建一个 DynamoDB 数据库:

import * as aws from "@pulumi/aws";
let music = new aws.dynamodb.Table("music", {
    attributes: [
        { name: "Album", type: "S" },
        { name: "Artist", type: "S" },
    ],
    hashKey: "Album",
    rangeKey: "Artist",
});

此代码创建一个基于容器的任务和无服务器功能,由一个存储桶触发:

import * as cloud from "@pulumi/cloud";
let bucket = new cloud.Bucket("bucket");
let task = new cloud.Task("ffmpegThumbTask", {
    build: "./path_to_dockerfile/",
});
bucket.onPut("onNewVideo", bucketArgs => {
    let file = bucketArgs.key;
    return task.run({
        environment: {
            "S3_BUCKET":   bucket.id.get(),
            "INPUT_VIDEO": file,
            "TIME_OFFSET":  file.substring(file.indexOf('_')+1, file.indexOf('.')).replace('-',':'),
            "OUTPUT_FILE": file.substring(0, file.indexOf('_')) + '.jpg',
        },
    });
});

更好的是,这些代码可以根据您的需求部署到任何公共或私有云中。

最后,这个例子创建了一个 Redis 缓存。我们怎么知道?我们不需要。缓存组件是一个抽象,它封装了我们可以安全忽略的不重要的细节:

import {Cache} from "./cache";
let cache = new Cache("url-cache");

在使用 Pulumi 之后,你不会再以同样的方式考虑基础设施。你的大脑将不再是一个独立于应用程序的独特“事物”,而是开始将分布式云系统看作是你的程序架构的核心部分,而不是事后的想法。

由于抽象,我们已经能够提供一些强大的库。该库是提炼和执行最佳实践的绝佳方式。当然,对于我们自己的库来说没有什么特别的,因为它们只是功能、类和代码,我们期待着看到你为自己、你的团队或者社区建立的那些库。

我们最复杂的库——Pulumi 云框架——提供了一些令人兴奋的正在进行的工作的早期预览,展示如何创建跨越云提供商自己对诸如容器、无服务器功能和存储桶等核心概念的抽象。以同样的方式,您可以用 Node.js、Python、Java、.NET 等语言编写功能强大的应用程序,利用进程、线程和文件系统,无论是在 macOS、Linux 还是 Windows 上,这种方法都可以让您创建针对任何云提供商的现代混合云应用程序。像 Kubernetes 和其他 CNCF 产品组合这样的技术正在帮助推动这一不可避免的结果,因为它们在整个云基板上实现了对基本计算抽象的民主化和共识。

Pulumi 不是 PaaS,尽管它提供类似 PaaS 的生产力;您的程序总是直接针对您选择的云运行,并且始终可以访问该基础云的全部功能。即使您选择使用更高级别的组件,它也会向下兼容,并且您可以随时直接使用原始资源。它就像任何复杂的现代软件:有时,整个事情必须用 C++ 编写,以便访问底层平台的全部功能,但对于大多数常见情况,70% 到 100%可以是平台独立代码,而只有不到 30% 的专业化才能真正需要直接与操作系统交互。

接下来我还将发布十几篇博客文章来介绍 Pulumi 所有方面的更多细节。然而,为了保持这篇文章尽量简短,我将首先介绍下 Pulumi 的一些我最喜欢的方面。

我最喜欢的东西

这很难选择,但这里有一些关于 Pulumi 我最喜欢的东西:

开源。我坚信所有开发人员工具都应该是开源的。当然,Pulumi 也是一家公司,但是有充足的机会通过增加便利性以建立商业模式。(可以认为是​​Git 与 GitHub 的关系)我们从以前的工作中受益匪浅,其中包括 Docker、Terraform、Kubernetes、TypeScript 以及其他许多明确提及的工作。我们期待成为生态系统的一部分。因为我们在开放源代码方面下了很大功夫,所以我很高兴看到社区给我们带来什么,特别是在更高级别的软件包领域。

多语言。就像使用 Java 和.NET 一样,Pulumi 运行时的架构可以支持多种语言,并以目标语言的所有方面(风格、语法、软件包等)的惯用方式来实现。因为我们是开源的,任何人都可以贡献自己的力量。

混合云。我们的云对象模型是一个强大的基础,可以支持任何云提供商。这提供了一个统一的编程模型,工具和控制平面,用于在任何地方管理云软件。如果仅仅是为了让一个简单的基于容器的应用程序在生产中运行起来,没有必要学习三种不同的 YAML 方言和五种不同的 CLI。

云对象模型。这个底层云对象模型为您的云计算构建方式提供了丰富的视图。所得到的对象使用程序中的依赖关系组成一个 DAG,系统可以分析和理解这些依赖关系以提供洞察力,这是我们打算随着时间的推移解锁复杂的静态分析和可视化的功能。

可重复使用的组件。由于拥有真正的语言,我们可以构建更高层次的抽象。我最喜欢的例子之一是帮助我们的客户定期从部署中排除 1000 行 YAML,这是我们的 AWS 基础架构软件包。它采用 AWS 最佳实践来设置虚拟私有云,并提供专用子网和多可用区域支持,并将其转变为几行代码以配置整个网络:

import * as awsinfra from "@pulumi/aws-infra";
let network = new awsinfra.Network(`${prefix}-net`, {
    numberOfAvailabilityZones: 3, // Create subnets in many AZs
    usePrivateSubnets: true,      // Run inside private per-AZ subnets
});

迄今为止,我最喜欢的成功案例是将客户的 25,000 行 AWS CloudFormation YAML 文件(其中使用无服务器、容器、基础设施和三个自定义部署管道)使用 500 行 TypeScript 和一个 Pulumi 的持续部署架构来替换。这不仅仅使得公司所有工程师都可以理解的代码变得少得多,这样他们可以将过去需要花费数周时间才能完成的事情现在用一个下午就可以搞定,而且现在可以在任何云或原生的 Kubernetes 上运行,而不仅是在 AWS。管理团队的 CloudFormation 堆栈,而不是一个工作量过饱和的工程师,整个团队可以更加高效。

统一的容器构建/发布管道。尝试将容器投入生产时有个问题让我早就感到很沮丧,就是同步我的应用程序、容器和基础架构管理,因为每个容器都倾向于使用不同的工具。我们的云框架演示了一个集成的工作流程,在这个工作流程中,只需简单地运行 Pulumi 构建、diff、推送和拉取新的容器镜像,所有这些都经过精心安排,以消除停机时间。

**Lambda 无服务器功能 **。AWS 的取了个好名字:Lambda。在 Pulumi 中,我现在可以用我最喜欢的语言使用 lambda 表达式来编写我的无服务器函数,而不需要一行 YAML:

import * as aws from "@pulumi/aws";
import * as serverless from "@pulumi/aws-serverless";
let topic = new aws.sns.Topic("topic");
serverless.cloudwatch.onEvent("hourly", "rate(60 minutes)", event => {
    const sns = new (await import "aws-sdk").SNS();
    return sns.publish({
        Message: JSON.stringify({ event: event }),
        TopicArn: topic.id.get(),
    }).promise();
});

此功能允许您捕获对变量的引用:常量、配置设置或加密,甚至可以引用其他资源,以便与它们进行通信。当你第一次这样做的时候,我保证你会有一个“哇塞”的时刻,将无服务器连接到你写过的每一个事件驱动的代码片段。

使用 API 的资源。因为我可以捕获对其他云资源的引用,所以我可以在其上创建 API 以使它们更易于在我的运行时代码中使用。这使得“演员般的”编程模型无需处理配置和服务发现。

堆栈。Pulumi 的核心是“堆栈”的概念。堆栈是您的云计算的独立实例,其资源和配置与所有其他堆栈不同。您可能有一堆用于生产、暂存和测试的堆栈,或者可能是每个单一租户的环境。Pulumi 的 CLI 使得启动和卸载大量堆栈变得轻而易举。这会打开以前可能没有尝试过的工作流,例如每个开发人员都拥有自己的堆栈,将新堆叠起来(并拆除)以测试每个 Pull 请求,甚至将服务的层拆分成多个链接在一起的堆栈。

我将在未来的博客文章介绍如何做。现在 Pulumi 已经公开,期望在接下来的几天和几周内听到更多的消息。我希望这能让您更好地了解整体平台,其方法和独特优势。

下一步是什么?

我们希望通过 Pulumi,开发人员和 DevOps 团队都将体验到云的复兴。构建强大的云软件将更加愉快、更高效、更具协作性。现代云计算软件将从代码孤岛转变为等量的配置胶水,成为优雅的分布式系统。

这是一个难题。我绝不会说我们已经解决了它。我确实相信 Pulumi 是我亲身见过并希望最接近我心目中的云开发平台。在这个激动人心的时刻,投注于语言将使我们所有人“站在巨人的肩膀上”,这让我感到乐观;语言总是一个安全的赌注。

今天很可能是我职业生涯中最激动人心的一天。我想感谢我们的团队和所有帮助过我们的人,放纵我们的疯狂想法并相信我们。

现在访问https://pulumi.io,或者直接运行:

$ curl -fsSL https://get.pulumi.com | sh

我迫不及待想看看你将使用 Pulumi 构建的所有令人难以置信的东西。


P.S 我要感谢我已故的导师,最好的朋友 Chris Brumme。虽然 Chris 没办法和我们一起庆祝这一刻,但我清楚“Chris 每一步会做些什么”。Pulumi 是夏威夷语,是“扫帚”的意思,尽管这完全是他名字的错误发音,但为了纪念 Chirs 我还是用了它。

最后更新于 2024/11/21