Skip to content

Commit

Permalink
[node] add tpl to init containers (#333)
Browse files Browse the repository at this point in the history
* add tpl to init containers

* add option to use own chainspec

* update README.md

* add examples/local-rococo
  • Loading branch information
BulatSaif authored Mar 25, 2024
1 parent 977fc91 commit 9fe1c9e
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 11 deletions.
2 changes: 1 addition & 1 deletion charts/node/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: node
description: A Helm chart to deploy Substrate/Polkadot nodes
type: application
version: 5.6.2
version: 5.6.3
maintainers:
- name: Parity
url: https://github.com/paritytech/helm-charts
Expand Down
10 changes: 7 additions & 3 deletions charts/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This is intended behaviour. Make sure to run `git add -A` once again to stage ch

# Substrate/Polkadot node Helm chart

![Version: 5.6.2](https://img.shields.io/badge/Version-5.6.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
![Version: 5.6.3](https://img.shields.io/badge/Version-5.6.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

## Maintainers

Expand Down Expand Up @@ -298,7 +298,7 @@ If you're running a collator node:
| jaegerAgent.ports.samplingPort | HTTP | `5778` | serve configs, sampling strategies |
| jaegerAgent.resources | object | `{}` | Resource limits & requests |
| nameOverride | string | `""` | Provide a name in place of node for `app:` labels |
| node | object | `{"allowUnsafeRpcMethods":false,"chain":"polkadot","chainData":{"annotations":{},"chainPath":null,"chainSnapshot":{"enabled":false,"filelistName":"files.txt","method":"gcs","url":""},"database":"rocksdb","kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"pruning":1000,"storageClass":"","volumeSize":"100Gi"},"chainKeystore":{"accessModes":["ReadWriteOnce"],"annotations":{},"kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"mountInMemory":{"enabled":false,"sizeLimit":null},"storageClass":"","volumeSize":"10Mi"},"collatorExternalRelayChain":{"enabled":false,"relayChainRpcUrls":[]},"collatorLightClient":{"enabled":false,"relayChain":"","relayChainCustomChainspecPath":"/chain-data/relay_chain_chainspec.json","relayChainCustomChainspecUrl":null},"collatorRelayChain":{"chain":"polkadot","chainData":{"annotations":{},"chainPath":"","chainSnapshot":{"enabled":false,"filelistName":"files.txt","method":"gcs","url":""},"database":"rocksdb","kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"pruning":1000,"storageClass":"","volumeSize":"100Gi"},"chainKeystore":{"accessModes":["ReadWriteOnce"],"annotations":{},"kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"mountInMemory":{"enabled":false,"sizeLimit":null},"storageClass":"","volumeSize":"10Mi"},"customChainspecPath":"/relaychain-data/relay_chain_chainspec.json","customChainspecUrl":null,"flags":[],"prometheus":{"enabled":false,"port":9625}},"command":"polkadot","customChainspecPath":"/chain-data/chainspec.json","customChainspecUrl":null,"customNodeKey":null,"enableOffchainIndexing":false,"enableSidecarLivenessProbe":false,"enableSidecarReadinessProbe":false,"enableStartupProbe":true,"existingSecrets":{"keys":[],"nodeKey":{}},"extraConfigmapMounts":[],"extraEnvVars":[],"extraSecretMounts":[],"flags":[],"forceDownloadChainspec":false,"isParachain":false,"keys":{},"legacyRpcFlags":false,"logLevels":[],"perNodeServices":{"apiService":{"annotations":{},"enabled":true,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"httpPort":9933,"prometheusPort":9615,"relayChainPrometheusPort":9625,"rpcPort":9944,"type":"ClusterIP","wsPort":9955},"paraP2pService":{"annotations":{},"enabled":false,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"port":30334,"type":"NodePort","ws":{"enabled":false,"port":30335}},"relayP2pService":{"annotations":{},"enabled":false,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"port":30333,"type":"NodePort","ws":{"enabled":false,"port":30334}},"setPublicAddressToExternalIp":{"enabled":false,"ipRetrievalServiceUrl":"https://ifconfig.io"}},"persistGeneratedNodeKey":false,"persistentVolumeClaimRetentionPolicy":null,"podManagementPolicy":null,"prometheus":{"enabled":true,"port":9615},"replicas":1,"resources":{},"role":"full","serviceAnnotations":{},"serviceMonitor":{"enabled":false,"interval":"30s","metricRelabelings":[],"namespace":null,"relabelings":[],"scrapeTimeout":"10s","targetLabels":["node"]},"startupProbeFailureThreshold":30,"substrateApiSidecar":{"enabled":false},"telemetryUrls":[],"tracing":{"enabled":false},"updateStrategy":{"enabled":false,"maxUnavailable":1,"type":"RollingUpdate"},"vault":{"authConfigServiceAccount":null,"authConfigType":null,"authPath":null,"authRole":null,"authType":null,"keys":{},"nodeKey":{}},"wasmRuntimeOverridesPath":"/chain-data/runtimes","wasmRuntimeUrl":""}` | Deploy a substrate node. ref: https://docs.substrate.io/tutorials/v3/private-network/ |
| node | object | `{"allowUnsafeRpcMethods":false,"chain":"polkadot","chainData":{"annotations":{},"chainPath":null,"chainSnapshot":{"enabled":false,"filelistName":"files.txt","method":"gcs","url":""},"database":"rocksdb","kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"pruning":1000,"storageClass":"","volumeSize":"100Gi"},"chainKeystore":{"accessModes":["ReadWriteOnce"],"annotations":{},"kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"mountInMemory":{"enabled":false,"sizeLimit":null},"storageClass":"","volumeSize":"10Mi"},"collatorExternalRelayChain":{"enabled":false,"relayChainRpcUrls":[]},"collatorLightClient":{"enabled":false,"relayChain":"","relayChainCustomChainspec":false,"relayChainCustomChainspecPath":"/chain-data/relay_chain_chainspec.json","relayChainCustomChainspecUrl":null},"collatorRelayChain":{"chain":"polkadot","chainData":{"annotations":{},"chainPath":"","chainSnapshot":{"enabled":false,"filelistName":"files.txt","method":"gcs","url":""},"database":"rocksdb","kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"pruning":1000,"storageClass":"","volumeSize":"100Gi"},"chainKeystore":{"accessModes":["ReadWriteOnce"],"annotations":{},"kubernetesVolumeSnapshot":null,"kubernetesVolumeToClone":null,"mountInMemory":{"enabled":false,"sizeLimit":null},"storageClass":"","volumeSize":"10Mi"},"customChainspec":false,"customChainspecPath":"/relaychain-data/relay_chain_chainspec.json","customChainspecUrl":null,"flags":[],"prometheus":{"enabled":false,"port":9625}},"command":"polkadot","customChainspec":false,"customChainspecPath":"/chain-data/chainspec.json","customChainspecUrl":null,"customNodeKey":null,"enableOffchainIndexing":false,"enableSidecarLivenessProbe":false,"enableSidecarReadinessProbe":false,"enableStartupProbe":true,"existingSecrets":{"keys":[],"nodeKey":{}},"extraConfigmapMounts":[],"extraEnvVars":[],"extraSecretMounts":[],"flags":[],"forceDownloadChainspec":false,"isParachain":false,"keys":{},"legacyRpcFlags":false,"logLevels":[],"perNodeServices":{"apiService":{"annotations":{},"enabled":true,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"httpPort":9933,"prometheusPort":9615,"relayChainPrometheusPort":9625,"rpcPort":9944,"type":"ClusterIP","wsPort":9955},"paraP2pService":{"annotations":{},"enabled":false,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"port":30334,"type":"NodePort","ws":{"enabled":false,"port":30335}},"relayP2pService":{"annotations":{},"enabled":false,"externalDns":{"customPrefix":"","enabled":false,"hostname":"example.com","ttl":300},"externalTrafficPolicy":"Cluster","extraPorts":[],"port":30333,"type":"NodePort","ws":{"enabled":false,"port":30334}},"setPublicAddressToExternalIp":{"enabled":false,"ipRetrievalServiceUrl":"https://ifconfig.io"}},"persistGeneratedNodeKey":false,"persistentVolumeClaimRetentionPolicy":null,"podManagementPolicy":null,"prometheus":{"enabled":true,"port":9615},"replicas":1,"resources":{},"role":"full","serviceAnnotations":{},"serviceExtraPorts":[],"serviceMonitor":{"enabled":false,"interval":"30s","metricRelabelings":[],"namespace":null,"relabelings":[],"scrapeTimeout":"10s","targetLabels":["node"]},"startupProbeFailureThreshold":30,"substrateApiSidecar":{"enabled":false},"telemetryUrls":[],"tracing":{"enabled":false},"updateStrategy":{"enabled":false,"maxUnavailable":1,"type":"RollingUpdate"},"vault":{"authConfigServiceAccount":null,"authConfigType":null,"authPath":null,"authRole":null,"authType":null,"keys":{},"nodeKey":{}},"wasmRuntimeOverridesPath":"/chain-data/runtimes","wasmRuntimeUrl":""}` | Deploy a substrate node. ref: https://docs.substrate.io/tutorials/v3/private-network/ |
| node.allowUnsafeRpcMethods | bool | `false` | Allow executing unsafe RPC methods |
| node.chain | string | `"polkadot"` | Name of the chain |
| node.chainData.annotations | object | `{}` | Annotations to add to the volumeClaimTemplates |
Expand Down Expand Up @@ -327,9 +327,10 @@ If you're running a collator node:
| node.collatorExternalRelayChain | object | `{"enabled":false,"relayChainRpcUrls":[]}` | EXPERIMENTAL!!! Run the collator node without a relay chain via external relay chain ref: https://github.com/paritytech/cumulus#external-relay-chain-node Enabling this option will disable the values of collatorRelayChain |
| node.collatorExternalRelayChain.enabled | bool | `false` | Enable deployment of the external collator |
| node.collatorExternalRelayChain.relayChainRpcUrls | list | `[]` | List of Relay Chain RPCs to connect |
| node.collatorLightClient | object | `{"enabled":false,"relayChain":"","relayChainCustomChainspecPath":"/chain-data/relay_chain_chainspec.json","relayChainCustomChainspecUrl":null}` | EXPERIMENTAL!!! Run the collator node without a relay chain via light client ref: https://github.com/paritytech/cumulus/pull/2270 Enabling this option will disable the values of collatorRelayChain |
| node.collatorLightClient | object | `{"enabled":false,"relayChain":"","relayChainCustomChainspec":false,"relayChainCustomChainspecPath":"/chain-data/relay_chain_chainspec.json","relayChainCustomChainspecUrl":null}` | EXPERIMENTAL!!! Run the collator node without a relay chain via light client ref: https://github.com/paritytech/cumulus/pull/2270 Enabling this option will disable the values of collatorRelayChain |
| node.collatorLightClient.enabled | bool | `false` | Enable deployment of the external collator |
| node.collatorLightClient.relayChain | string | `""` | Name of the Relay Chain to connect |
| node.collatorLightClient.relayChainCustomChainspec | bool | `false` | Use the file defined in `collatorLightClient.relayChainCustomChainspecPath` as the chainspec. Ensure that the file is either mounted or generated with an init container. |
| node.collatorLightClient.relayChainCustomChainspecPath | string | `"/chain-data/relay_chain_chainspec.json"` | Path to the file containing the chainspec of the collator relay-chain |
| node.collatorLightClient.relayChainCustomChainspecUrl | string | `nil` | URL to retrive custom chain spec |
| node.collatorRelayChain.chain | string | `"polkadot"` | Name of the Relay Chain to connect |
Expand All @@ -355,13 +356,15 @@ If you're running a collator node:
| node.collatorRelayChain.chainKeystore.mountInMemory.sizeLimit | string | `nil` | Size limit of the emptyDir holding a keystore. Requires K8s >=1.22 |
| node.collatorRelayChain.chainKeystore.storageClass | string | `""` | Storage class to use for persistent volume |
| node.collatorRelayChain.chainKeystore.volumeSize | string | `"10Mi"` | Size of the volume |
| node.collatorRelayChain.customChainspec | bool | `false` | Use the file defined in `collatorRelayChain.customChainspecPath` as the chainspec. Ensure that the file is either mounted or generated with an init container. |
| node.collatorRelayChain.customChainspecPath | string | `"/relaychain-data/relay_chain_chainspec.json"` | Path to the file containing the chainspec of the collator relay-chain Set to /relaychain-data to use additional volume |
| node.collatorRelayChain.customChainspecUrl | string | `nil` | URL to retrive custom chain spec |
| node.collatorRelayChain.flags | list | `[]` | Flags to add to the Polkadot binary |
| node.collatorRelayChain.prometheus | object | `{"enabled":false,"port":9625}` | Expose relay chain metrics via Prometheus format in /metrics endpoint. Passes the following args to the Polkadot binary: - "--prometheus-external" \ - "--prometheus-port {{ port }}" |
| node.collatorRelayChain.prometheus.enabled | bool | `false` | Expose Prometheus metrics |
| node.collatorRelayChain.prometheus.port | int | `9625` | The port for exposed Prometheus metrics |
| node.command | string | `"polkadot"` | Command to run within the container |
| node.customChainspec | bool | `false` | Use the file defined in `node.customChainspecPath` as the chainspec. Ensure that the file is either mounted or generated with an init container. |
| node.customChainspecPath | string | `"/chain-data/chainspec.json"` | Node may require custom name for chainspec file. ref: moonbeam https://github.com/PureStake/moonbeam/issues/1104#issuecomment-996787548 Note: path should start with /chain-data/ since this folder mount in init container download-chainspec. |
| node.customChainspecUrl | string | `nil` | URL to retrive custom chain spec |
| node.customNodeKey | string | `nil` | Name of the secret containig the key |
Expand Down Expand Up @@ -436,6 +439,7 @@ If you're running a collator node:
| node.resources | object | `{}` | Resource limits & requests |
| node.role | string | `"full"` | Type of the node. One of: full, authority, validator, collator, light |
| node.serviceAnnotations | object | `{}` | Annotations to add to the Service |
| node.serviceExtraPorts | list | `[]` | Additional ports on main Service |
| node.serviceMonitor | object | `{"enabled":false,"interval":"30s","metricRelabelings":[],"namespace":null,"relabelings":[],"scrapeTimeout":"10s","targetLabels":["node"]}` | Service Monitor of Prometheus-Operator ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md#include-servicemonitors |
| node.serviceMonitor.enabled | bool | `false` | Enables Service Monitor |
| node.serviceMonitor.interval | string | `"30s"` | Scrape interval |
Expand Down
56 changes: 56 additions & 0 deletions charts/node/examples/local-rococo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Relaychain
## Install relaychain
```shell
helm upgrade --install bootnode . -f examples/local-rococo/bootnode.yaml
kubectl wait --for=condition=Ready pod bootnode-0 --timeout=90s
helm upgrade --install validators . -f examples/local-rococo/validators-alice-bob.yaml

```

## Access to relaychain RPC
```shell
kubectl port-forward bootnode-0 9944:9944
```
open: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer

# Parachain
## Install parachain
```shell
helm upgrade --install parachain . -f examples/local-rococo/asset-hub.yaml
```

## Onboard parachain
1. Find the para_id and Genesis state
```shell
kubectl logs --tail 10 -f parachain-node-0 dump-state-and-wasm
# Parachain Id:
# "para_id": 1000,
# Genesis head:
# 0x00000000000000000000000000000000000000000000000000000000000000000061dc4546910e4a874f59af705dd079344ecb7759f526cf86cf21db67473d0b4f03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400
```
2. Download genesis-wasm
```shell
kubectl cp parachain-node-0:/chain-data/genesis-wasm genesis-wasm
```
3. On relaychain RPC submit following call:
https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/sudo
```shell
parasSudoWrapper.sudoScheduleParaInitialize(id, genesis)
id = 1000
genesisHead = 0x00000000000000000000000000000000000000000000000000000000000000000061dc4546910e4a874f59af705dd079344ecb7759f526cf86cf21db67473d0b4f03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c11131400
validationCode = file upload(genesis-wasm)
paraKind = Yes
```
4. Check onboarding progress here: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/parachains/parathreads

## Access to parachain RPC
```shell
kubectl port-forward parachain-node-0 9945:9944
```
open: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9945#/explorer

## Cleanup
```shell
helm delete bootnode validators parachain
# clean pvc kubectl delete pvc --all
```
76 changes: 76 additions & 0 deletions charts/node/examples/local-rococo/asset-hub.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
image:
repository: parity/polkadot-parachain
tag: latest
pullPolicy: Always

node:
chain: asset-hub-rococo-local
command: polkadot-parachain
role: collator
replicas: 2
chainData:
pruning: 1000
storageClass: ""
chainKeystore:
storageClass: ""
keys:
# This is Alice seed
- seed: "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
type: aura
scheme: sr25519
# ${HOSTNAME##*-} will be evaluated as the pod index, pod-0: //Alice, pod-1: //Bob
extraDerivation: '$([ "${HOSTNAME##*-}" = "0" ] && echo "//Alice" || echo "//Bob")'
isParachain: true
collatorRelayChain:
chain: rococo-local
customChainspecUrl: http://bootnode:8080/chainspec.json
forceDownloadChainspec: true
chainData:
storageClass: ""
flags:
- "--allow-private-ipv4"
- "--discover-local"
ingress:
enabled: false
annotations:
kubernetes.io/ingress.class: TODO
external-dns.alpha.kubernetes.io/target: TODO
cert-manager.io/cluster-issuer: TODO
rules:
- host: parachain.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: parachain-node
port:
number: 9944
tls:
- secretName: parachain.example.com
hosts:
- parachain.example.com

extraInitContainers:
- name: dump-state-and-wasm
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
command: [ "/bin/bash" ]
args:
- -c
- |
if [ "${HOSTNAME##*-}" = "0" ]; then
echo "Parachain Id:"
{{ .Values.node.command }} build-spec --chain {{ .Values.node.chain }} | grep -E 'para_id|parachainId'
echo "Genesis head:"
{{ .Values.node.command }} export-genesis-state --chain {{ .Values.node.chain }}
echo ""
echo "Genesis wasm (validationCode) stored in /chain-data/genesis-wasm"
{{ .Values.node.command }} export-genesis-wasm --chain {{ .Values.node.chain }} > /chain-data/genesis-wasm
else
echo "Genesis head and wasm are in pod ${HOSTNAME%-*}-0"
fi
volumeMounts:
- mountPath: /chain-data
name: chain-data
Loading

0 comments on commit 9fe1c9e

Please sign in to comment.