Kurtosis:本地Devnet的深入研究

本文深入探讨了 Kurtosis 平台及其在受控环境中测试应用程序的功能。

Kurtosis:深入本地 Devnet

Kurtosis 简介

Kurtosis 是一种运行临时包的工具,这些包在 Starlark 中定义,这为开发者测试他们的应用程序、快速迭代和重新测试开辟了广阔的可能性。它从一开始就被构建为一个对开发者友好的平台,允许开发者在受控环境中测试他们的应用程序,而不需要复杂的设置或配置。

这篇博文的主要重点将是对 Kurtosis 平台的深入研究,探索其特性、功能,以及如何使用它在受控环境中测试应用程序。主要重点将放在一个构建在 Kurtosis 之上的包,称为 ethereum-package。这个包是 KurtosisethPandaOps 团队的智慧结晶,旨在让开发者能够轻松测试他们的 Ethereum 客户端和相应的工具。

为什么首先需要 Kurtosis?

你可能已经读到我们在过去的演示文稿、推文和博文中经常提到 kurtosis/ethereum-package。我们在许多不同的地方提到它的原因是我们的团队一直依赖它来快速测试各种客户端版本。它也被用作测试我们所有工具的主要试验台。由于它与工具的深度集成及其简单性,Kurtosis 已成为我们进行快速迭代本地测试的首选方法。

Kurtosis 基于 overrides(覆盖)工作,所有可配置的值都可以被 overriden(覆盖),允许开发人员轻松地将稳定的镜像替换为他们希望测试的镜像。这意味着我们可以在本地环境中执行集成测试,并快速知道它是否会中断。

除了作为独立工具很有用之外,Kurtosis 也可以在 CI 上运行,以确保客户端或工具能够测试他们的 pull requests,并确保健康的发布。我们将 kurtosis 与我们的测试断言工具 assertoor 打包到一个名为 kurtosis-assertoor-github-action 的 github action 中。如果你能提供关于 kurtosis 和 assertoor 的反馈,以便我们更容易在你的 CI pipelines 中运行它们,请提供反馈。

大众的本地 devnets

传统上,启动 devnets(开发网络)的标准方法是通过定制脚本。这些脚本通常是为特定客户端量身定制的,不包含任何工具。发布公开可访问的 devnets 需要更多的组织和协作,通常需要 DevOps 工程师的帮助。Kurtosis 使得减少这种辛苦成为可能,并在几分钟内自动完成设置私有 devnets 的过程,它还将工具扩展到这个 devnet,使全新范围的开发者能够执行本地开发。

如何使用 Kurtosis (基本指南)

前提条件

概念

Kurtosis 是一个 CLI 工具,它连接到 Kurtosis 引擎,该引擎是一个服务器,然后可以与系统交互以启动一个 package()。重要的是,在运行任何 package 之前,kurtosis 引擎始终在运行。

Kurtosis 引擎利用 dockerkubernetes 后端来执行定义的 package。docker 模式意味着代码在单个实例上执行,而 kubernetes 模式意味着代码在多节点 kubernetes 集群上执行。这意味着 Kurtosis packages 可以受益于本地执行以及可扩展的远程执行。

Kurtosis 是围绕 enclaves飞地)的概念构建的。这些 enclaves 是一种分离执行的方式,类似于 kubernetes 中的 namespace命名空间)。一个 enclave 的参与者通常无法以任何方式与另一个 enclave 的参与者进行交互。

快速入门指南

要在你的本地机器上开始你的第一个 devnet,你可以运行以下命令:

kurtosis engine start

然后我们可以使用 kurtosis run <package> 来启动任何 package。这个 package 是 kurtosis 可以解释的 starlark 代码的集合。可以通过 Github URL 或 git 仓库的本地路径来引用该 package。你可以通过运行以下命令来探索所有标志:

kurtosis run --help

为了我们的目的,我们将使用 ethereum-package。要运行 ethereum-package,你可以运行以下命令:

kurtosis run github.com/ethpandaops/ethereum-package

这将启动默认的 Ethereum devnet,其中包含一个节点(geth/lighthouse 对),kurtosis 负责创建 genesis state(创世状态),peering(对等连接),validator keys(验证者密钥)并确保节点以正确的标志启动。我们将在本文后面探讨如何自定义它以满足你的需求。

run 命令的输出将是一个参与者列表,以及他们暴露的端口。你可以像在任何其他网络上一样使用这些端口与 devnet 交互。

为了清理所有由 kurtosis run 命令实例化的资源,你可以运行以下命令:

