HashiCorp工具中的go

您所在的位置:网站首页 go语言动态加载插件是什么 HashiCorp工具中的go

HashiCorp工具中的go

2024-03-30 06:16| 来源: 网络整理| 查看: 265

通过RPC的Go插件系统

go-plugin 是一个基于RPC的Go(golang)插件系统。它是HashiCorp工具中使用了4年多的插件系统。虽然最初是为Packer创建的,但它还被Terraform、Nomad、Vault和Boundary所使用。

虽然插件系统是通过RPC的,但它目前只被设计为在本地[可靠]网络上工作。真正的网络上的插件不被支持,并且会导致意外的行为。

这个插件系统已经在许多不同的项目中的数百万台机器上使用过,并被证明是经过战斗加固的,可以用于生产。

特点

HashiCorp的插件系统支持一系列的功能。

插件是Go接口的实现。这使得编写和使用插件感觉非常自然。对一个插件作者来说:你只需实现一个接口,就像它要在同一个进程中运行一样。对于一个插件用户来说:你只需使用和调用一个接口的函数,就像它在同一个进程中一样。这个插件系统处理中间的通信。

跨语言支持。几乎所有的主要语言都可以编写(和消费)插件。这个库支持通过gRPC为插件提供服务。基于gRPC的插件使得插件可以用任何语言编写。

支持复杂的参数和返回值。这个库提供了处理复杂参数和返回值的API,如接口、io.Reader/Writer ,等等。我们通过给你一个库(MuxBroker),用于在客户端/服务器之间创建新的连接,以服务于额外的接口或传输原始数据。

双向通信。因为插件系统支持复杂的参数,主机进程可以向它发送接口实现,插件可以回调到主机进程。

内置日志。任何使用log 标准库的插件都会有日志数据自动发送到主机进程。宿主进程将镜像该输出,并以插件二进制文件的路径为前缀。这使得对插件的调试变得简单。如果主机系统使用hclog,那么日志数据将是结构化的。如果插件也使用hclog,那么来自插件的日志将被发送到主机hclog并被结构化。

协议版本。支持一个非常基本的 "协议版本",它可以被递增以使以前的任何插件失效。这在接口签名改变、协议级别改变是必要的等情况下很有用。当协议版本不兼容时,会向终端用户显示一个人性化的错误信息。

**Stdout/Stderr同步。**当插件是子进程时,它们可以继续像往常一样使用stdout/stderr,输出将被镜像到主进程。主进程可以控制这些流向的io.Writer ,以防止这种情况发生。

TTY的保存。插件子进程与主机进程连接到相同的stdin文件描述符上,使需要TTY的软件能够工作。例如,一个插件可以执行ssh ,即使有多个子进程和RPC发生,它在最终用户看来也是完美的。

**在插件运行时进行主机升级。**插件可以被 "重新连接",以便主机进程可以在插件仍在运行时进行升级。ReattachConfig 这需要主机/插件知道这是可能的,并正确地daemonize。NewClient ,以确定是否以及如何重新连接。

密码学上安全的插件。插件可以用预期的校验和进行验证,RPC通信可以被配置为使用TLS。宿主进程必须有适当的安全保障来保护这个配置。

架构

HashiCorp的插件系统通过启动子进程和通过RPC(使用标准net/rpc 或gRPC)进行通信来工作。任何插件和主机进程之间都有一个单一的连接。对于基于net/rpc的插件,我们使用一个连接复用库来复用上面的任何其他连接。对于基于gRPC的插件,HTTP2协议处理复用。

这种架构有很多好处。

插件不能让你的主机进程崩溃。插件中的恐慌不会使插件的用户恐慌。

插件非常容易编写:只要编写一个Go程序和go build 。或者使用任何其他语言来编写一个gRPC服务器,只需要少量的模板来支持go-plugin。

插件非常容易安装:只需将二进制文件放在主机能找到的地方(取决于主机,但这个库也提供了帮助器),其余的由插件主机处理。

插件可以是相对安全的。插件只能访问给它的接口和args,而不能访问进程的整个内存空间。此外,go-plugin可以通过TLS与插件进行通信。

使用方法

要使用插件系统,你必须采取以下步骤。这些是必须完成的高级步骤。例子可在examples/ 目录中找到。

选择你想为插件公开的接口。

对于每个接口,实现该接口的一个实现,通过net/rpc 连接或通过gRPC连接或两者进行通信。你必须同时实现一个客户端和服务器端的实现。

创建一个Plugin 实现,知道如何为给定的插件类型创建RPC客户端/服务器。

插件作者调用plugin.Serve ,从main 函数中提供一个插件。

插件用户使用plugin.Client 来启动一个子进程,并通过RPC请求一个接口实现。

这就是了!在实践中,第2步是最繁琐和耗时的步骤。即便如此,它也不是很困难,你可以在examples/ 目录以及我们的各种开源项目中看到一些例子。

关于完整的API文档,请参阅GoDoc。

路线图

我们的插件系统是不断发展的。当我们将插件系统用于新项目或现有项目的新功能时,我们不断发现我们可以进行的改进。

在这个时间点上,插件系统的路线图是。

**语义版本管理。**插件将能够实现语义版本。这个插件系统将给主机进程提供一个约束版本的系统。这是对已经存在的协议版本控制的补充,后者更多的是针对较大的底层变化。

关于共享库呢?

当我们开始使用插件时(2012年底,2013年初),通过RPC的插件是唯一的选择,因为Go不支持动态库加载。今天,Go支持插件标准库,但有一些限制。自2012年以来,我们的插件系统已经从数以千万计的用户使用中稳定下来,并且有许多我们非常重视的好处。

例如,我们在Vault中使用这个插件系统,在那里,由于安全原因,动态库加载是不可接受的。这是一个极端的例子,但我们相信我们的库系统与动态库加载相比,优点多于缺点,由于我们已经建立并测试了多年,我们将继续使用它。

与我们的系统相比,共享库有一个主要的优势,那就是更高的性能。在我们各种工具的实际应用中,我们从未要求我们的插件系统有更高的性能,而且它的吞吐量非常高,所以目前这对我们来说并不是一个问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3