mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
feat: ✨ Deployment improvements & environmental overrides (#103)
This PR contains improvements to the DataHaven deployment infrastructure: 1. Directory restructure: Moved from `deployment/` to `deploy/` (more common for K8s / Helm -based deployment configs). 2. Added **local environment** support: updated CLI to support deploying to a local K8s cluster. 3. Manual deployment script: `deploy/scripts/deploy.sh` for manual deployments. 4. Environment-specific configurations: Structured values files for each environment. 5. Chart organization: Renamed bridges-common-relay to relay for clarity. --------- Co-authored-by: Gonza Montiel <gon.montiel@gmail.com> Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
This commit is contained in:
parent
a6c1cb2ab2
commit
c3e6f1258b
51 changed files with 614 additions and 114 deletions
190
deploy/README.md
Normal file
190
deploy/README.md
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
# DataHaven Deployment
|
||||
|
||||
This directory contains all the necessary files and configurations for deploying DataHaven to various environments.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
deploy/
|
||||
├── charts/ # Helm charts
|
||||
│ ├── node/ # Node chart
|
||||
│ │ └── datahaven/ # DataHaven-specific node configurations
|
||||
│ │ ├── dh-bootnode.yaml
|
||||
│ │ └── dh-validator.yaml
|
||||
│ └── relay/ # Relay chart
|
||||
│ └── snowbridge/ # Snowbridge-specific relay configurations
|
||||
│ ├── dh-beacon-relay.yaml # Beacon chain relay
|
||||
│ ├── dh-beefy-relay.yaml # BEEFY consensus relay
|
||||
│ └── dh-execution-relay.yaml # Execution layer relay
|
||||
├── environments/ # Environment-specific configurations
|
||||
│ ├── local/ # Local development environment
|
||||
│ │ └── values.yaml
|
||||
│ ├── stagenet/ # Staging environment
|
||||
│ └── values.yaml
|
||||
└── scripts/ # Deployment scripts
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes cluster
|
||||
- kubectl configured
|
||||
- Helm 3.x installed
|
||||
|
||||
## Deployment
|
||||
|
||||
To deploy to a specific environment:
|
||||
|
||||
```bash
|
||||
./scripts/deploy.sh <environment>
|
||||
```
|
||||
|
||||
Example:
|
||||
```bash
|
||||
./scripts/deploy.sh local
|
||||
```
|
||||
|
||||
Available environments:
|
||||
- `local`: Local development environment (minimal resources)
|
||||
- `stagenet`: Staging environment for pre-release testing
|
||||
|
||||
## Environment Details
|
||||
|
||||
### Local
|
||||
- Single replica
|
||||
- Minimal resources (256Mi memory, 100m CPU)
|
||||
- Local image tags
|
||||
- Small persistence size
|
||||
|
||||
### Stagenet
|
||||
- 2 replicas
|
||||
- Medium resources (512Mi memory, 200m CPU)
|
||||
- Stagenet image tags
|
||||
- 20Gi persistence size
|
||||
|
||||
## Configuration Structure
|
||||
|
||||
The configuration is organized in layers, with later layers overriding earlier ones:
|
||||
|
||||
1. Base Configurations (`charts/node/datahaven/`):
|
||||
- Base configurations for DataHaven nodes
|
||||
- Default values for bootnode and validator
|
||||
|
||||
2. Environment-Specific Configurations (`environments/<env>/values.yaml`):
|
||||
- Environment-specific settings
|
||||
- Resource configurations
|
||||
- Image tags
|
||||
- Replica counts
|
||||
- Storage configurations
|
||||
|
||||
The deployment process:
|
||||
1. Loads base configurations from the respective chart directories
|
||||
2. Applies environment-specific overrides from `environments/<env>/values.yaml`
|
||||
3. Deploys the components with the merged configuration
|
||||
|
||||
## Components
|
||||
|
||||
### Nodes
|
||||
- **Bootnode**: Entry point for the network
|
||||
- **Validator**: Validates transactions and produces blocks
|
||||
|
||||
### Relays
|
||||
- **Snowbridge Relays**: Handle cross-chain communication with Ethereum
|
||||
- **Beacon Relay**: Relays Ethereum beacon chain data
|
||||
- **BEEFY Relay**: Relays BEEFY consensus data for finality
|
||||
- **Execution Relay**: Relays Ethereum execution layer data
|
||||
|
||||
## Development
|
||||
|
||||
For local development:
|
||||
1. Ensure you have a local Kubernetes cluster (e.g., Minikube, Kind)
|
||||
2. Deploy using the local environment:
|
||||
```bash
|
||||
./scripts/deploy.sh local
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Common issues and solutions:
|
||||
|
||||
1. Namespace doesn't exist:
|
||||
```bash
|
||||
kubectl create namespace kt-datahaven-<env>
|
||||
```
|
||||
|
||||
2. Helm dependencies need updating:
|
||||
```bash
|
||||
helm dependency update charts/node
|
||||
helm dependency update charts/relay
|
||||
```
|
||||
|
||||
3. View deployment status:
|
||||
```bash
|
||||
kubectl get all -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
4. Preview deployment changes:
|
||||
```bash
|
||||
./scripts/deploy.sh <env> true
|
||||
```
|
||||
|
||||
## Manual Deployment (Advanced)
|
||||
|
||||
For advanced users who want to deploy components individually or need more control:
|
||||
|
||||
### DataHaven Bootnode & Validators
|
||||
|
||||
#### Deploy individual components
|
||||
```bash
|
||||
cd deploy
|
||||
helm upgrade --install dh-bootnode charts/node -f charts/node/datahaven/dh-bootnode.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
|
||||
helm upgrade --install dh-validator charts/node -f charts/node/datahaven/dh-validator.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
#### Access validator node with Polkadot.js apps
|
||||
```bash
|
||||
kubectl port-forward svc/dh-validator-0 -n kt-datahaven-<env> 9955:9955
|
||||
# Then visit: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9955#/explorer
|
||||
```
|
||||
|
||||
#### Remove DataHaven components
|
||||
```bash
|
||||
helm uninstall dh-bootnode -n kt-datahaven-<env>
|
||||
helm uninstall dh-validator -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
#### Cleanup volumes
|
||||
```bash
|
||||
kubectl delete pvc -l app.kubernetes.io/instance=dh-bootnode -n kt-datahaven-<env>
|
||||
kubectl delete pvc -l app.kubernetes.io/instance=dh-validator -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
### Snowbridge Relayers
|
||||
|
||||
#### Create required secrets
|
||||
```bash
|
||||
kubectl create secret generic dh-beefy-relay-ethereum-key --from-literal=pvk="<ETHEREUM_PRIVATE_KEY>" -n kt-datahaven-<env>
|
||||
kubectl create secret generic dh-beacon-relay-substrate-key --from-literal=pvk="<SUBSTRATE_PRIVATE_KEY>" -n kt-datahaven-<env>
|
||||
kubectl create secret generic dh-execution-relay-substrate-key --from-literal=pvk="<SUBSTRATE_PRIVATE_KEY>" -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
#### Deploy individual relay components
|
||||
```bash
|
||||
cd deploy
|
||||
helm upgrade --install dh-beacon-relay charts/relay -f charts/relay/snowbridge/dh-beacon-relay.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
|
||||
helm upgrade --install dh-beefy-relay charts/relay -f charts/relay/snowbridge/dh-beefy-relay.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
|
||||
helm upgrade --install dh-execution-relay charts/relay -f charts/relay/snowbridge/dh-execution-relay.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
#### Remove relay components
|
||||
```bash
|
||||
helm uninstall dh-beacon-relay -n kt-datahaven-<env>
|
||||
helm uninstall dh-beefy-relay -n kt-datahaven-<env>
|
||||
helm uninstall dh-execution-relay -n kt-datahaven-<env>
|
||||
```
|
||||
|
||||
#### Delete relay secrets
|
||||
```bash
|
||||
kubectl delete secret dh-beefy-relay-ethereum-key -n kt-datahaven-<env>
|
||||
kubectl delete secret dh-beacon-relay-substrate-key -n kt-datahaven-<env>
|
||||
kubectl delete secret dh-execution-relay-substrate-key -n kt-datahaven-<env>
|
||||
```
|
||||
|
|
@ -11,7 +11,6 @@ imagePullSecrets:
|
|||
- name: datahaven-dockerhub
|
||||
|
||||
node:
|
||||
chain: stagenet-local
|
||||
command: datahaven-node
|
||||
# customChainspec: true # see extraInitContainers, chainspec-generator
|
||||
role: full
|
||||
|
|
@ -63,4 +62,4 @@ extraContainers:
|
|||
- name: chain-data
|
||||
subPath: chainspec.json
|
||||
mountPath: /usr/share/nginx/html/chainspec.json
|
||||
readOnly: true
|
||||
readOnly: true
|
||||
|
|
@ -11,7 +11,6 @@ imagePullSecrets:
|
|||
- name: datahaven-dockerhub
|
||||
|
||||
node:
|
||||
chain: stagenet-local
|
||||
command: datahaven-node
|
||||
# customChainspecUrl: http://dh-bootnode:8080/chainspec.json
|
||||
# forceDownloadChainspec: true
|
||||
|
|
@ -78,4 +77,4 @@ extraInitContainers:
|
|||
fi
|
||||
volumeMounts:
|
||||
- mountPath: /chain-data
|
||||
name: chain-data
|
||||
name: chain-data
|
||||
|
|
@ -230,4 +230,4 @@ spec:
|
|||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
54
deploy/environments/local/values.yaml
Normal file
54
deploy/environments/local/values.yaml
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Global settings
|
||||
global:
|
||||
environment: local
|
||||
namespace: kt-datahaven-local
|
||||
|
||||
# Common image settings
|
||||
image:
|
||||
tag: local
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets:
|
||||
- name: datahaven-dockerhub
|
||||
|
||||
# Common node settings
|
||||
node:
|
||||
chain: local
|
||||
chainData:
|
||||
storageClass: "hostpath"
|
||||
persistence:
|
||||
size: 10Gi
|
||||
chainKeystore:
|
||||
storageClass: "hostpath"
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "200m"
|
||||
|
||||
# Override settings for bootnode
|
||||
dh-bootnode:
|
||||
node:
|
||||
customNodeKey: 80c30ac6ba927c6e5c0c9681aa9674f1d181d180853bcd3485cee9d18e931238
|
||||
|
||||
# Override settings for validator
|
||||
dh-validator:
|
||||
node:
|
||||
customNodeKey:
|
||||
# To generate new key run: docker run --rm -t moonsonglabs/datahaven:latest key generate-node-key
|
||||
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
|
||||
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
|
||||
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
|
||||
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
|
||||
|
||||
# Common relay settings
|
||||
relay:
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "100m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "200m"
|
||||
52
deploy/environments/stagenet/values.yaml
Normal file
52
deploy/environments/stagenet/values.yaml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Global settings
|
||||
global:
|
||||
environment: stagenet
|
||||
namespace: kt-datahaven-stagenet
|
||||
|
||||
# Common image settings
|
||||
image:
|
||||
repository: moonsonglabs/datahaven
|
||||
tag: stagenet
|
||||
pullPolicy: Always
|
||||
|
||||
imagePullSecrets:
|
||||
- name: datahaven-dockerhub
|
||||
|
||||
# Common node settings
|
||||
node:
|
||||
chain: stagenet-local
|
||||
chainData:
|
||||
persistence:
|
||||
size: 20Gi
|
||||
resources:
|
||||
requests:
|
||||
memory: "512Mi"
|
||||
cpu: "200m"
|
||||
limits:
|
||||
memory: "1Gi"
|
||||
cpu: "500m"
|
||||
|
||||
# Override settings for bootnode
|
||||
dh-bootnode:
|
||||
node:
|
||||
customNodeKey: 80c30ac6ba927c6e5c0c9681aa9674f1d181d180853bcd3485cee9d18e931238
|
||||
|
||||
# Override settings for validator
|
||||
dh-validator:
|
||||
node:
|
||||
customNodeKey:
|
||||
# To generate new key run: docker run --rm -t moonsonglabs/datahaven:latest key generate-node-key
|
||||
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
|
||||
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
|
||||
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
|
||||
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
|
||||
|
||||
# Common relay settings
|
||||
relay:
|
||||
resources:
|
||||
requests:
|
||||
memory: "512Mi"
|
||||
cpu: "200m"
|
||||
limits:
|
||||
memory: "1Gi"
|
||||
cpu: "500m"
|
||||
136
deploy/scripts/deploy.sh
Executable file
136
deploy/scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# Default values
|
||||
ENVIRONMENT=${1:-local}
|
||||
DRY_RUN=${2:-false}
|
||||
NAMESPACE="kt-datahaven-${ENVIRONMENT}"
|
||||
VALUES_FILE="$(dirname "$0")/../environments/${ENVIRONMENT}/values.yaml"
|
||||
NODE_CHART="$(dirname "$0")/../charts/node"
|
||||
RELAY_CHART="$(dirname "$0")/../charts/relay"
|
||||
|
||||
# Validate environment
|
||||
if [[ ! -f "${VALUES_FILE}" ]]; then
|
||||
echo "Error: Invalid environment '${ENVIRONMENT}'"
|
||||
echo "Available environments:"
|
||||
echo "- local (local development)"
|
||||
echo "- stagenet (staging environment)"
|
||||
echo "- testnet (testing environment)"
|
||||
echo "- mainnet (production environment)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate namespace exists
|
||||
if ! kubectl get namespace "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "Creating namespace ${NAMESPACE}"
|
||||
kubectl create namespace "${NAMESPACE}"
|
||||
fi
|
||||
|
||||
# Update dependencies
|
||||
echo "Updating Helm dependencies..."
|
||||
helm dependency update "${NODE_CHART}"
|
||||
helm dependency update "${RELAY_CHART}"
|
||||
|
||||
# Deploy DataHaven nodes
|
||||
echo "Deploying DataHaven nodes..."
|
||||
|
||||
# Deploy bootnode
|
||||
echo "Deploying DataHaven bootnode..."
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "=== Bootnode Configuration Preview ==="
|
||||
helm template dh-bootnode "${NODE_CHART}" \
|
||||
-f "${NODE_CHART}/datahaven/dh-bootnode.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--debug
|
||||
echo "=== End Bootnode Configuration Preview ==="
|
||||
else
|
||||
helm upgrade --install dh-bootnode "${NODE_CHART}" \
|
||||
-f "${NODE_CHART}/datahaven/dh-bootnode.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--wait
|
||||
fi
|
||||
|
||||
# Deploy validator
|
||||
echo "Deploying DataHaven validator..."
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "=== Validator Configuration Preview ==="
|
||||
helm template dh-validator "${NODE_CHART}" \
|
||||
-f "${NODE_CHART}/datahaven/dh-validator.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--debug
|
||||
echo "=== End Validator Configuration Preview ==="
|
||||
else
|
||||
helm upgrade --install dh-validator "${NODE_CHART}" \
|
||||
-f "${NODE_CHART}/datahaven/dh-validator.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--wait
|
||||
fi
|
||||
|
||||
# Deploy Snowbridge relays
|
||||
echo "Deploying Snowbridge relays..."
|
||||
|
||||
# Deploy Beacon relay
|
||||
echo "Deploying Snowbridge Beacon relay..."
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "=== Snowbridge Beacon Relay Configuration Preview ==="
|
||||
helm template snowbridge-beacon-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-beacon-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--debug
|
||||
echo "=== End Snowbridge Beacon Relay Configuration Preview ==="
|
||||
else
|
||||
helm upgrade --install snowbridge-beacon-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-beacon-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--wait
|
||||
fi
|
||||
|
||||
# Deploy BEEFY relay
|
||||
echo "Deploying Snowbridge BEEFY relay..."
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "=== Snowbridge BEEFY Relay Configuration Preview ==="
|
||||
helm template snowbridge-beefy-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-beefy-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--debug
|
||||
echo "=== End Snowbridge BEEFY Relay Configuration Preview ==="
|
||||
else
|
||||
helm upgrade --install snowbridge-beefy-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-beefy-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--wait
|
||||
fi
|
||||
|
||||
# Deploy Execution relay
|
||||
echo "Deploying Snowbridge Execution relay..."
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "=== Snowbridge Execution Relay Configuration Preview ==="
|
||||
helm template snowbridge-execution-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-execution-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--debug
|
||||
echo "=== End Snowbridge Execution Relay Configuration Preview ==="
|
||||
else
|
||||
helm upgrade --install snowbridge-execution-relay "${RELAY_CHART}" \
|
||||
-f "${RELAY_CHART}/snowbridge/dh-execution-relay.yaml" \
|
||||
-f "${VALUES_FILE}" \
|
||||
-n "${NAMESPACE}" \
|
||||
--wait
|
||||
fi
|
||||
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "Dry run completed. No changes were made."
|
||||
else
|
||||
echo "Deployment completed successfully!"
|
||||
fi
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
# DataHaven Helm charts
|
||||
|
||||
## DataHaven Bootnode & Validators
|
||||
|
||||
### Deploy
|
||||
|
||||
```sh
|
||||
cd deployment/charts/node
|
||||
helm upgrade --install dh-bootnode . -f ./datahaven/dh-bootnode.yaml -n kt-datahaven-stagenet
|
||||
helm upgrade --install dh-validator . -f ./datahaven/dh-validator.yaml -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
### Access validator node with Polkadot.js apps
|
||||
|
||||
```sh
|
||||
kubectl port-forward svc/dh-validator-0 -n kt-datahaven-stagenet 9955:9955
|
||||
https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9955#/explorer
|
||||
```
|
||||
|
||||
### Remove
|
||||
|
||||
```sh
|
||||
helm uninstall dh-bootnode -n kt-datahaven-stagenet
|
||||
helm uninstall dh-validator -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
### Cleanup volumes
|
||||
|
||||
```sh
|
||||
kubectl delete pvc -l app.kubernetes.io/instance=dh-bootnode -n kt-datahaven-stagenet
|
||||
kubectl delete pvc -l app.kubernetes.io/instance=dh-validator -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
## Snowbridge Relayers
|
||||
|
||||
### Create secrets
|
||||
|
||||
```sh
|
||||
kubectl create secret generic dh-beefy-relay-ethereum-key --from-literal=pvk="<PRIVATE_KEY>" -n kt-datahaven-stagenet
|
||||
kubectl create secret generic dh-beacon-relay-substrate-key --from-literal=pvk="<PRIVATE_KEY>" -n kt-datahaven-stagenet
|
||||
kubectl create secret generic dh-execution-relay-substrate-key --from-literal=pvk="<PRIVATE_KEY>" -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
### Deploy
|
||||
|
||||
```sh
|
||||
helm upgrade --install dh-beacon-relay . -f ./snowbridge/dh-beacon-relay.yaml -n kt-datahaven-stagenet
|
||||
helm upgrade --install dh-beefy-relay . -f ./snowbridge/dh-beefy-relay.yaml -n kt-datahaven-stagenet
|
||||
helm upgrade --install dh-execution-relay . -f ./snowbridge/dh-execution-relay.yaml -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
## Remove
|
||||
|
||||
```sh
|
||||
helm uninstall dh-beacon-relay -n kt-datahaven-stagenet
|
||||
helm uninstall dh-beefy-relay -n kt-datahaven-stagenet
|
||||
helm uninstall dh-execution-relay -n kt-datahaven-stagenet
|
||||
```
|
||||
|
||||
### Delete secrets
|
||||
|
||||
```sh
|
||||
kubectl delete secret <secret_name> -n kt-datahaven-stagenet
|
||||
```
|
||||
|
|
@ -56,6 +56,7 @@ export const deploymentChecks = async (
|
|||
logger.success("Helm is installed");
|
||||
|
||||
switch (options.environment) {
|
||||
case "local":
|
||||
case "stagenet":
|
||||
launchedNetwork.kubeNamespace = `kt-${options.kurtosisEnclaveName}`;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export const cleanup = async (
|
|||
return;
|
||||
}
|
||||
|
||||
if (options.environment === "stagenet") {
|
||||
if (options.isPrivateNetwork) {
|
||||
await checkAndCleanKurtosisDeployment(options);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,13 @@ export const deployDataHavenSolochain = async (
|
|||
logger.info("🚀 Deploying DataHaven bootnode with helm chart...");
|
||||
const bootnodeTimeout = "5m"; // 5 minutes
|
||||
logger.debug(
|
||||
await $`helm upgrade --install dh-bootnode . -f ./datahaven/dh-bootnode.yaml \
|
||||
await $`helm upgrade --install dh-bootnode charts/node \
|
||||
-f charts/node/datahaven/dh-bootnode.yaml \
|
||||
-f environments/${options.environment}/values.yaml \
|
||||
-n ${launchedNetwork.kubeNamespace} \
|
||||
--wait \
|
||||
--timeout ${bootnodeTimeout}`
|
||||
.cwd(path.join(process.cwd(), "../deployment/charts/node"))
|
||||
.cwd(path.join(process.cwd(), "../deploy"))
|
||||
.text()
|
||||
);
|
||||
logger.success("DataHaven bootnode deployed successfully");
|
||||
|
|
@ -76,11 +78,13 @@ export const deployDataHavenSolochain = async (
|
|||
logger.info("🚀 Deploying DataHaven validators with helm chart...");
|
||||
const validatorTimeout = "5m"; // 5 minutes
|
||||
logger.debug(
|
||||
await $`helm upgrade --install dh-validator . -f ./datahaven/dh-validator.yaml \
|
||||
await $`helm upgrade --install dh-validator charts/node \
|
||||
-f charts/node/datahaven/dh-validator.yaml \
|
||||
-f environments/${options.environment}/values.yaml \
|
||||
-n ${launchedNetwork.kubeNamespace} \
|
||||
--wait \
|
||||
--timeout ${validatorTimeout}`
|
||||
.cwd(path.join(process.cwd(), "../deployment/charts/node"))
|
||||
.cwd(path.join(process.cwd(), "../deploy"))
|
||||
.text()
|
||||
);
|
||||
logger.success("DataHaven validators deployed successfully");
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { performValidatorOperations } from "./validator";
|
|||
// Non-optional properties determined by having default values
|
||||
export interface DeployOptions {
|
||||
environment: DeployEnvironment;
|
||||
isPrivateNetwork?: boolean;
|
||||
kubeNamespace?: string;
|
||||
kurtosisEnclaveName: string;
|
||||
slotTime: number;
|
||||
|
|
@ -101,13 +102,15 @@ export const deployPreActionHook = (
|
|||
thisCmd.error("--verified requires --blockscout to be set");
|
||||
}
|
||||
|
||||
if (opts.environment === "stagenet" && opts.kubeNamespace !== undefined) {
|
||||
opts.isPrivateNetwork = opts.environment === "local" || opts.environment === "stagenet";
|
||||
|
||||
if (opts.isPrivateNetwork && opts.kubeNamespace !== undefined) {
|
||||
logger.warn(
|
||||
"⚠️ --kube-namespace is not allowed in stagenet environment. The Kurtosis namespace will be used instead."
|
||||
"⚠️ --kube-namespace is not allowed in private networks (local and stagenet). The Kurtosis namespace will be used instead."
|
||||
);
|
||||
}
|
||||
|
||||
if (opts.environment !== "stagenet" && opts.elRpcUrl === undefined) {
|
||||
thisCmd.error("--eth-rpc-url is required in non-stagenet environment");
|
||||
if (!opts.isPrivateNetwork && opts.elRpcUrl === undefined) {
|
||||
thisCmd.error("--eth-rpc-url is required in public networks (testnet and mainnet)");
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ export const deployKurtosis = async (
|
|||
printHeader("Deploying Kurtosis Ethereum Network");
|
||||
|
||||
invariant(
|
||||
options.environment === "stagenet",
|
||||
"❌ Kurtosis should only be used in stagenet environment"
|
||||
options.isPrivateNetwork,
|
||||
"❌ Kurtosis should only be used in private networks (local and stagenet)"
|
||||
);
|
||||
|
||||
await runKurtosisEnclave(options, "configs/kurtosis/minimal.yaml");
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import type { DeployOptions } from ".";
|
|||
const ETH_EL_RPC_PORT = 8546;
|
||||
const ETH_CL_HTTP_PORT = 4000;
|
||||
|
||||
const RELAYER_CONFIG_DIR = "../deployment/charts/bridges-common-relay/configs";
|
||||
const RELAYER_CONFIG_DIR = "../deploy/charts/relay/configs";
|
||||
const RELAYER_CONFIG_PATHS = {
|
||||
BEACON: path.join(RELAYER_CONFIG_DIR, "beacon-relay.json"),
|
||||
BEEFY: path.join(RELAYER_CONFIG_DIR, "beefy-relay.json"),
|
||||
|
|
@ -222,11 +222,13 @@ export const deployRelayers = async (options: DeployOptions, launchedNetwork: La
|
|||
// Deploying relayer with helm chart
|
||||
const relayerTimeout = "2m"; // 2 minutes
|
||||
logger.debug(
|
||||
await $`helm upgrade --install ${containerName} . -f ./snowbridge/${containerName}.yaml \
|
||||
await $`helm upgrade --install ${containerName} charts/relay \
|
||||
-f charts/relay/snowbridge/${containerName}.yaml \
|
||||
-f environments/${options.environment}/values.yaml \
|
||||
-n ${launchedNetwork.kubeNamespace} \
|
||||
--wait \
|
||||
--timeout ${relayerTimeout}`
|
||||
.cwd(path.join(process.cwd(), "../deployment/charts/bridges-common-relay"))
|
||||
.cwd(path.join(process.cwd(), "../deploy"))
|
||||
.text()
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const performValidatorOperations = async (options: DeployOptions, network
|
|||
}
|
||||
|
||||
// If not specified, prompt for funding
|
||||
const shouldFundValidators = options.environment === "stagenet";
|
||||
const shouldFundValidators = options.isPrivateNetwork;
|
||||
|
||||
if (shouldFundValidators) {
|
||||
await fundValidators({
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ function parseIntValue(value: string): number {
|
|||
|
||||
// Function to parse and validate DeployEnvironment
|
||||
function parseDeployEnvironment(value: string): DeployEnvironment {
|
||||
if (value === "stagenet" || value === "testnet" || value === "mainnet") {
|
||||
if (value === "local" || value === "stagenet" || value === "testnet" || value === "mainnet") {
|
||||
return value;
|
||||
}
|
||||
throw new InvalidArgumentError(
|
||||
"Invalid environment. Must be one of 'stagenet', 'testnet', or 'mainnet'."
|
||||
"Invalid environment. Must be one of 'local', 'stagenet', 'testnet', or 'mainnet'."
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -50,12 +50,7 @@ program
|
|||
`
|
||||
)
|
||||
.description("Deploy a full DataHaven network stack to a Kubernetes cluster")
|
||||
.option(
|
||||
"--e, --environment <value>",
|
||||
"Environment to deploy to",
|
||||
parseDeployEnvironment,
|
||||
"stagenet"
|
||||
)
|
||||
.option("--e, --environment <value>", "Environment to deploy to", parseDeployEnvironment, "local")
|
||||
.option(
|
||||
"--k, --kube-namespace <value>",
|
||||
"Kubernetes namespace to deploy to. In 'stagenet' this parameter is ignored and the Kurtosis namespace is used instead. Default will be `datahaven-<environment>`."
|
||||
|
|
@ -63,7 +58,7 @@ program
|
|||
.option(
|
||||
"--ke, --kurtosis-enclave-name <value>",
|
||||
"Name of the Kurtosis enclave",
|
||||
"datahaven-stagenet"
|
||||
"datahaven-local"
|
||||
)
|
||||
.option("--st, --slot-time <number>", "Set slot time in seconds", parseIntValue, 12)
|
||||
.option("--kn, --kurtosis-network-args <value>", "CustomKurtosis network args")
|
||||
|
|
@ -76,11 +71,11 @@ program
|
|||
)
|
||||
.option(
|
||||
"--el-rpc-url <value>",
|
||||
"URL of the Ethereum Execution Layer (EL) RPC endpoint to use. In stagenet environment, the Kurtosis Ethereum network will be used. In testnet and mainnet environment, this parameter is required."
|
||||
"URL of the Ethereum Execution Layer (EL) RPC endpoint to use. In local & stagenet environments (private networks), the Kurtosis Ethereum network will be used. In testnet and mainnet environments (public networks), this parameter is required."
|
||||
)
|
||||
.option(
|
||||
"--cl-endpoint <value>",
|
||||
"URL of the Ethereum Consensus Layer (CL) endpoint to use. In stagenet environment, the Kurtosis Ethereum network will be used. In testnet and mainnet environment, this parameter is required."
|
||||
"URL of the Ethereum Consensus Layer (CL) endpoint to use. In local & stagenet environments (private networks), the Kurtosis Ethereum network will be used. In testnet and mainnet environments (public networks), this parameter is required."
|
||||
)
|
||||
.option(
|
||||
"--rit, --relayer-image-tag <value>",
|
||||
|
|
|
|||
|
|
@ -160,6 +160,12 @@ should-send-metrics: true
|
|||
kurtosis-clusters:
|
||||
docker:
|
||||
type: "docker"
|
||||
docker.k8s:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "docker-desktop"
|
||||
storage-class: "hostpath"
|
||||
enclave-size-in-megabytes: 10
|
||||
minikube:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
|
|
@ -175,7 +181,57 @@ kurtosis-clusters:
|
|||
EOF
|
||||
```
|
||||
|
||||
This will add three kurtosis clusters. You won't need all of them at once, but is good to have them configured. First one is docker, second is for minikube (useful for some), and the third one is the one we'll use for the deployment to kubernetes. Alternatively, you can check your current Kurtosis config file:
|
||||
This will add four kurtosis clusters. You won't need all of them at once, but is good to have them configured.
|
||||
|
||||
1. **Docker containers**
|
||||
|
||||
This is usually only for running kurtosis directly to docker containers, it doesn't need a specific config, and it's equivalent to what we use in the `bun cli launch` command.
|
||||
|
||||
```yaml
|
||||
docker:
|
||||
type: "docker"
|
||||
```
|
||||
|
||||
2. **Docker Kubernetes**
|
||||
|
||||
For macOS users or everyone that can run Docker Desktop, you can check this docs to enable Kubernetes natively on your Docker Desktop app: https://docs.docker.com/desktop/features/kubernetes/
|
||||
|
||||
```yaml
|
||||
docker.k8s:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "docker-desktop"
|
||||
storage-class: "hostpath"
|
||||
enclave-size-in-megabytes: 10
|
||||
```
|
||||
|
||||
2. **Minikube**
|
||||
|
||||
Great tool for running local Kubernetes clusters, you can check installation instructions here: https://minikube.sigs.k8s.io/docs/start/
|
||||
|
||||
```yaml
|
||||
minikube:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "minikube"
|
||||
storage-class: "standard"
|
||||
enclave-size-in-megabytes: 10
|
||||
```
|
||||
|
||||
4. **Kubernetes**
|
||||
|
||||
This is gonna be for a production deployment.
|
||||
|
||||
```yaml
|
||||
cloud:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "vira-dh-poc-cluster"
|
||||
storage-class: "gp2"
|
||||
enclave-size-in-megabytes: 10
|
||||
```
|
||||
|
||||
If yout don't want all of them, you can always check your Kurtosis config file and add the desired clusters under `kurtosis-clusters:`
|
||||
|
||||
```bash
|
||||
kurtosis config path
|
||||
|
|
@ -187,23 +243,21 @@ And manually paste the contents:
|
|||
config-version: 2
|
||||
should-send-metrics: true
|
||||
kurtosis-clusters:
|
||||
docker:
|
||||
type: "docker"
|
||||
minikube:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "minikube"
|
||||
storage-class: "standard"
|
||||
enclave-size-in-megabytes: 10
|
||||
cloud:
|
||||
type: "kubernetes"
|
||||
config:
|
||||
kubernetes-cluster-name: "vira-dh-poc-cluster"
|
||||
storage-class: "gp2"
|
||||
enclave-size-in-megabytes: 10
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 4. For local deploymeny
|
||||
Assuming well use Docker Kubernetes cluster:
|
||||
|
||||
```bash
|
||||
# Set your Docker kubernetes
|
||||
kurtosis cluster set docker.k8s
|
||||
|
||||
# In a separete terminal, run and keep the gateway running (we still need this to communicate from local machine to the local kubernetes cluster)
|
||||
kurtosis gateway
|
||||
```
|
||||
|
||||
#### 5. For production deploymeny
|
||||
```bash
|
||||
# Set your cloud cluster as the target
|
||||
kurtosis cluster set cloud
|
||||
|
|
@ -212,8 +266,8 @@ kurtosis cluster set cloud
|
|||
kurtosis gateway
|
||||
```
|
||||
|
||||
|
||||
#### 4. (Optional) Test a simple deployment
|
||||
#### 5. Test a simple deployment (recommended)
|
||||
Before going any further, it's highly recommended that you test your config by creating a simple test network and runing it. Below, the steps:
|
||||
|
||||
```bash
|
||||
# Creates a test-network.yml file
|
||||
|
|
@ -223,9 +277,16 @@ echo -e "participants:\n - el_type: geth\n cl_type: prysm\n vc_type: prys
|
|||
kurtosis run --enclave local-eth-testnet github.com/ethpandaops/ethereum-package --args-file test-network.yml
|
||||
```
|
||||
|
||||
You can also go for testing against the provided hello-world by Kurtosis.
|
||||
|
||||
```bash
|
||||
~ kurtosis run --enclave test-k8s github.com/kurtosis-tech/awesome-kurtosis/hello-world
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### Access to GitHub
|
||||
|
||||
> ⚠️ **WARNING**
|
||||
> This is a permissioned step. You need to get credentials for DockerHub.
|
||||
>
|
||||
|
|
@ -242,6 +303,8 @@ docker login -u <username>
|
|||
docker manifest inspect moonsonglabs/datahaven:main
|
||||
```
|
||||
|
||||
### Remote deployment
|
||||
|
||||
#### 3. Run the deploy command with the credentials
|
||||
|
||||
```bash
|
||||
|
|
@ -252,6 +315,12 @@ If everything went well, you will see something like:
|
|||
|
||||
> [17:24:01.058] INFO (59757): ✅ Deploy function completed successfully in 28.4 minutes
|
||||
|
||||
### Local deployment
|
||||
|
||||
```bash
|
||||
bun cli deploy --docker-username=<username> --docker-password=<pass> --docker-email=<email> --e local
|
||||
```
|
||||
|
||||
## Access Kubernetes dashboard: k9s
|
||||
|
||||
```bash
|
||||
|
|
@ -262,6 +331,66 @@ k9s -n kt-datahaven-stagenet
|
|||
|
||||
You can also check https://k9scli.io/topics/commands/ for a list of available commands and bindings.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Using the right context
|
||||
|
||||
Ensure your Kubernetes context (shown by 'kubectl config current-context') matches the cluster Kurtosis is set to use (shown by 'kurtosis cluster get').
|
||||
For Docker Desktop, use 'docker-desktop' context and 'docker.k8s' cluster. For Minikube, use 'minikube' context and 'minikube' cluster.
|
||||
|
||||
```bash
|
||||
# List available contexts
|
||||
kubectl config get-contexts
|
||||
|
||||
# If you want to use Docker Desktop's Kubernetes, switch context:
|
||||
kubectl config use-context docker-desktop
|
||||
|
||||
# If you want to use Minikube, switch context:
|
||||
kubectl config use-context minikube
|
||||
|
||||
# Verify your current context:
|
||||
kubectl config current-context
|
||||
|
||||
# Make sure your Kurtosis cluster matches your Kubernetes context:
|
||||
kurtosis cluster get
|
||||
|
||||
```
|
||||
|
||||
### RBAC Permission Issues (Kubernetes clusters only)
|
||||
|
||||
You shouldn't, but If you get an error like "Failed to create cluster role with name 'kurtosis-logs-collector-*'" or "is attempting to grant RBAC permissions not currently held", you can use this to fix the RBAC permissions:
|
||||
|
||||
```bash
|
||||
# Get the service account name from the error message and create a cluster role binding
|
||||
kubectl create clusterrolebinding kurtosis-logs-collector --clusterrole=cluster-admin --serviceaccount=<namespace>:<serviceaccount>
|
||||
|
||||
# Example (replace with the actual service account from your error):
|
||||
kubectl create clusterrolebinding kurtosis-logs-collector --clusterrole=cluster-admin --serviceaccount=kurtosis-engine-43c7ccedab104a1f86fa8839637141e2:kurtosis-engine-43c7ccedab104a1f86fa8839637141e2
|
||||
```
|
||||
|
||||
**Note:** This gives the Kurtosis engine cluster-admin privileges, which is acceptable for local development but should be avoided in production environments.
|
||||
|
||||
|
||||
### Make sure storage-class matches your config
|
||||
|
||||
If say you're using a kurtosis cluster that has a storage-class different from `"hostpath"`when you run locally (i.e. `"standard"`, for minikube), then you might get some errors when trying to execute the helm charts.
|
||||
|
||||
Look for this chunk in `deploy/environments/local/values.yaml`:
|
||||
|
||||
```yaml
|
||||
# Common node settings
|
||||
node:
|
||||
chain: local
|
||||
chainData:
|
||||
storageClass: "hostpath"
|
||||
persistence:
|
||||
size: 10Gi
|
||||
...
|
||||
```
|
||||
|
||||
And try changing storageClass to whatever you have configured in the cluster. Good luck!
|
||||
|
||||
## Help commands (for reference only)
|
||||
|
||||
> ⚠️ **WARNING**
|
||||
|
|
|
|||
|
|
@ -237,4 +237,4 @@ export function parseRelayConfig(
|
|||
}
|
||||
}
|
||||
|
||||
export type DeployEnvironment = "stagenet" | "testnet" | "mainnet";
|
||||
export type DeployEnvironment = "local" | "stagenet" | "testnet" | "mainnet";
|
||||
|
|
|
|||
Loading…
Reference in a new issue