Skip to content

Commit

Permalink
feat: add pitfalls for persistent storage as a warning (#441)
Browse files Browse the repository at this point in the history
  • Loading branch information
barnabasbusa authored Jan 9, 2024
1 parent 060fd8f commit 69da8f0
Show file tree
Hide file tree
Showing 15 changed files with 285 additions and 5 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ Where `network_params.yaml` contains the parameters for your network in your hom

Kurtosis packages work the same way over Docker or on Kubernetes. Please visit our [Kubernetes docs](https://docs.kurtosis.com/k8s) to learn how to spin up a private testnet on a Kubernetes cluster.

#### Considerations for Running on a Public Testnet with a Cloud Provider
When running on a public testnet using a cloud provider's Kubernetes cluster, there are a few important factors to consider:
1. State Growth: The growth of the state might be faster than anticipated. This could potentially lead to issues if the default parameters become insufficient over time. It's important to monitor state growth and adjust parameters as necessary.

2. Persistent Storage Speed: Most cloud providers provision their Kubernetes clusters with relatively slow persistent storage by default. This can cause performance issues, particularly with Ethereum Light (EL) clients.

3. Network Syncing: The disk speed provided by cloud providers may not be sufficient to sync with networks that have high demands, such as the mainnet. This could lead to syncing issues and delays.

To mitigate these issues, you can use the `el_client_volume_size` and `cl_client_volume_size` flags to override the default settings locally. This allows you to allocate more storage to the EL and CL clients, which can help accommodate faster state growth and improve syncing performance. However, keep in mind that increasing the volume size may also increase your cloud provider costs. Always monitor your usage and adjust as necessary to balance performance and cost.

For optimal performance, we recommend using a cloud provider that allows you to provision Kubernetes clusters with fast persistent storage or self hosting your own Kubernetes cluster with fast persistent storage.

#### Tear down

The testnet will reside in an [enclave][enclave] - an isolated, ephemeral environment. The enclave and its contents (e.g. running containers, files artifacts, etc) will persist until torn down. You can remove an enclave and its contents with:
Expand Down Expand Up @@ -125,6 +138,11 @@ participants:
# A list of optional extra env_vars the el container should spin up with
el_extra_env_vars: {}
# Persistent storage size for the EL client container (in MB)
# Defaults to 0, which means that the default size for the client will be used
# Default values can be found in /src/package_io/constants.star VOLUME_SIZE
el_client_volume_size: 0
# A list of optional extra labels the el container should spin up with
# Example; el_extra_labels: {"ethereum-package.partition": "1"}
el_extra_labels: {}
Expand Down Expand Up @@ -154,6 +172,11 @@ participants:
# Defaults to false
cl_split_mode_enabled: false
# Persistent storage size for the CL client container (in MB)
# Defaults to 0, which means that the default size for the client will be used
# Default values can be found in /src/package_io/constants.star VOLUME_SIZE
cl_client_volume_size: 0
# A list of optional extra params that will be passed to the CL client Beacon container for modifying its behaviour
# If the client combines the Beacon & validator nodes (e.g. Teku, Nimbus), then this list will be passed to the combined Beacon-validator node
beacon_extra_params: []
Expand Down
15 changes: 15 additions & 0 deletions src/cl/lighthouse/lighthouse_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def launch(
extra_beacon_labels,
extra_validator_labels,
persistent,
cl_volume_size,
split_mode_enabled=False,
):
beacon_service_name = "{0}".format(service_name)
Expand All @@ -135,6 +136,17 @@ def launch(
bn_max_cpu = int(bn_max_cpu) if int(bn_max_cpu) > 0 else BEACON_MAX_CPU
bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY
network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
cl_volume_size = (
int(cl_volume_size)
if int(cl_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["lighthouse_volume_size"]
)

# Launch Beacon node
beacon_config = get_beacon_config(
Expand All @@ -156,6 +168,7 @@ def launch(
extra_beacon_params,
extra_beacon_labels,
persistent,
cl_volume_size,
)

beacon_service = plan.add_service(beacon_service_name, beacon_config)
Expand Down Expand Up @@ -283,6 +296,7 @@ def get_beacon_config(
extra_params,
extra_labels,
persistent,
cl_volume_size,
):
# If snooper is enabled use the snooper engine context, otherwise use the execution client context
if snooper_enabled:
Expand Down Expand Up @@ -390,6 +404,7 @@ def get_beacon_config(
if persistent:
files[BEACON_DATA_DIRPATH_ON_BEACON_SERVICE_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)
return ServiceConfig(
image=image,
Expand Down
18 changes: 17 additions & 1 deletion src/cl/lodestar/lodestar_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def launch(
extra_beacon_labels,
extra_validator_labels,
persistent,
cl_volume_size,
split_mode_enabled=False,
):
beacon_service_name = "{0}".format(service_name)
Expand All @@ -114,6 +115,18 @@ def launch(
bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY

network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
cl_volume_size = (
int(cl_volume_size)
if int(cl_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["lodestar_volume_size"]
)

# Launch Beacon node
beacon_config = get_beacon_config(
plan,
Expand All @@ -134,6 +147,7 @@ def launch(
extra_beacon_params,
extra_beacon_labels,
persistent,
cl_volume_size,
)

beacon_service = plan.add_service(beacon_service_name, beacon_config)
Expand Down Expand Up @@ -253,6 +267,7 @@ def get_beacon_config(
extra_params,
extra_labels,
persistent,
cl_volume_size,
):
el_client_rpc_url_str = "http://{0}:{1}".format(
el_client_context.ip_addr,
Expand Down Expand Up @@ -344,7 +359,8 @@ def get_beacon_config(

if persistent:
files[BEACON_DATA_DIRPATH_ON_SERVICE_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name)
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)
return ServiceConfig(
image=image,
Expand Down
18 changes: 17 additions & 1 deletion src/cl/nimbus/nimbus_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def launch(
extra_beacon_labels,
extra_validator_labels,
persistent,
cl_volume_size,
split_mode_enabled,
):
beacon_service_name = "{0}".format(service_name)
Expand All @@ -161,6 +162,18 @@ def launch(
bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY

network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
cl_volume_size = (
int(cl_volume_size)
if int(cl_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["nimbus_volume_size"]
)

beacon_config = get_beacon_config(
plan,
launcher.el_cl_genesis_data,
Expand All @@ -182,6 +195,7 @@ def launch(
extra_beacon_labels,
split_mode_enabled,
persistent,
cl_volume_size,
)

beacon_service = plan.add_service(beacon_service_name, beacon_config)
Expand Down Expand Up @@ -291,6 +305,7 @@ def get_beacon_config(
extra_labels,
split_mode_enabled,
persistent,
cl_volume_size,
):
validator_keys_dirpath = ""
validator_secrets_dirpath = ""
Expand Down Expand Up @@ -392,7 +407,8 @@ def get_beacon_config(

if persistent:
files[BEACON_DATA_DIRPATH_ON_SERVICE_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name)
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)

return ServiceConfig(
Expand Down
17 changes: 16 additions & 1 deletion src/cl/prysm/prysm_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def launch(
extra_beacon_labels,
extra_validator_labels,
persistent,
cl_volume_size,
split_mode_enabled=False,
):
split_images = images.split(IMAGE_SEPARATOR_DELIMITER)
Expand Down Expand Up @@ -140,6 +141,17 @@ def launch(
bn_max_cpu = int(bn_max_cpu) if int(bn_max_cpu) > 0 else BEACON_MAX_CPU
bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY
network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
cl_volume_size = (
int(cl_volume_size)
if int(cl_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["prysm_volume_size"]
)

beacon_config = get_beacon_config(
plan,
Expand All @@ -160,6 +172,7 @@ def launch(
extra_beacon_params,
extra_beacon_labels,
persistent,
cl_volume_size,
)

beacon_service = plan.add_service(beacon_service_name, beacon_config)
Expand Down Expand Up @@ -271,6 +284,7 @@ def get_beacon_config(
extra_params,
extra_labels,
persistent,
cl_volume_size,
):
# If snooper is enabled use the snooper engine context, otherwise use the execution client context
if snooper_enabled:
Expand Down Expand Up @@ -350,7 +364,8 @@ def get_beacon_config(

if persistent:
files[BEACON_DATA_DIRPATH_ON_SERVICE_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name)
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)

return ServiceConfig(
Expand Down
18 changes: 17 additions & 1 deletion src/cl/teku/teku_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def launch(
extra_beacon_labels,
extra_validator_labels,
persistent,
cl_volume_size,
split_mode_enabled,
):
beacon_service_name = "{0}".format(service_name)
Expand All @@ -143,6 +144,18 @@ def launch(
bn_min_mem = int(bn_min_mem) if int(bn_min_mem) > 0 else BEACON_MIN_MEMORY
bn_max_mem = int(bn_max_mem) if int(bn_max_mem) > 0 else BEACON_MAX_MEMORY

network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
cl_volume_size = (
int(cl_volume_size)
if int(cl_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["teku_volume_size"]
)

config = get_beacon_config(
plan,
launcher.el_cl_genesis_data,
Expand All @@ -164,6 +177,7 @@ def launch(
extra_beacon_labels,
split_mode_enabled,
persistent,
cl_volume_size,
)

beacon_service = plan.add_service(service_name, config)
Expand Down Expand Up @@ -276,6 +290,7 @@ def get_beacon_config(
extra_labels,
split_mode_enabled,
persistent,
cl_volume_size,
):
validator_keys_dirpath = ""
validator_secrets_dirpath = ""
Expand Down Expand Up @@ -399,7 +414,8 @@ def get_beacon_config(

if persistent:
files[BEACON_DATA_DIRPATH_ON_SERVICE_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name)
persistent_key="data-{0}".format(service_name),
size=cl_volume_size,
)
return ServiceConfig(
image=image,
Expand Down
15 changes: 15 additions & 0 deletions src/el/besu/besu_launcher.star
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def launch(
extra_env_vars,
extra_labels,
persistent,
el_volume_size,
):
log_level = input_parser.get_client_log_level_or_default(
participant_log_level, global_log_level, BESU_LOG_LEVELS
Expand All @@ -84,6 +85,17 @@ def launch(
el_max_cpu = int(el_max_cpu) if int(el_max_cpu) > 0 else EXECUTION_MAX_CPU
el_min_mem = int(el_min_mem) if int(el_min_mem) > 0 else EXECUTION_MIN_MEMORY
el_max_mem = int(el_max_mem) if int(el_max_mem) > 0 else EXECUTION_MAX_MEMORY
network_name = (
"devnets"
if launcher.network != "kurtosis"
and launcher.network not in constants.PUBLIC_NETWORKS
else launcher.network
)
el_volume_size = (
el_volume_size
if int(el_volume_size) > 0
else constants.VOLUME_SIZE[network_name]["besu_volume_size"]
)

cl_client_name = service_name.split("-")[3]

Expand All @@ -105,6 +117,7 @@ def launch(
extra_env_vars,
extra_labels,
persistent,
el_volume_size,
)

service = plan.add_service(service_name, config)
Expand Down Expand Up @@ -147,6 +160,7 @@ def get_config(
extra_env_vars,
extra_labels,
persistent,
el_volume_size,
):
cmd = [
"besu",
Expand Down Expand Up @@ -219,6 +233,7 @@ def get_config(
if persistent:
files[EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER] = Directory(
persistent_key="data-{0}".format(service_name),
size=el_volume_size,
)
return ServiceConfig(
image=image,
Expand Down
Loading

0 comments on commit 69da8f0

Please sign in to comment.