kurtosis enclave rm <enclave-name> -f

如果没有其他 enclaves 正在运行,你也可以运行以下命令来清理所有资源:

kurtosis clean -a

自定义 devnet

Kurtosis 基于覆盖参数运行,因此如果默认的运行参数不足,你可以运行 kurtosis 并使用 --args-file <path-to-args-file>。此标志允许你传入一个 YAML/JSON 文件,其中包含你想要自定义的所有参数,当未配置参数时,将使用其默认值。所有可能的配置参数的详尽列表可以在这里找到。

我们维护了一个非详尽的已完成的配置文件列表,可以在 ethereum-package 仓库的 tests 文件夹中找到。我们希望这些示例能够展示该 package 的强大之处。

你也可以通过使用给定文件的原始 URL 来引用在线托管的 yaml 文件。这是一个你如何使用自定义配置文件运行 devnet 的示例:

kurtosis run github.com/ethpandaops/ethereum-package --args-file https://raw.githubusercontent.com/ethpandaops/ethereum-package/main/.github/tests/mix.yaml

自定义不同的参与者

网络中的参与者指的是将参与 devnet 的节点。你可以使用 count 参数指定具有相同配置的多个客户端。你可以使用新元素来指定不同的参与者。这是一个例子:

participants:
  - el_type: geth
    cl_type: lighthouse
    count: 3
  - el_type: nethermind
    cl_type: teku

上面的例子将启动 3x geth/lighthouse 节点和 1x nethermind/teku 及其默认参数。它们都将获得相同数量的验证者,并将提供相同的 genesis 文件和 peering 信息。

覆盖默认配置

你可以在配置文件中指定一个参数以覆盖它,客户端镜像也是如此。这是一个使用自定义 docker 容器用于 nethermind 节点的配置文件的示例:

participants:
  - el_type: nethermind
    el_image: ethpandaops/nethermind:best-image
  - el_type: besu
    cl_type: lighthouse

在这个例子中,我们将启动一个具有 nethermind/lighthouse(默认 CL) 和一个 besu/lighthouse 节点的网络。由于 nethermind 节点具有自定义镜像,它将使用指定的镜像启动,而其他节点将使用默认镜像。

运行自定义数量的验证者,使用不同的验证者客户端

为了运行一个客户端对以及自定义数量的验证者并使用不同的验证者客户端类型,你可以使用以下配置文件:

participants:
  - el_type: geth
    cl_type: lighthouse
    vc_type: lodestar
    validator_count: 100

在上面的例子中,你将启动一个 devnet,其中包含 1 个 geth 节点,1 个 lighthouse 节点和 100 个 lodestar 验证者节点,它们连接到 lighthouse 节点。

额外的参数、环境变量和额外的标签

如果你想传递额外的标志、参数、环境变量或标签到正在启动的 docker 容器,你可以使用以下配置文件(也适用于 clvc):

participants:
  - el_type: geth
    cl_type: lighthouse
    count: 3
    el_extra_params:
      - "--rpc"
    el_extra_env_vars: {"ETH_RPC_PORT": "8545"}
    el_extra_labels: {"com.example.label": "example"}

使用这些信息,你应该能够基本了解你可以使用 ethereum-package 做什么,以及如何根据你的需求自定义参与者。

部署整个 MEV 堆栈

Kurtosis 支持整个 MEV 以及 MEV 测试堆栈。这包括启动 mev-boost、mev-relays、builders 和 frontend 以展示交付的 payloads(负载)。这是一个你如何运行一个包含整个 MEV 堆栈的 devnet 的示例:

participants:
- el_type: geth
  cl_type: lighthouse
  count: 3
mev_type: full

mev_type full 将部署在 Mainnet ethereum 上看到的整个 MEV 堆栈。MEV 堆栈的每个部分都可以为测试目的进行自定义。但是,为了更容易的客户端原型设计,我们还支持 mev_type: mock,它部署了 relay 堆栈的 mock 实现,并由 这里 的工具管理。这种 mock 模式可以帮助迭代 builder API 的更改,而无需更新许多组件。

通过自定义 mev_boost_image 配置值,我们还可以利用此工作流程来测试在 mev-boost 层运行的工具。

自定义网络参数(基本)

下一步是深入研究你可以自定义的网络参数。这些参数在配置文件的 network_params 部分中定义。

