From 744a7cdae70b262b7e603c2c4609fe1999e39eae Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Wed, 28 Mar 2018 02:17:03 -0700 Subject: [PATCH] [stable/ethereum] Add Chart for Deploying Private Ethereum Network (#3220) * add chart for deploying private ethereum network. closes #2088. * fix: update readme. add privatekey for default account to fund * fix: add private key to values. import-geth-account to geth nodes * fix: decrease difficulty of network. increase gas limit, allow remote connections to geth-tx * fix: make difficulty/gasLimit configurable. use versioned ethstats image * fix: use component labels * fix: remove LICENSE * fix: as per code review, remove keys * docs: add documentation on creating a new geth account * fix: clarify documentation on creating a new account * add custom test values.yaml * move chart to stable * use latest _helpers --- stable/ethereum/Chart.yaml | 14 +++ stable/ethereum/README.md | 102 +++++++++++++++++ stable/ethereum/ci/test-values.yaml | 35 ++++++ stable/ethereum/scripts/get-bootnode.sh | 18 +++ stable/ethereum/templates/NOTES.txt | 56 +++++++++ stable/ethereum/templates/_helpers.tpl | 32 ++++++ .../templates/bootnode.deployment.yaml | 70 ++++++++++++ .../ethereum/templates/bootnode.service.yaml | 22 ++++ .../templates/ethstats.deployment.yaml | 37 ++++++ .../ethereum/templates/ethstats.secret.yaml | 12 ++ .../ethereum/templates/ethstats.service.yaml | 19 ++++ .../templates/geth-account.secret.yaml | 17 +++ .../templates/geth-miner.deployment.yaml | 102 +++++++++++++++++ .../templates/geth-tx.deployment.yaml | 106 ++++++++++++++++++ .../ethereum/templates/geth-tx.service.yaml | 22 ++++ stable/ethereum/templates/geth.configmap.yaml | 30 +++++ stable/ethereum/values.yaml | 44 ++++++++ 17 files changed, 738 insertions(+) create mode 100644 stable/ethereum/Chart.yaml create mode 100644 stable/ethereum/README.md create mode 100644 stable/ethereum/ci/test-values.yaml create mode 100644 stable/ethereum/scripts/get-bootnode.sh create mode 100644 stable/ethereum/templates/NOTES.txt create mode 100644 stable/ethereum/templates/_helpers.tpl create mode 100644 stable/ethereum/templates/bootnode.deployment.yaml create mode 100644 stable/ethereum/templates/bootnode.service.yaml create mode 100644 stable/ethereum/templates/ethstats.deployment.yaml create mode 100644 stable/ethereum/templates/ethstats.secret.yaml create mode 100644 stable/ethereum/templates/ethstats.service.yaml create mode 100644 stable/ethereum/templates/geth-account.secret.yaml create mode 100644 stable/ethereum/templates/geth-miner.deployment.yaml create mode 100644 stable/ethereum/templates/geth-tx.deployment.yaml create mode 100644 stable/ethereum/templates/geth-tx.service.yaml create mode 100644 stable/ethereum/templates/geth.configmap.yaml create mode 100644 stable/ethereum/values.yaml diff --git a/stable/ethereum/Chart.yaml b/stable/ethereum/Chart.yaml new file mode 100644 index 0000000000..d69c7c887c --- /dev/null +++ b/stable/ethereum/Chart.yaml @@ -0,0 +1,14 @@ +name: ethereum +version: 0.1.0 +description: private Ethereum network Helm chart for Kubernetes +keywords: +- ethereum +- blockchain +home: https://www.ethereum.org/ +sources: +- https://github.com/ethereum/go-ethereum +maintainers: +- name: jpoon + email: kubernetes@jasonpoon.ca +icon: https://www.ethereum.org/images/logos/ETHEREUM-LOGO_PORTRAIT_Black_small.png +appVersion: v1.7.3 diff --git a/stable/ethereum/README.md b/stable/ethereum/README.md new file mode 100644 index 0000000000..791f121c70 --- /dev/null +++ b/stable/ethereum/README.md @@ -0,0 +1,102 @@ +# ethereum + +[Ethereum](https://www.ethereum.org/) is a decentralized platform for building applications using blockchain. + +## TL;DR; + +```console +$ helm install stable/ethereum +``` + +## Introduction + +This chart deploys a **private** [Ethereum](https://www.ethereum.org/) network onto a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. This network is **not** connected to MainNet, and for further information on running a private network, refer to [Geth's documentation](https://github.com/ethereum/go-ethereum/wiki/Private-network). This chart is comprised of 4 components: + +1. *bootnode*: used for Geth node discovery +1. *ethstats*: [Ethereum Network Stats](https://github.com/cubedro/eth-netstats) +1. *geth-miner*: Geth miner nodes +1. *geth-tx*: Geth transaction nodes with mining disabled whose responsbility is to respond to API (websocket, rpc) queries + +## Prerequisites + +* Kubernetes 1.8 + +## Installing the Chart + +1. Create an Ethereum address and private key. To create a new Ethereum wallet, refer to [this blog post](https://kobl.one/blog/create-full-ethereum-keypair-and-address/) which will walkthrough the following instructions in greater detail: + + ```console + $ git clone https://github.com/vkobel/ethereum-generate-wallet + $ cd ethereum-generate-wallet + $ pip3 install -r requirements.txt + $ python3 ethereum-wallet-generator.py + + Private key: 38000e15ca07309cc2d0b30faaaadb293c45ea222a117e9e9c6a2a9872bb3bcf + Public key: 60758d37d431d34b920847212febbd583008ec2a34d00f907d48bd48b88dc2661806eb99cb6178312d228b2fd08cdb88bafc352d0395ae09b2fe453f0c4403ad + Address: 0xab70383d9207c6cc43ab85eeef9db4d33a8ad4e8 + ``` + +2. Install the chart as follows: + + ```console + $ helm install --name my-release stable/ethereum + --set geth.account.address=[PUBLIC_ADDRESS] + --set geth.account.privateKey=[PRIVATE_KEY] + --set geth.account.secret=[SECRET] + ``` + + using the above generated example, the configurations would equate to: + + * `geth.account.address` = `0xab70383d9207c6cc43ab85eeef9db4d33a8ad4e8` + * `geth.account.privateKey` = `38000e15ca07309cc2d0b30faaaadb293c45ea222a117e9e9c6a2a9872bb3bcf` + * `geth.account.secret` = any passphrase that Geth will use to encrypt your private key + + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following tables lists the configurable parameters of the vault chart and their default values. + +| Parameter | Description | Default | +|-----------------------------------|-----------------------------------------------|---------------------------------------| +| `imagePullPolicy` | Container pull policy | `IfNotPresent` | +| `bootnode.image.repository` | bootnode container image to use | `ethereum/client-go` | +| `bootnode.image.tag` | bootnode container image tag to deploy | `alltools-v1.7.3` | +| `ethstats.image.repository` | ethstats container image to use | `ethereumex/eth-stats-dashboard` | +| `ethstats.image.tag` | ethstats container image tag to deploy | `latest` | +| `ethstats.webSocketSecret` | ethstats secret for posting data | `my-secret-for-connecting-to-ethstats`| +| `ethstats.service.type` | k8s service type for ethstats | `LoadBalancer` | +| `geth.image.repository` | geth container image to use | `ethereum/client-go` | +| `geth.image.tag` | geth container image tag to deploy | `v1.7.3` | +| `geth.tx.replicaCount` | geth transaction nodes replica count | `2` | +| `geth.tx.service.type` | k8s service type for geth transaction nodes | `ClusterIP` | +| `geth.miner.replicaCount` | geth miner nodes replica count | `3` | +| `geth.miner.account.secret` | geth account secret | `my-secret-account-password` | +| `geth.genesis.networkId` | Ethereum network id | `98052` | +| `geth.genesis.difficulty` | Ethereum network difficulty | `0x0400` | +| `geth.genesis.gasLimit` | Ethereum network gas limit | `0x8000000` | +| `geth.account.address` | Geth Account to be initially funded and deposited with mined Ether | | +| `geth.account.privateKey` | Geth Private Key | | +| `geth.account.secret` | Geth Account Secret | | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, to configure the networkid: + +```console +$ helm install stable/ethereum --name ethereum --set geth.genesis.networkid=98052 +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install stable/ethereum -f values.yaml +``` + diff --git a/stable/ethereum/ci/test-values.yaml b/stable/ethereum/ci/test-values.yaml new file mode 100644 index 0000000000..529f515186 --- /dev/null +++ b/stable/ethereum/ci/test-values.yaml @@ -0,0 +1,35 @@ +# Test values for ethereum for CI + +imagePullPolicy: IfNotPresent + +bootnode: + image: + repository: ethereum/client-go + tag: alltools-v1.7.3 + +ethstats: + image: + repository: ethereumex/eth-stats-dashboard + tag: v0.0.1 + webSocketSecret: my-secret-for-connecting-to-ethstats + service: + type: LoadBalancer + +geth: + image: + repository: ethereum/client-go + tag: v1.7.3 + tx: + replicaCount: 2 + service: + type: ClusterIP + miner: + replicaCount: 3 + genesis: + difficulty: '0x0400' + gasLimit: '0x8000000' + networkId: 98052 + account: + address: 0xab70383d9207c6cc43ab85eeef9db4d33a8ad4e8 + privateKey: 38000e15ca07309cc2d0b30faaaadb293c45ea222a117e9e9c6a2a9872bb3bcf + secret: my-super-secret-passphrase \ No newline at end of file diff --git a/stable/ethereum/scripts/get-bootnode.sh b/stable/ethereum/scripts/get-bootnode.sh new file mode 100644 index 0000000000..e4053f67a6 --- /dev/null +++ b/stable/ethereum/scripts/get-bootnode.sh @@ -0,0 +1,18 @@ +apk add --no-cache curl; +CNT=0; +echo "retreiving bootnodes from $BOOTNODE_SVC" +while [ $CNT -le 90 ] +do + curl -m 5 -s $BOOTNODE_SVC | xargs echo -n >> /geth/bootnodes; + if [ -s /geth/bootnodes ] + then + cat /geth/bootnodes; + exit 0; + fi; + + echo "no bootnodes found. retrying $CNT..."; + sleep 2 || break; + CNT=$((CNT+1)); +done; +echo "WARNING. unable to find bootnodes. continuing but geth may not be able to find any peers."; +exit 0; \ No newline at end of file diff --git a/stable/ethereum/templates/NOTES.txt b/stable/ethereum/templates/NOTES.txt new file mode 100644 index 0000000000..aa3c399fc0 --- /dev/null +++ b/stable/ethereum/templates/NOTES.txt @@ -0,0 +1,56 @@ +{{- if and .Values.geth.account.address .Values.geth.account.privateKey .Values.geth.account.secret }} + + 1. View the EthStats dashboard at: + + {{- if contains "NodePort" .Values.ethstats.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "ethereum.fullname" . }}-ethstats) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT + {{- else if contains "LoadBalancer" .Values.ethstats.service.type }} + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "ethereum.fullname" . }}-ethstats -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "ethereum.fullname" . }}-ethstats-service' + {{- else if contains "ClusterIP" .Values.ethstats.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "ethereum.fullname" . }}-ethstats,release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1 to use your application" + kubectl port-forward $POD_NAME 80:80 + {{- end }} + + 2. Connect to Geth transaction nodes (through RPC or WS) at the following IP: + + {{- if contains "NodePort" .Values.geth.tx.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "ethereum.fullname" . }}-geth-tx) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo $NODE_IP:$NODE_PORT + {{- else if contains "LoadBalancer" .Values.geth.tx.service.type }} + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "ethereum.fullname" . }}-geth-tx -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo $SERVICE_IP + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "ethereum.fullname" . }}-geth-tx' + {{- else if contains "ClusterIP" .Values.geth.tx.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "ethereum.fullname" . }}-geth-tx,release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward $POD_NAME 8545:8545 8546:8546 + {{- end }} + +{{- else -}} + +############################################################################## +#### ERROR: Geth Account has not been configured! #### +############################################################################## + +This deployment will be incomplete until a Geth account is configured. +See https://github.com/ethereum/go-ethereum/wiki/Managing-your-accounts for +instructions on how to create a Geth account. + +Once created, run: + + helm upgrade {{ .Release.Name }} \ + --set geth.account.address=YOUR-ETHEREUM-ADDRESS-HERE + --set geth.account.privateKey=YOUR-PRIVATE-KEY-HERE + --set geth.account.secret=YOUR-SECRET-HERE + stable/ethereum + +{{- end }} \ No newline at end of file diff --git a/stable/ethereum/templates/_helpers.tpl b/stable/ethereum/templates/_helpers.tpl new file mode 100644 index 0000000000..207d526f72 --- /dev/null +++ b/stable/ethereum/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "ethereum.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "ethereum.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ethereum.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/stable/ethereum/templates/bootnode.deployment.yaml b/stable/ethereum/templates/bootnode.deployment.yaml new file mode 100644 index 0000000000..030ccda096 --- /dev/null +++ b/stable/ethereum/templates/bootnode.deployment.yaml @@ -0,0 +1,70 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "ethereum.fullname" . }}-bootnode + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: bootnode +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: bootnode + template: + metadata: + labels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: bootnode + spec: + containers: + - name: bootnode + image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "bootnode --nodekey=/etc/bootnode/node.key --verbosity=4" + volumeMounts: + - name: data + mountPath: /etc/bootnode + ports: + - name: discovery + containerPort: 30301 + protocol: UDP + - name: bootnode-server + image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }} + imagePullPolicy: {{.Values.imagePullPolicy}} + command: ["/bin/sh"] + args: + - "-c" + - "while [ 1 ]; do echo -e \"HTTP/1.1 200 OK\n\nenode://$(bootnode -writeaddress --nodekey=/etc/bootnode/node.key)@$(POD_IP):30301\" | nc -l -v -p 80 || break; done;" + volumeMounts: + - name: data + mountPath: /etc/bootnode + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + ports: + - containerPort: 80 + initContainers: + - name: genkey + image: {{ .Values.bootnode.image.repository }}:{{ .Values.bootnode.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "bootnode --genkey=/etc/bootnode/node.key" + volumeMounts: + - name: data + mountPath: /etc/bootnode + volumes: + - name: data + emptyDir: {} diff --git a/stable/ethereum/templates/bootnode.service.yaml b/stable/ethereum/templates/bootnode.service.yaml new file mode 100644 index 0000000000..1083e287bb --- /dev/null +++ b/stable/ethereum/templates/bootnode.service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "ethereum.fullname" . }}-bootnode + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: bootnode +spec: + selector: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: bootnode + clusterIP: None + ports: + - name: discovery + port: 30301 + protocol: UDP + - name: http + port: 80 \ No newline at end of file diff --git a/stable/ethereum/templates/ethstats.deployment.yaml b/stable/ethereum/templates/ethstats.deployment.yaml new file mode 100644 index 0000000000..60482a1351 --- /dev/null +++ b/stable/ethereum/templates/ethstats.deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "ethereum.fullname" . }}-ethstats + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: ethstats +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: ethstats + template: + metadata: + labels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: ethstats + spec: + containers: + - name: ethstats + image: {{ .Values.ethstats.image.repository }}:{{ .Values.ethstats.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + ports: + - name: http + containerPort: 3000 + env: + - name: WS_SECRET + valueFrom: + secretKeyRef: + name: {{ template "ethereum.fullname" . }}-ethstats + key: WS_SECRET \ No newline at end of file diff --git a/stable/ethereum/templates/ethstats.secret.yaml b/stable/ethereum/templates/ethstats.secret.yaml new file mode 100644 index 0000000000..ee5412227a --- /dev/null +++ b/stable/ethereum/templates/ethstats.secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "ethereum.fullname" . }}-ethstats + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + WS_SECRET: {{ .Values.ethstats.webSocketSecret | b64enc | quote }} \ No newline at end of file diff --git a/stable/ethereum/templates/ethstats.service.yaml b/stable/ethereum/templates/ethstats.service.yaml new file mode 100644 index 0000000000..259e696926 --- /dev/null +++ b/stable/ethereum/templates/ethstats.service.yaml @@ -0,0 +1,19 @@ +kind: Service +apiVersion: v1 +metadata: + name: {{ template "ethereum.fullname" . }}-ethstats + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: ethstats +spec: + selector: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: ethstats + type: {{ .Values.ethstats.service.type }} + ports: + - port: 80 + targetPort: http \ No newline at end of file diff --git a/stable/ethereum/templates/geth-account.secret.yaml b/stable/ethereum/templates/geth-account.secret.yaml new file mode 100644 index 0000000000..d4e326acec --- /dev/null +++ b/stable/ethereum/templates/geth-account.secret.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "ethereum.fullname" . }}-geth-account + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + {{- if .Values.geth.account.privateKey }} + accountPrivateKey: {{ .Values.geth.account.privateKey | b64enc | quote }} + {{- end }} + {{- if .Values.geth.account.secret }} + accountSecret: {{ .Values.geth.account.secret | b64enc | quote }} + {{- end }} \ No newline at end of file diff --git a/stable/ethereum/templates/geth-miner.deployment.yaml b/stable/ethereum/templates/geth-miner.deployment.yaml new file mode 100644 index 0000000000..8fdf1063dc --- /dev/null +++ b/stable/ethereum/templates/geth-miner.deployment.yaml @@ -0,0 +1,102 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "ethereum.fullname" . }}-geth-miner + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: geth-miner +spec: + replicas: {{ .Values.geth.miner.replicaCount }} + selector: + matchLabels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: geth-miner + template: + metadata: + labels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: geth-miner + spec: + containers: + - name: geth-miner + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "geth --bootnodes=`cat /root/.ethereum/bootnodes` --mine --etherbase=0 --networkid=${NETWORK_ID} --ethstats=${HOSTNAME}:${ETHSTATS_SECRET}@${ETHSTATS_SVC} --verbosity=5" + env: + - name: ETHSTATS_SVC + value: {{ template "ethereum.fullname" . }}-ethstats.{{ .Release.Namespace }} + - name: ETHSTATS_SECRET + valueFrom: + secretKeyRef: + name: {{ template "ethereum.fullname" . }}-ethstats + key: WS_SECRET + - name: NETWORK_ID + valueFrom: + configMapKeyRef: + name: {{ template "ethereum.fullname" . }}-geth-config + key: networkid + ports: + - name: discovery-udp + containerPort: 30303 + protocol: UDP + - name: discovery-tcp + containerPort: 30303 + volumeMounts: + - name: data + mountPath: /root/.ethereum + initContainers: + - name: init-genesis + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "init" + - "/var/geth/genesis.json" + volumeMounts: + - name: data + mountPath: /root/.ethereum + - name: config + mountPath: /var/geth + - name: import-geth-account + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "geth account import --password /root/.ethereum/account/accountSecret /root/.ethereum/account/accountPrivateKey" + volumeMounts: + - name: data + mountPath: /root/.ethereum + - name: account + readOnly: true + mountPath: /root/.ethereum/account + - name: get-bootnodes + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - |- +{{ .Files.Get "scripts/get-bootnode.sh" | indent 10 }} + env: + - name: BOOTNODE_SVC + value: {{ template "ethereum.fullname" . }}-bootnode.{{ .Release.Namespace }} + volumeMounts: + - name: data + mountPath: /geth + volumes: + - name: data + emptyDir: {} + - name: config + configMap: + name: {{ template "ethereum.fullname" . }}-geth-config + - name: account + secret: + secretName: {{ template "ethereum.fullname" . }}-geth-account \ No newline at end of file diff --git a/stable/ethereum/templates/geth-tx.deployment.yaml b/stable/ethereum/templates/geth-tx.deployment.yaml new file mode 100644 index 0000000000..934669d957 --- /dev/null +++ b/stable/ethereum/templates/geth-tx.deployment.yaml @@ -0,0 +1,106 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "ethereum.fullname" . }}-geth-tx + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: geth-tx +spec: + replicas: {{ .Values.geth.tx.replicaCount }} + selector: + matchLabels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: geth-tx + template: + metadata: + labels: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: geth-tx + spec: + containers: + - name: geth-tx + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "geth --bootnodes=`cat /root/.ethereum/bootnodes` --rpc --rpcaddr 0.0.0.0 --rpcapi=eth,net,web3 --rpccorsdomain='*' --ws --networkid=${NETWORK_ID} --ethstats=${HOSTNAME}:${ETHSTATS_SECRET}@${ETHSTATS_SVC} --verbosity=5" + env: + - name: ETHSTATS_SVC + value: {{ template "ethereum.fullname" . }}-ethstats.{{ .Release.Namespace }} + - name: ETHSTATS_SECRET + valueFrom: + secretKeyRef: + name: {{ template "ethereum.fullname" . }}-ethstats + key: WS_SECRET + - name: NETWORK_ID + valueFrom: + configMapKeyRef: + name: {{ template "ethereum.fullname" . }}-geth-config + key: networkid + ports: + - name: rpc + containerPort: 8545 + - name: ws + containerPort: 8546 + - name: discovery-udp + containerPort: 30303 + protocol: UDP + - name: discovery-tcp + containerPort: 30303 + volumeMounts: + - name: data + mountPath: /root/.ethereum + initContainers: + - name: init-genesis + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "init" + - "/var/geth/genesis.json" + volumeMounts: + - name: data + mountPath: /root/.ethereum + - name: config + mountPath: /var/geth + - name: import-geth-account + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - "geth account import --password /root/.ethereum/account/accountSecret /root/.ethereum/account/accountPrivateKey" + volumeMounts: + - name: data + mountPath: /root/.ethereum + - name: account + readOnly: true + mountPath: /root/.ethereum/account + - name: get-bootnodes + image: {{ .Values.geth.image.repository }}:{{ .Values.geth.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: + - "-c" + - |- +{{ .Files.Get "scripts/get-bootnode.sh" | indent 10 }} + env: + - name: BOOTNODE_SVC + value: {{ template "ethereum.fullname" . }}-bootnode.{{ .Release.Namespace }} + volumeMounts: + - name: data + mountPath: /geth + volumes: + - name: data + emptyDir: {} + - name: config + configMap: + name: {{ template "ethereum.fullname" . }}-geth-config + - name: account + secret: + secretName: {{ template "ethereum.fullname" . }}-geth-account diff --git a/stable/ethereum/templates/geth-tx.service.yaml b/stable/ethereum/templates/geth-tx.service.yaml new file mode 100644 index 0000000000..fd2dac6779 --- /dev/null +++ b/stable/ethereum/templates/geth-tx.service.yaml @@ -0,0 +1,22 @@ +kind: Service +apiVersion: v1 +metadata: + name: {{ template "ethereum.fullname" . }}-geth-tx + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: geth-tx +spec: + selector: + app: {{ template "ethereum.name" . }} + release: {{ .Release.Name }} + component: geth-tx + type: {{ .Values.geth.tx.service.type }} + sessionAffinity: ClientIP + ports: + - name: rpc + port: 8545 + - name: ws + port: 8546 \ No newline at end of file diff --git a/stable/ethereum/templates/geth.configmap.yaml b/stable/ethereum/templates/geth.configmap.yaml new file mode 100644 index 0000000000..c13be0dee4 --- /dev/null +++ b/stable/ethereum/templates/geth.configmap.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "ethereum.fullname" . }}-geth-config + labels: + app: {{ template "ethereum.name" . }} + chart: {{ template "ethereum.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + networkid: "{{ .Values.geth.genesis.networkId }}" + genesis.json: |- + { + "config": { + "chainId": {{ .Values.geth.genesis.networkId }}, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0 + }, + "difficulty": {{ .Values.geth.genesis.difficulty | quote }}, + "gasLimit": {{ .Values.geth.genesis.gasLimit | quote }}, + "alloc": { + {{- if .Values.geth.account.address }} + {{ .Values.geth.account.address | quote }}: { + "balance": "1000000000000000000000000" + } + {{- end }} + } + } \ No newline at end of file diff --git a/stable/ethereum/values.yaml b/stable/ethereum/values.yaml new file mode 100644 index 0000000000..25fb89be26 --- /dev/null +++ b/stable/ethereum/values.yaml @@ -0,0 +1,44 @@ +# Default values for ethereum. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +imagePullPolicy: IfNotPresent + +bootnode: + image: + repository: ethereum/client-go + tag: alltools-v1.7.3 + +ethstats: + image: + repository: ethereumex/eth-stats-dashboard + tag: v0.0.1 + webSocketSecret: my-secret-for-connecting-to-ethstats + service: + type: LoadBalancer + +geth: + image: + repository: ethereum/client-go + tag: v1.7.3 + tx: + # transaction nodes + replicaCount: 2 + service: + type: ClusterIP + miner: + # miner nodes + replicaCount: 3 + genesis: + # geth genesis block + difficulty: '0x0400' + gasLimit: '0x8000000' + networkId: 98052 + account: + # You will need to configure an Ethereum account before this + # network will run. The Ethereum account will be used to seed + # Ether and mined Ether will be deposited into this account. + # ref: https://github.com/ethereum/go-ethereum/wiki/Managing-your-accounts + address: + privateKey: + secret: