Skip to content

Commit 1f0cd6d

Browse files
stiiifffclaude
andauthored
feat: ✨ Enhanced Helm deployment with ingress management and solochain support (#115)
This PR enhances the Helm-based deployment system with several key improvements organized into the following areas: ## New Features ### Ingress Management - **Ingress per replica**: Added `ingress-per-replica` chart template that automatically generates an ingress for each node replica, exposing individual pod instances - **Traefik integration**: Added chart values to deploy Traefik as the ingress controller for local K8s clusters, enabling proper ingress testing (requires adding names to `/etc/hosts`) ### Solochain Support - **New relay chart**: Added dedicated Helm chart for Solochain relay deployment - **CLI integration**: Updated DataHaven CLI to deploy both Execution and Solochain relayers ## Configuration Improvements ### Environment Structure - **Modular configs**: Refactored environmental configurations from single `values.yaml` files into separate component-specific overrides for better organization ### Node Configuration - **Base config updates**: Improved base configurations for bootnode and validator nodes - **Network protocol**: Reverted from litep2p back to libp2p to resolve node communication issues on Stagenet - **Archive node routing**: In Stagenet, relayers now connect to the bootnode (configured as archive node) instead of validator nodes ## Storage & Deployment ### Persistent Storage - **Relayer database**: Added support for persistent volumes to store relayer databases instead of using ephemeral storage ### Deployment Scripts - **Documentation cleanup**: Removed obsolete test deploy.sh script and updated the deployment README with clearer instructions These changes provide a more robust, scalable, and maintainable deployment system for DataHaven infrastructure. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for deploying new relayer types: Solochain and Execution relayers, with dedicated configuration and secret management. * Introduced per-replica ingress configuration for node deployments, allowing each replica to have its own ingress resource and hostname. * Added persistent storage options for relay data, configurable via storage path, class, and size. * Added new deployment configuration files for local and stagenet environments, including Traefik ingress controller setup. * Introduced a new relay category, "Solochain Relayers," for standalone chain operations and cross-chain communication. * **Improvements** * Updated deployment configurations to use container-specific environment YAML files for more granular control. * Enhanced relay and node configurations with new flags and backend options, including dynamic peer ID generation and automatic bootnode discovery. * Updated relayer endpoints to consistently use the bootnode for connections. * Refined relay configuration files for improved structure, clarity, and endpoint management. * **Bug Fixes** * Corrected deployment logic to reference the correct environment-specific configuration files during Helm deployments. * **Documentation** * Simplified and updated deployment documentation to focus on CLI-based deployment, removing outdated manual instructions and adding a concise overview of components and relayer types. * **Chores** * Removed deprecated deployment scripts and outdated configuration files to streamline the deployment process. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <[email protected]>
1 parent cf55991 commit 1f0cd6d

34 files changed

Lines changed: 639 additions & 490 deletions

deploy/README.md

Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ deploy/
3232

3333
## Deployment
3434

35-
To deploy to a specific environment:
35+
The recommended way to deploy is using the DataHaven CLI with the deploy command:
3636

3737
```bash
38-
./scripts/deploy.sh <environment>
38+
cd test && bun cli deploy --e <environment>
3939
```
4040

4141
Example:
4242
```bash
43-
./scripts/deploy.sh local
43+
cd test && bun cli deploy --e local
4444
```
4545

4646
Available environments:
@@ -92,99 +92,4 @@ The deployment process:
9292
- **Beacon Relay**: Relays Ethereum beacon chain data
9393
- **BEEFY Relay**: Relays BEEFY consensus data for finality
9494
- **Execution Relay**: Relays Ethereum execution layer data
95-
96-
## Development
97-
98-
For local development:
99-
1. Ensure you have a local Kubernetes cluster (e.g., Minikube, Kind)
100-
2. Deploy using the local environment:
101-
```bash
102-
./scripts/deploy.sh local
103-
```
104-
105-
## Troubleshooting
106-
107-
Common issues and solutions:
108-
109-
1. Namespace doesn't exist:
110-
```bash
111-
kubectl create namespace kt-datahaven-<env>
112-
```
113-
114-
2. Helm dependencies need updating:
115-
```bash
116-
helm dependency update charts/node
117-
helm dependency update charts/relay
118-
```
119-
120-
3. View deployment status:
121-
```bash
122-
kubectl get all -n kt-datahaven-<env>
123-
```
124-
125-
4. Preview deployment changes:
126-
```bash
127-
./scripts/deploy.sh <env> true
128-
```
129-
130-
## Manual Deployment (Advanced)
131-
132-
For advanced users who want to deploy components individually or need more control:
133-
134-
### DataHaven Bootnode & Validators
135-
136-
#### Deploy individual components
137-
```bash
138-
cd deploy
139-
helm upgrade --install dh-bootnode charts/node -f charts/node/datahaven/dh-bootnode.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
140-
helm upgrade --install dh-validator charts/node -f charts/node/datahaven/dh-validator.yaml -f ../environments/<env>/values.yaml -n kt-datahaven-<env>
141-
```
142-
143-
#### Access validator node with Polkadot.js apps
144-
```bash
145-
kubectl port-forward svc/dh-validator-0 -n kt-datahaven-<env> 9955:9955
146-
# Then visit: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9955#/explorer
147-
```
148-
149-
#### Remove DataHaven components
150-
```bash
151-
helm uninstall dh-bootnode -n kt-datahaven-<env>
152-
helm uninstall dh-validator -n kt-datahaven-<env>
153-
```
154-
155-
#### Cleanup volumes
156-
```bash
157-
kubectl delete pvc -l app.kubernetes.io/instance=dh-bootnode -n kt-datahaven-<env>
158-
kubectl delete pvc -l app.kubernetes.io/instance=dh-validator -n kt-datahaven-<env>
159-
```
160-
161-
### Snowbridge Relayers
162-
163-
#### Create required secrets
164-
```bash
165-
kubectl create secret generic dh-beefy-relay-ethereum-key --from-literal=pvk="<ETHEREUM_PRIVATE_KEY>" -n kt-datahaven-<env>
166-
kubectl create secret generic dh-beacon-relay-substrate-key --from-literal=pvk="<SUBSTRATE_PRIVATE_KEY>" -n kt-datahaven-<env>
167-
kubectl create secret generic dh-execution-relay-substrate-key --from-literal=pvk="<SUBSTRATE_PRIVATE_KEY>" -n kt-datahaven-<env>
168-
```
169-
170-
#### Deploy individual relay components
171-
```bash
172-
cd deploy
173-
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>
174-
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>
175-
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>
176-
```
177-
178-
#### Remove relay components
179-
```bash
180-
helm uninstall dh-beacon-relay -n kt-datahaven-<env>
181-
helm uninstall dh-beefy-relay -n kt-datahaven-<env>
182-
helm uninstall dh-execution-relay -n kt-datahaven-<env>
183-
```
184-
185-
#### Delete relay secrets
186-
```bash
187-
kubectl delete secret dh-beefy-relay-ethereum-key -n kt-datahaven-<env>
188-
kubectl delete secret dh-beacon-relay-substrate-key -n kt-datahaven-<env>
189-
kubectl delete secret dh-execution-relay-substrate-key -n kt-datahaven-<env>
190-
```
95+
- **Solochain Relayers**: Handle standalone chain operations and cross-chain communication

deploy/charts/node/datahaven/dh-bootnode.yaml

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,27 @@ imagePullSecrets:
1212

1313
node:
1414
command: datahaven-node
15-
# customChainspec: true # see extraInitContainers, chainspec-generator
15+
customChainspec: true # see extraInitContainers, chainspec-generator
1616
role: full
1717
replicas: 1
1818
chainData:
19-
pruning: archive
19+
pruning: 1000
2020
storageClass: "gp2"
2121
chainKeystore:
2222
mountInMemory:
2323
enabled: true
24-
# perNodeServices:
25-
# relayP2pService:
26-
# enabled: true
27-
# to generate new key run: docker run moonsonglabs/datahaven key generate-node-key
28-
# 12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk
29-
customNodeKey: 80c30ac6ba927c6e5c0c9681aa9674f1d181d180853bcd3485cee9d18e931238
24+
persistGeneratedNodeKey: true
3025
flags:
3126
- "--allow-private-ipv4"
3227
- "--discover-local"
28+
- "--network-backend libp2p"
29+
30+
ingress:
31+
enabled: false
32+
perReplica: false
33+
wildcardDomain: datahaven.local
34+
# If enabled, this would generate:
35+
# - dh-bootnode-0.datahaven.local
3336

3437
# Generate chainspec, and expose it as url
3538
extraInitContainers:
@@ -43,15 +46,32 @@ extraInitContainers:
4346
- |
4447
apt update || true
4548
apt install -y jq
49+
50+
# Wait for node key to be generated by the persist-generated-node-key init container
51+
echo "Waiting for node key generation..."
52+
for i in {1..60}; do
53+
[ -f /keystore/node-key ] && break
54+
echo "Node key not found, waiting ($i/60)…"
55+
sleep 2
56+
done
57+
[ -f /keystore/node-key ] || { echo "Node key generation timed out"; exit 1; }
58+
59+
# Extract the peer ID from the generated node key
60+
NODE_PEER_ID="$({{ .Values.node.command }} key inspect-node-key --file /keystore/node-key)"
61+
echo "Using generated peer ID: ${NODE_PEER_ID}"
62+
63+
# Generate chainspec with dynamic peer ID
4664
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} > base.json
47-
echo '{"bootNodes":["/dns/dh-bootnode-0/tcp/30333/p2p/12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk"]}' > override1.json
65+
echo "{\"bootNodes\":[\"/dns/dh-bootnode-0/tcp/30333/p2p/${NODE_PEER_ID}\"]}" > override1.json
4866
jq -s '.[0] * .[1]' base.json override1.json | sed 's/1e+18/1000000000000000000/' > plain.json
4967
cut -c -256 plain.json
5068
{{ .Values.node.command }} build-spec --chain plain.json --raw > chainspec.json
5169
cp chainspec.json {{ .Values.node.customChainspecPath }}
5270
volumeMounts:
5371
- mountPath: /chain-data
5472
name: chain-data
73+
- mountPath: /keystore
74+
name: chain-keystore
5575
extraContainers:
5676
- name: chainspec
5777
image: nginxinc/nginx-unprivileged:stable