最常用的参数是 seconds_per_slotgenesis_delayelectra_fork_epoch。这些参数可以帮助你的网络更快或更慢地生成 slots(),而 genesis_delay 将帮助你延迟网络的 genesis block(创世区块)。electra_fork_epoch 参数将帮助你定义 electra fork(Electra 分叉)应该何时发生。这可以帮助你通过在任何给定 epoch(纪元)激活下一个 fork 来测试 feature branches(特性分支)。这是一个你如何在配置文件中定义这些参数的示例:

network_params:
  seconds_per_slot: 6
  genesis_delay: 120
  electra_fork_epoch: 5

还可以调整更高级的配置选项,例如 min_validator_withdrawability_delayshard_committee_period

自定义网络参数(高级)

Minimal 预设

如果你想为网络使用一个 minimal preset最小预设),你可以使用以下配置文件:

network_params:
  preset: minimal

但是,请记住,此 preset 需要在配置文件中定义自定义共识层客户端,可以在这里找到这些客户端对的示例。minimal preset 也会破坏某些工具,因此请谨慎操作。

Shadowfork 和引导(高级)

ethereum-package 现在通过在配置文件中定义 networknetwork_sync_base_url 参数来支持引导和 shadowforks(影子分叉)。这将帮助你从特定 snapshot(快照)引导网络,并运行网络的 shadowfork。这是一个你如何在配置文件中定义这些参数的示例:

network_params:
  network: holesky-shadowfork
  network_sync_base_url: https://ethpandaops-ethereum-node-snapshots.ams3.digitaloceanspaces.com/
persistent: true

这些参数将从上面链接的 s3 bucket 中定义的 holesky 网络中提取最新的 snapshot。此 snapshot 是使用工具 snapshotter 创建的,并指定了存储数据的格式。导入数据后,genesis 工具将为客户端创建必要的数据,以启动新的 beaconchain(信标链)并在定义的 electra_fork_epoch 执行 shadowfork。

强烈建议在使用 shadowforks 时保持持久性,因为这需要多个 GB 的存储空间来存储链数据,并且不建议将其全部存储在 RAM 或 SWAP 中。

注意: kurtosis clean -a 将擦除链数据并清除 enclave,如果你想再次运行 shadowfork,则必须重新下载 snapshot。

如何使用 Kurtosis (高级指南)

所以到目前为止,你应该非常熟悉如何使用 ethereum-package,并且你应该非常熟悉如何根据你的需求自定义 devnet。在本节中,我们将探讨 ethereum-package 的一些更高级的功能,以及你如何利用它们来发挥你的优势。

使用 Kubernetes 的长时间运行的 devnets

如果你希望长时间运行 devnet,建议使用 Kubernetes 作为 kurtosis 的后端引擎。这需要更详细的配置。一个前提条件是你有一个正在运行的 Kubernetes 集群,并且该集群被设置为你当前的上下文。(Kubernetes 集群的设置或如何设置上下文超出了这篇博文的范围,但你可以在这里找到更多信息)。

使用以下指南调整你的 kurtosis-config.yaml 文件,在其中定义 kurtosis 引擎的连接参数。

在你设置好你的 kurtosis-config.yaml 文件后,你可以使用以下命令启动 kurtosis 引擎:

kurtosis cluster set <cluster-name>
kurtosis engine restart
kurtosis gateway

注意: kurtosis gateway 命令将启动一个本地代理,允许你连接到在 Kubernetes 集群上运行的 kurtosis 引擎。无论何时你与 kurtosis 引擎交互,都需要在后台运行它。如果 gateway 命令没有运行,你将无法与 kurtosis 引擎交互,但这不会影响任何正在运行的 enclaves。

然后从这一点开始,你可以使用相同的 kurtosis run 命令来启动你的 devnet,它将 targeting(指向) Kubernetes 集群而不是本地机器。这使你能够长时间运行 devnets,你甚至可以与你的团队成员共享 devnet。此外,这使你能够运行更大的 devnets,其中你的(自动扩展 - 可选)Kubernetes 集群可以处理负载。

所有可能的配置参数的完整指南可以在 ethereum-package 的非常详细的文档中找到。

Kubernetes 特定的配置标志

当 Kubernetes 上运行 devnet 时,你可以使用一些额外的标志来根据你的需求自定义 devnet。其中一些标志是 tolerations容忍度)和 node selectors节点选择器)。这些标志可以用于定义 devnet 应该在哪些节点上运行,以及 devnet 不应该在哪些节点上运行。强烈建议在使用与其他工作负载共享的 kubernetes 集群时定义这些标志。节点选择器和容忍度可以帮助你确保 devnet 运行在未被其他工作负载使用的节点上,并且 devnet 不会干扰其他工作负载。

这些标志是:

participants:
  - el_type: geth
    cl_type: lighthouse
    count: 3
    node_selectors:
      kubernetes.io/hostname: node1
    tolerations:  # tolerations for this participant
      - key: "key"
    cl_toleration: []  # tolerations for the consensus client
    el_toleration: []  # tolerations for the execution client
    vc_toleration: []  # tolerations for the validator client

另一个可以定义的重要的标志是 CPU 和内存请求以及限制。每种客户端类型都有这些参数的默认值,但是你可以通过在配置文件中定义它们来覆盖它们。这些标志是 (也适用于 clvc):

el_min_cpu: 0
el_max_cpu: 0
el_min_mem: 0
el_max_mem: 0
el_volume_size: 0

自定义这些值将帮助你确保 devnet 运行在一个具有足够资源来处理负载的节点上,并帮助你避免与在同一节点上运行的其他工作负载发生任何资源争用。以及帮助你的 kubernetes 集群根据 devnet 的资源需求自动向上/向下扩展。

结论

在这篇博文中,我们探讨了 ethereum-package 的基本和高级功能,以及你如何利用它们来发挥你的优势。我们探讨了如何根据你的需求自定义不同的参与者,devnet 网络参数,以及你如何在 docker 或 Kubernetes 上运行 devnet。我们希望这篇博文让你很好地理解了你如何使用 ethereum-package 在受控环境中测试你的 Ethereum 客户端和工具。

非常感谢整个 Kurtosis 团队构建了如此出色的平台!🚀

参考

Ethereum-package 客户端和工具

ethereum-package 开箱即用地支持各种各样的 ethereum 客户端。这些客户端是:

执行层客户端

  • Geth - Ethereum 协议的 Go 实现
  • Nethermind - 高性能 .NET Core 实现
  • Besu - Hyperledger 的 Java 实现
  • Erigon - 专注于效率的实现
  • Reth - Paradigm 的 Rust 实现
  • Nimbus-eth1 - Nim 实现

共识层客户端

  • Lighthouse - Sigma Prime 的 Rust 实现
  • Teku - ConsenSys 的 Java 实现
  • Nimbus-eth2 - 用于资源受限设备的 Nim 实现
  • Prysm - Prysmatic Labs 的 Go 实现
  • Lodestar - ChainSafe 的 TypeScript 实现
  • Grandine - Grandine 的 Rust 实现

工具

  • assertoor - (关于 assertoor 的更多细节可以在 assertoor 博文中找到)
  • tx_spammer - 基本的事务垃圾邮件发送工具,可以帮助你生成随机事务来测试块中的事务包含
  • blob_spammer - 基本的 blob 垃圾邮件发送工具,可以帮助你生成随机的 blobs 来测试网络处理大量数据的能力
  • goomy_blob - 更高级的 blob 垃圾邮件发送工具,可以帮助你生成具有特定结构的 blobs 来测试网络处理结构化数据的能力
  • el_forkmon - 一个 fork 监控工具,可以帮助你监控执行层客户端的 forks 和 reorgs
  • blockscout - 一个块浏览器工具,可以帮助你浏览网络上的块和事务
  • beacon_metrics_gazer - 一个验证者指标工具,可以帮助你监控网络上验证者的性能 - 需要运行 prometheus_grafana
  • dora - 一个轻量级的信标链浏览器
  • full_beaconchain_explorer - 一个完整的信标链浏览器,监控共识和执行层数据
  • prometheus_grafana - 一个额外的工具,启动一个带有 prometheus 的 grafana,以帮助你监控 devnet 的性能
  • blobscan - 一个可以帮助你扫描网络上的 blobs 并分析正在发送的数据的工具
  • dugtrio - 一个共识层负载均衡器
  • blutgang - 一个执行层负载均衡器
  • rpc-snooper - 一个中间人工具,可以帮助你监听在共识和执行层客户端之间,以及在共识层客户端和验证者客户端之间进行的 RPC 调用
  • blobber - 一个帮助你生成恶意 blobs 来测试网络处理恶意数据的能力的工具
  • ethereum-metrics-exporter - 一个帮助你将以太坊客户端的指标导出到 prometheus 的工具 - 需要运行 prometheus_grafana
  • xatu - 一个用于数据管道的中心化以太坊网络监控工具 - 关于 xatu 的更多细节可以在 xatu 博文 中找到
  • mev - 使用 mev_params 完全支持 MEV 工作流工具。
  • 原文链接: ethpandaops.io/posts/kur...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
EthPandaOps
EthPandaOps
https://ethpandaops.io