deploy/charts/node/datahaven/dh-validator.yaml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ imagePullSecrets:
1212

1313
node:
1414
command: datahaven-node
15-
# customChainspecUrl: http://dh-bootnode:8080/chainspec.json
16-
# forceDownloadChainspec: true
15+
customChainspecUrl: http://dh-bootnode:8080/chainspec.json
16+
forceDownloadChainspec: true
1717
role: authority
1818
replicas: 2
1919
chainData:
@@ -40,19 +40,19 @@ node:
4040
type: beef
4141
scheme: ecdsa
4242
extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")'
43-
customNodeKey:
44-
# To generate new key run: docker run --rm -t moonsonglabs/datahaven:latest key generate-node-key
45-
# 12D3KooWL5Av1ZZSKkaittmxXBmZpzP7zgiB1AAnWHEw7MxzqnFp
46-
- bdf71a910354e231095366230621eaefb5f99465045f1501478fd3d9b5deef98
47-
# 12D3KooWAxFonTS177T81CTDeH6mfvJQWYEJeVQ1gPrnULjNY8Cn
48-
- 2a775a9db9fb0ff40afacb4aa7ccbf2a5d04c6d980bb1437c196c8e38a6cd948
43+
persistGeneratedNodeKey: true
4944
flags:
50-
- "--bootnodes /dns/dh-bootnode-0/tcp/30333/p2p/12D3KooWRpzRTivvJ5ySvgbFnPeEE6rDhitQKL1fFJvvBGhnenSk"
45+
- "--network-backend libp2p"
46+
# Note: Bootnode discovery will happen automatically via the chainspec downloaded from customChainspecUrl
5147
enableOffchainIndexing: true
52-
perNodeServices:
53-
apiService:
54-
enabled: true
55-
type: NodePort
48+
49+
ingress:
50+
enabled: false
51+
perReplica: true
52+
wildcardDomain: datahaven.local
53+
# If enabled, this would generate:
54+
# - dh-validator-0.datahaven.local
55+
# - dh-validator-1.datahaven.local
5656

5757
extraInitContainers:
5858
- name: dump-state-and-wasm
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{{- if and .Values.ingress.enabled .Values.ingress.perReplica -}}
2+
{{- $fullName := include "node.fullname" . -}}
3+
{{- $replicas := .Values.node.replicas | int -}}
4+
{{- range $i := until $replicas }}
5+
---
6+
apiVersion: networking.k8s.io/v1
7+
kind: Ingress
8+
metadata:
9+
name: {{ $fullName }}-{{ $i }}
10+
labels:
11+
{{- $labels := include "node.labels" $ | fromYaml }}
12+
{{- range $key, $value := $labels }}
13+
{{- if eq $key "app.kubernetes.io/instance" }}
14+
{{ $key }}: {{ $value | replace $fullName (printf "%s-%d" $fullName $i) | quote }}
15+
{{- else }}
16+
{{ $key }}: {{ $value | quote }}
17+
{{- end }}
18+
{{- end }}
19+
replica: "{{ $i }}"
20+
{{- with $.Values.ingress.annotations }}
21+
annotations:
22+
{{- range $key, $value := . }}
23+
{{- if eq $key "meta.helm.sh/release-name" }}
24+
{{ $key }}: {{ $value | quote }}
25+
{{- else }}
26+
{{ $key }}: {{ $value | replace $fullName (printf "%s-%d" $fullName $i) | quote }}
27+
{{- end }}
28+
{{- end }}
29+
{{- end }}
30+
spec:
31+
{{- if $.Values.ingress.ingressClassName }}
32+
ingressClassName: {{ $.Values.ingress.ingressClassName | quote }}
33+
{{- end }}
34+
rules:
35+
- host: {{ printf "%s-%d.%s" $fullName $i $.Values.ingress.wildcardDomain | quote }}
36+
http:
37+
paths:
38+
- path: /
39+
pathType: Prefix
40+
backend:
41+
service:
42+
name: {{ $fullName }}-{{ $i }}
43+
port:
44+
number: {{ $.Values.node.perNodeServices.apiService.rpcPort }}
45+
{{- with $.Values.ingress.tls }}
46+
tls:
47+
{{- toYaml . | nindent 4 }}
48+
{{- end }}
49+
{{- end }}
50+
{{- end }}

deploy/charts/node/templates/ingress.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.ingress.enabled -}}
1+
{{- if and .Values.ingress.enabled (not .Values.ingress.perReplica) -}}
22
{{- $fullName := include "node.fullname" . -}}
33
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
44
apiVersion: networking.k8s.io/v1

deploy/charts/relay/configs/beacon-relay.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
}
1414
},
1515
"datastore": {
16-
"location": "/data",
16+
"location": "/relay-data",
1717
"maxEntries": 100
1818
}
1919
}
2020
},
2121
"sink": {
2222
"parachain": {
23-
"endpoint": "ws://dh-validator-0:9944",
23+
"endpoint": "ws://dh-bootnode-0:9944",
2424
"maxWatchedExtrinsics": 8,
2525
"headerRedundancy": 20
2626
},

deploy/charts/relay/configs/beefy-relay.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"source": {
33
"polkadot": {
4-
"endpoint": "ws://dh-validator-0:9944"
4+
"endpoint": "ws://dh-bootnode-0:9944"
55
}
66
},
77
"sink": {
Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,40 @@
11
{
2-
"source": {
3-
"ethereum": {
4-
"endpoint": "ws://el-1-reth-lodestar:8546"
5-
},
6-
"contracts": {
7-
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
2+
"source": {
3+
"ethereum": {
4+
"endpoint": "ws://el-1-reth-lodestar:8546"
5+
},
6+
"contracts": {
7+
"Gateway": "0x8f86403A4DE0BB5791fa46B8e795C547942fE4Cf"
8+
},
9+
"beacon": {
10+
"endpoint": "http://cl-1-lodestar-reth:4000",
11+
"stateEndpoint": "http://cl-1-lodestar-reth:4000",
12+
"spec": {
13+
"syncCommitteeSize": 512,
14+
"slotsInEpoch": 32,
15+
"epochsPerSyncCommitteePeriod": 256,
16+
"forkVersions": {
17+
"deneb": 0,
18+
"electra": 0
19+
}
20+
},
21+
"datastore": {
22+
"location": "/relay-data",
23+
"maxEntries": 100
24+
}
25+
}
826
},
9-
"channel-id": "",
10-
"beacon": {
11-
"endpoint": "http://cl-1-lodestar-reth:4000",
12-
"stateEndpoint": "http://cl-1-lodestar-reth:4000",
13-
"spec": {
14-
"syncCommitteeSize": 512,
15-
"slotsInEpoch": 32,
16-
"epochsPerSyncCommitteePeriod": 256,
17-
"forkVersions": {
18-
"deneb": 0,
19-
"electra": 0
27+
"sink": {
28+
"parachain": {
29+
"endpoint": "ws://dh-bootnode-0:9944",
30+
"maxWatchedExtrinsics": 8,
31+
"headerRedundancy": 20
2032
}
21-
},
22-
"datastore": {
23-
"location": "",
24-
"maxEntries": 100
25-
}
26-
}
27-
},
28-
"sink": {
29-
"parachain": {
30-
"endpoint": "ws://dh-validator-0:9944",
31-
"maxWatchedExtrinsics": 8,
32-
"headerRedundancy": 20
33+
},
34+
"instantVerification": false,
35+
"schedule": {
36+
"id": null,
37+
"totalRelayerCount": 1,
38+
"sleepInterval": 1
3339
}
34-
},
35-
"instantVerification": false,
36-
"schedule": {
37-
"id": null,
38-
"totalRelayerCount": 1,
39-
"sleepInterval": 1
40-
}
41-
}
40+
}

0 commit comments

Comments
 (0)