From fa16b58c0933232a50f5802d2a8a88a1ae92e803 Mon Sep 17 00:00:00 2001 From: antares-sw <23400824+antares-sw@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:25:56 +0300 Subject: [PATCH] Add Reth chart --- charts/reth/.helmignore | 23 ++ charts/reth/Chart.lock | 6 + charts/reth/Chart.yaml | 24 ++ charts/reth/templates/_helpers.yaml | 3 + charts/reth/templates/clusterrole.yaml | 10 + charts/reth/templates/clusterrolebinding.yaml | 16 + charts/reth/templates/pdb.yaml | 18 + charts/reth/templates/prometheusrules.yaml | 35 ++ charts/reth/templates/role.yaml | 10 + charts/reth/templates/rolebinding.yaml | 15 + charts/reth/templates/secret.yaml | 11 + charts/reth/templates/service-p2p.yaml | 42 ++ charts/reth/templates/service.yaml | 43 ++ charts/reth/templates/serviceaccount.yaml | 12 + charts/reth/templates/servicemonitor.yaml | 42 ++ charts/reth/templates/statefulset.yaml | 255 ++++++++++++ .../reth/templates/tests/test-connection.yaml | 19 + charts/reth/values.yaml | 384 ++++++++++++++++++ 18 files changed, 968 insertions(+) create mode 100644 charts/reth/.helmignore create mode 100644 charts/reth/Chart.lock create mode 100644 charts/reth/Chart.yaml create mode 100644 charts/reth/templates/_helpers.yaml create mode 100644 charts/reth/templates/clusterrole.yaml create mode 100644 charts/reth/templates/clusterrolebinding.yaml create mode 100644 charts/reth/templates/pdb.yaml create mode 100644 charts/reth/templates/prometheusrules.yaml create mode 100644 charts/reth/templates/role.yaml create mode 100644 charts/reth/templates/rolebinding.yaml create mode 100644 charts/reth/templates/secret.yaml create mode 100644 charts/reth/templates/service-p2p.yaml create mode 100644 charts/reth/templates/service.yaml create mode 100644 charts/reth/templates/serviceaccount.yaml create mode 100644 charts/reth/templates/servicemonitor.yaml create mode 100644 charts/reth/templates/statefulset.yaml create mode 100644 charts/reth/templates/tests/test-connection.yaml create mode 100644 charts/reth/values.yaml diff --git a/charts/reth/.helmignore b/charts/reth/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/reth/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/reth/Chart.lock b/charts/reth/Chart.lock new file mode 100644 index 000000000..5d404f403 --- /dev/null +++ b/charts/reth/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.stakewise.io/ + version: 1.0.0 +digest: sha256:a52d823dcd535c64eafc9df56fe41455c602032e084b8adcaa34e536451d2ab2 +generated: "2023-01-09T12:35:46.013108+04:00" diff --git a/charts/reth/Chart.yaml b/charts/reth/Chart.yaml new file mode 100644 index 000000000..64eddbed3 --- /dev/null +++ b/charts/reth/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: reth +version: 1.0.0 +kubeVersion: "^1.20.0-0" +description: Official Golang implementation of the Ethereum v1 protocol. +type: application +icon: https://storage.googleapis.com/stakewise-charts/stakewise.png +keywords: + - ethereum + - blockchain + - reth + - p2p +home: https://www.ethereum.org/ +sources: + - https://github.com/ethereum/go-ethereum/ +maintainers: + - name: Dmitri Tsumak + email: dmitri@stakewise.io +appVersion: v1.0.0 + +dependencies: + - name: common + version: 1.x.x + repository: https://charts.stakewise.io/ diff --git a/charts/reth/templates/_helpers.yaml b/charts/reth/templates/_helpers.yaml new file mode 100644 index 000000000..3dba45e8f --- /dev/null +++ b/charts/reth/templates/_helpers.yaml @@ -0,0 +1,3 @@ +{{- define "reth.p2pPort" -}} +{{- printf "30303" -}} +{{- end -}} diff --git a/charts/reth/templates/clusterrole.yaml b/charts/reth/templates/clusterrole.yaml new file mode 100644 index 000000000..6d7136bd1 --- /dev/null +++ b/charts/reth/templates/clusterrole.yaml @@ -0,0 +1,10 @@ +{{- if or .Values.global.rbac.create .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "common.names.clusterRoleName" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +rules: +{{- toYaml .Values.rbac.clusterRules | nindent 0 }} +{{- end }} diff --git a/charts/reth/templates/clusterrolebinding.yaml b/charts/reth/templates/clusterrolebinding.yaml new file mode 100644 index 000000000..87d636dac --- /dev/null +++ b/charts/reth/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if or .Values.global.rbac.create .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "common.names.clusterRoleName" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "common.names.clusterRoleName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "common.names.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/reth/templates/pdb.yaml b/charts/reth/templates/pdb.yaml new file mode 100644 index 000000000..4ef63f0ff --- /dev/null +++ b/charts/reth/templates/pdb.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +spec: +{{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} +{{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} +{{- end }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/reth/templates/prometheusrules.yaml b/charts/reth/templates/prometheusrules.yaml new file mode 100644 index 000000000..af4acd4f7 --- /dev/null +++ b/charts/reth/templates/prometheusrules.yaml @@ -0,0 +1,35 @@ +{{- if and (or .Values.global.metrics.enabled .Values.metrics.enabled) + (or .Values.global.metrics.prometheusRule.enabled .Values.metrics.prometheusRule.enabled) }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + {{- if .Values.metrics.prometheusRule.namespace }} + namespace: {{ .Values.metrics.prometheusRule.namespace }} + {{- else }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- toYaml .Values.metrics.prometheusRule.additionalLabels | nindent 4 }} + {{- end }} +spec: + groups: + {{- with .Values.metrics.prometheusRule.rules }} + - name: {{ include "common.names.fullname" $ }} + rules: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- if .Values.metrics.prometheusRule.default }} + - name: {{ include "common.names.fullname" $ }}-default + rules: + - alert: RethNodeDown + expr: up{job="{{ include "common.names.fullname" . }}"} == 0 + for: 5m + labels: + severity: critical + annotations: + summary: Reth Node {{ printf "{{ $labels.instance }}" }} down + description: Reth Node {{ printf "{{ $labels.instance }}" }} is down + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/reth/templates/role.yaml b/charts/reth/templates/role.yaml new file mode 100644 index 000000000..dfbc0fe48 --- /dev/null +++ b/charts/reth/templates/role.yaml @@ -0,0 +1,10 @@ +{{- if or .Values.global.rbac.create .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +rules: +{{- toYaml .Values.rbac.rules | nindent 0 }} +{{- end }} diff --git a/charts/reth/templates/rolebinding.yaml b/charts/reth/templates/rolebinding.yaml new file mode 100644 index 000000000..1fdb617ba --- /dev/null +++ b/charts/reth/templates/rolebinding.yaml @@ -0,0 +1,15 @@ +{{- if or .Values.global.rbac.create .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "common.names.serviceAccountName" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "common.names.serviceAccountName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "common.names.serviceAccountName" . }} +{{- end }} diff --git a/charts/reth/templates/secret.yaml b/charts/reth/templates/secret.yaml new file mode 100644 index 000000000..2981fe224 --- /dev/null +++ b/charts/reth/templates/secret.yaml @@ -0,0 +1,11 @@ +{{- if .Values.global.JWTSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +type: Opaque +data: + jwtsecret: {{ .Values.global.JWTSecret | b64enc | quote }} +{{- end }} diff --git a/charts/reth/templates/service-p2p.yaml b/charts/reth/templates/service-p2p.yaml new file mode 100644 index 000000000..b69b568d7 --- /dev/null +++ b/charts/reth/templates/service-p2p.yaml @@ -0,0 +1,42 @@ +{{- if .Values.p2pNodePort.enabled -}} +{{- range $i, $e := until (int .Values.global.replicaCount) }} +{{- $port := add $.Values.p2pNodePort.startAt $i -}} +{{- if hasKey $.Values.p2pNodePort.replicaToNodePort ($i | toString) -}} + {{ $port = index $.Values.p2pNodePort.replicaToNodePort ($i | toString) }} +{{- end }} + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" $ }}-{{ $i }} + labels: + {{- include "common.labels.standard" $ | nindent 4 }} + pod: "{{ include "common.names.fullname" $ }}-{{ $i }}" + type: p2p + {{- with $.Values.p2pNodePort.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ $.Values.p2pNodePort.type }} + externalTrafficPolicy: Local + ports: + - name: p2p-tcp + port: {{ include "reth.p2pPort" $ }} + protocol: TCP + targetPort: {{ $port }} + nodePort: {{ $port }} + {{- if eq $.Values.p2pNodePort.type "NodePort" }} + - name: p2p-udp + port: {{ include "reth.p2pPort" $ }} + protocol: UDP + targetPort: p2p-udp + nodePort: {{ $port }} + {{- end }} + selector: + {{- include "common.labels.matchLabels" $ | nindent 4 }} + statefulset.kubernetes.io/pod-name: "{{ include "common.names.fullname" $ }}-{{ $i }}" + +{{- end }} +{{- end }} diff --git a/charts/reth/templates/service.yaml b/charts/reth/templates/service.yaml new file mode 100644 index 000000000..16eaff920 --- /dev/null +++ b/charts/reth/templates/service.yaml @@ -0,0 +1,43 @@ +{{- if or .Values.http.enabled .Values.ws.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} +spec: +{{- if .Values.svcHeadless }} + clusterIP: None +{{- end }} +{{- if .Values.sessionAffinity.enabled }} + sessionAffinity: ClientIP + sessionAffinityConfig: + clientIP: + timeoutSeconds: {{ .Values.sessionAffinity.timeoutSeconds }} +{{- end }} + type: ClusterIP + ports: + {{- if .Values.global.JWTSecret }} + - name: authrpc + port: {{ .Values.authRpc.port }} + targetPort: authrpc + {{- end }} + {{- if .Values.http.enabled }} + - name: http + port: {{ .Values.http.port }} + targetPort: http + {{- end }} + {{- if .Values.ws.enabled }} + - name: ws + port: {{ .Values.ws.port }} + targetPort: ws + {{- end }} + {{- if .Values.global.metrics.enabled }} + - name: metrics + port: {{ .Values.metrics.port }} + targetPort: metrics + {{- end }} + selector: + {{- include "common.labels.matchLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/reth/templates/serviceaccount.yaml b/charts/reth/templates/serviceaccount.yaml new file mode 100644 index 000000000..cb2edd11f --- /dev/null +++ b/charts/reth/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if or .Values.global.serviceAccount.create .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "common.names.serviceAccountName" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/reth/templates/servicemonitor.yaml b/charts/reth/templates/servicemonitor.yaml new file mode 100644 index 000000000..f4bea9897 --- /dev/null +++ b/charts/reth/templates/servicemonitor.yaml @@ -0,0 +1,42 @@ +{{- if and (or .Values.global.metrics.enabled .Values.metrics.enabled) + (or .Values.global.metrics.serviceMonitor.enabled .Values.metrics.serviceMonitor.enabled) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "common.names.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- else }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: metrics + path: / + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.metrics.serviceMonitor.relabelings | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- toYaml .Values.metrics.serviceMonitor.metricRelabelings | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/reth/templates/statefulset.yaml b/charts/reth/templates/statefulset.yaml new file mode 100644 index 000000000..0f3c4531d --- /dev/null +++ b/charts/reth/templates/statefulset.yaml @@ -0,0 +1,255 @@ +--- +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "common.names.fullname" . }} + labels: + {{- include "common.labels.statefulset" . | nindent 4 }} +spec: + replicas: {{ .Values.global.replicaCount }} + podManagementPolicy: "Parallel" + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + serviceName: {{ include "common.names.fullname" . }} + template: + metadata: + labels: + {{- include "common.labels.matchLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with (concat .Values.imagePullSecrets .Values.global.imagePullSecrets) }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{ toYaml . | nindent 8 | trim }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{ toYaml . | nindent 8 | trim }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{ toYaml . | nindent 8 | trim }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{ toYaml . | nindent 8 | trim }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + serviceAccountName: {{ include "common.names.serviceAccountName" . }} + priorityClassName: {{ .Values.priorityClassName | quote }} + initContainers: + - name: init + image: "{{ .Values.initImage.registry }}/{{ .Values.initImage.repository }}:{{ .Values.initImage.tag }}" + imagePullPolicy: {{ .Values.initImage.pullPolicy }} + securityContext: + runAsNonRoot: false + runAsUser: 0 + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - sh + - -c + - > + echo "Namespace: ${POD_NAMESPACE} Pod: ${POD_NAME}"; + {{- if .Values.p2pNodePort.enabled }} + {{- if eq .Values.p2pNodePort.type "LoadBalancer" }} + until [ -n "$(kubectl -n ${POD_NAMESPACE} get svc/${POD_NAME} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" ]; do echo "Waiting for load balancer gets an IP" && sleep 10; done; + export EXTERNAL_PORT=$(kubectl -n ${POD_NAMESPACE} get services -l "pod in (${POD_NAME}), type in (p2p)" -o jsonpath='{.items[0].spec.ports[0].nodePort}'); + export EXTERNAL_IP=$(kubectl -n ${POD_NAMESPACE} get svc/${POD_NAME} -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); + {{- else }} + export EXTERNAL_PORT=$(kubectl get services -l "pod in (${POD_NAME}), type in (p2p)" -o jsonpath='{.items[0].spec.ports[0].nodePort}'); + export EXTERNAL_IP=$(kubectl get nodes "${NODE_NAME}" -o jsonpath='{.status.addresses[?(@.type=="ExternalIP")].address}'); + {{- end }} + echo "EXTERNAL_PORT=$EXTERNAL_PORT" > /env/init-nodeport; + echo "EXTERNAL_IP=$EXTERNAL_IP" >> /env/init-nodeport; + cat /env/init-nodeport; + {{- end }} + {{- if and .Values.persistence.enabled .Values.initChownData }} + mkdir -p /data && chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsUser }} /data; + {{- end }} + volumeMounts: + - name: env-nodeport + mountPath: /env + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - sh + - -ac + - > + {{- if .Values.p2pNodePort.enabled }} + . /env/init-nodeport; + {{- end }} + exec /usr/local/bin/reth + node + {{- if .Values.global.JWTSecret }} + --authrpc.jwtsecret=/secret/jwtsecret + --authrpc.addr={{ .Values.authRpc.addr }} + --authrpc.port={{ .Values.authRpc.port }} + {{- end }} + {{- if .Values.http.enabled }} + --http + --http.addr=0.0.0.0 + --http.port={{ .Values.http.port }} + --http.corsdomain={{ .Values.http.corsDomain }} + --http.api={{ .Values.http.api }} + {{- end }} + {{- if .Values.p2pNodePort.enabled }} + --nat=extip:$EXTERNAL_IP + --port=$EXTERNAL_PORT + {{- else }} + --nat=extip:$(POD_IP) + --port={{ include "reth.p2pPort" . }} + {{- end }} + {{- if .Values.ws.enabled }} + --ws + --ws.addr=0.0.0.0 + --ws.port={{ .Values.ws.port }} + --ws.origins={{ .Values.ws.origins }} + --ws.api={{ .Values.ws.api }} + {{- end }} + --datadir=/data/ethereum + --chain={{ .Values.global.network }} + {{- range .Values.extraFlags }} + {{ . | quote }} + {{- end }} + {{- if .Values.global.metrics.enabled }} + {{- range .Values.metrics.flags }} + {{ . | quote }} + {{- end }} + {{- end }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + ports: + {{- if .Values.global.JWTSecret }} + - name: authrpc + containerPort: {{ .Values.authRpc.port }} + {{- end }} + {{- if .Values.http.enabled }} + - name: http + containerPort: {{ .Values.http.port }} + {{- end }} + {{- if .Values.ws.enabled }} + - name: ws + containerPort: {{ .Values.ws.port }} + {{- end }} + {{- if .Values.global.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.metrics.port }} + {{- end }} + {{- if .Values.p2pNodePort.enabled }} + - name: p2p-tcp + containerPort: {{ include "reth.p2pPort" . }} + protocol: TCP + - name: p2p-udp + containerPort: {{ include "reth.p2pPort" . }} + protocol: UDP + {{- end }} + volumeMounts: + - name: data + mountPath: /data/ethereum + {{- if .Values.global.JWTSecret }} + - name: jwtsecret + mountPath: /secret + readOnly: true + {{- end }} + - name: env-nodeport + mountPath: /env + {{- with .Values.resources }} + resources: + {{ toYaml . | nindent 12 | trim }} + {{- end }} + {{- if .Values.http.enabled }} + - name: sidecar + image: "{{ .Values.sidecar.registry }}/{{ .Values.sidecar.repository }}:{{ .Values.sidecar.tag }}" + imagePullPolicy: {{ .Values.sidecar.pullPolicy }} + env: + - name: SERVER_BINDADDR + value: "{{ .Values.sidecar.bindAddr }}:{{ .Values.sidecar.bindPort }}" + - name: CLIENT_PORT + value: {{ .Values.http.port | quote }} + ports: + - containerPort: {{ .Values.sidecar.bindPort }} + name: sidecar + protocol: TCP + {{- if or .Values.global.livenessProbe.enabled .Values.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + httpGet: + path: {{ .Values.livenessProbe.httpGet.path }} + port: {{ .Values.livenessProbe.httpGet.port }} + scheme: {{ .Values.livenessProbe.httpGet.scheme }} + {{- end }} + {{- if or .Values.global.readinessProbe.enabled .Values.readinessProbe.enabled }} + readinessProbe: + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + httpGet: + path: {{ .Values.readinessProbe.httpGet.path }} + port: {{ .Values.readinessProbe.httpGet.port }} + scheme: {{ .Values.readinessProbe.httpGet.scheme }} + {{- end }} + {{- end }} + volumes: + {{- if .Values.global.JWTSecret }} + - name: jwtsecret + secret: + secretName: {{ include "common.names.fullname" . }} + {{- end }} + - name: env-nodeport + emptyDir: {} +{{- if (not .Values.persistence.enabled) }} + - name: data + emptyDir: {} +{{- else }} + volumeClaimTemplates: + - metadata: + name: data + labels: + {{- include "common.labels.statefulset" . | nindent 10 }} + {{- with .Values.persistence.annotations }} + annotations: + {{ toYaml . | nindent 10 | trim }} + {{- end }} + spec: + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- end }} diff --git a/charts/reth/templates/tests/test-connection.yaml b/charts/reth/templates/tests/test-connection.yaml new file mode 100644 index 000000000..2e7e9fdbb --- /dev/null +++ b/charts/reth/templates/tests/test-connection.yaml @@ -0,0 +1,19 @@ +{{- if .Values.http.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "common.names.fullname" . }}-test-connection" + labels: + {{- include "common.labels.standard" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + {{- if .Values.http.enabled }} + args: ['{{ include "common.names.fullname" . }}:{{ .Values.http.port }}'] + {{- end }} + restartPolicy: Never +{{- end }} diff --git a/charts/reth/values.yaml b/charts/reth/values.yaml new file mode 100644 index 000000000..090c83957 --- /dev/null +++ b/charts/reth/values.yaml @@ -0,0 +1,384 @@ +# Default values for reth. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + replicaCount: 1 + + ## Eth2 network ID + ## + network: mainnet + + ## JSON Web Token (JWT) authentication is used to secure the communication + ## between the beacon node and execution client. You can generate a JWT using + ## a command line tool, for example: + ## openssl rand -hex 32 > token.txt + ## + JWTSecret: "" + + ## Credentials to fetch images from private registry + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + imagePullSecrets: [] + + ## Service account + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ## Additional settings could be made in non-global section. + ## + serviceAccount: + # Specifies whether a service account should be created + create: true + + ## RBAC configuration. + ## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/ + ## Additional settings could be made in non-global section. + ## + rbac: + ## Specifies whether RBAC resources are to be created + ## + create: true + + ## Monitoring + ## Additional settings could be made in non-global section. + ## + metrics: + ## Whether to enable metrics collection or not + ## + enabled: true + + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + serviceMonitor: + ## Create ServiceMonitor resource(s) for scraping metrics using PrometheusOperator + ## + enabled: false + + ## Custom PrometheusRule to be defined + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + ## + prometheusRule: + ## Create a custom prometheusRule Resource for scraping metrics using PrometheusOperator + ## + enabled: false + + ## Configure liveness and readiness probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ + ## NB! readinessProbe and livenessProbe must be disabled before fully synced + ## Additional settings could be made in non-global section. + ## + livenessProbe: + enabled: true + + readinessProbe: + enabled: true + +## Init image is used to chown data volume, initialise genesis, etc. +## +initImage: + registry: "docker.io" + repository: "bitnami/kubectl" + tag: "1.24" + pullPolicy: IfNotPresent + +## Sidecar image is used to perform Liveness/Readiness probes. +## +sidecar: + registry: "europe-west4-docker.pkg.dev" + repository: "stakewiselabs/public/ethnode-sidecar" + tag: "v1.0.6" + pullPolicy: IfNotPresent + bindAddr: "0.0.0.0" + bindPort: 3000 + +## Reth image version +## ref: https://hub.docker.com/r/ethereum/client-go/tags/ +## +image: + registry: "ghcr.io" + repository: "paradigmxyz/reth" + tag: "" + pullPolicy: IfNotPresent + +## Credentials to fetch images from private registry +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +## +imagePullSecrets: [] + +## Provide a name in place of reth for `app:` labels +## +nameOverride: "" + +## Provide a name to substitute for the full names of resources +## +fullnameOverride: "" + +## Service account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +## Additional labels for all resources +## +additionalLabels: + client-type: "execution" + +## Termination Grace Period +## ref: https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/#delete-pods +## +terminationGracePeriodSeconds: 300 + +## Pod Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +## +securityContext: + fsGroup: 0 + runAsUser: 0 + +## RBAC configuration. +## ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/ +## +rbac: + # The name of the cluster role to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + ## Required ClusterRole rules + ## + clusterRules: + ## Required to obtain the nodes external IP + ## + - apiGroups: [""] + resources: + - "nodes" + verbs: + - "get" + - "list" + - "watch" + ## Required Role rules + ## + rules: + ## Required to get information about the serices nodePort. + ## + - apiGroups: [""] + resources: + - "services" + verbs: + - "get" + - "list" + - "watch" + +## AuthRPC configuration. +## +authRpc: + port: "8551" + addr: "0.0.0.0" + +## RPC configuration. +## +http: + enabled: true + port: "8545" + api: "web3,eth,net" + corsDomain: "" + +## WebSocket configuration. +## +ws: + enabled: true + port: "8546" + api: "web3,eth,net" + origins: "*" + +## Extra flags to pass to the node +## +extraFlags: + - "--full" + +## Extra annotations for StatefulSet pods +podAnnotations: {} + +## Configure pod disruption budgets for Alertmanager +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget +## This configuration is immutable once created and will require the PDB to be deleted to be changed +## https://github.com/kubernetes/kubernetes/issues/45398 +## +podDisruptionBudget: + enabled: true + maxUnavailable: 1 + +## Defines whether the service must be headless +## +svcHeadless: true + +## Configure session affinity for validator clients to hit the same beacon node +## for the period specified in `timeoutSeconds` +## ref: https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-userspace +## +sessionAffinity: + # Whether to enable session affinity or not + enabled: false + # The session duration in seconds + timeoutSeconds: 86400 + +## When p2pNodePort is enabled, your P2P port will be exposed via service type NodePort. +## This will generate a service for each replica, with a port binding via NodePort. +## This is useful if you want to expose and announce your node to the Internet. +## +p2pNodePort: + ## @param p2pNodePort.enabled Expose P2P port via NodePort + ## + enabled: false + ## @param p2pNodePort.annotations + ## + annotations: {} + ## @param p2pNodePort.type + ## Options: NodePort, LoadBalancer + type: NodePort + ## @param p2pNodePort.startAt The ports allocation will start from this value + ## + startAt: 31100 + ## @param p2pNodePort.replicaToNodePort Overwrite a port for specific replicas + ## @default -- See `values.yaml` for example + replicaToNodePort: {} + # "0": 32345 + # "3": 32348 + +## Monitoring +## +metrics: + ## Prometheus exporter port + ## + port: 6060 + + ## Extra flags to pass for collecting metrics + ## + flags: + - "--metrics=0.0.0.0:6060" + + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + serviceMonitor: + ## The namespace in which the ServiceMonitor will be created + ## + namespace: "" + ## The interval at which metrics should be scraped + ## + interval: 30s + ## The timeout after which the scrape is ended + ## + scrapeTimeout: "" + ## Metrics RelabelConfigs to apply to samples before scraping. + ## + relabellings: [] + ## Metrics RelabelConfigs to apply to samples before ingestion. + ## + metricRelabelings: [] + ## Specify honorLabels parameter to add the scrape endpoint + ## + honorLabels: false + ## Additional labels that can be used so ServiceMonitor resource(s) can be discovered by Prometheus + ## + additionalLabels: {} + ## Custom PrometheusRule to be defined + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + ## + prometheusRule: + ## Create a default set of Alerts + ## + default: true + ## The namespace in which the prometheusRule will be created + ## + namespace: "" + ## Additional labels for the prometheusRule + ## + additionalLabels: {} + ## Custom Prometheus rules + ## + rules: [] + +## Configure resource requests and limits. +## http://kubernetes.io/docs/user-guide/compute-resources/ +## +resources: {} + +## If false, data ownership will not be reset at startup +## This allows the reth node to be run with an arbitrary user +## +initChownData: true + +## Whether or not to allocate persistent volume disk for the data directory. +## In case of node failure, the node data directory will still persist. +## +persistence: + enabled: true + storageClassName: "" + accessModes: + - ReadWriteOnce + size: 900Gi + annotations: {} + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: {} + +## Affinity for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +## Example: +## affinity: +## podAntiAffinity: +## requiredDuringSchedulingIgnoredDuringExecution: +## - labelSelector: +## matchExpressions: +## - key: app.kubernetes.io/name +## operator: In +## values: +## - reth +## topologyKey: kubernetes.io/hostname +## +affinity: {} + +## used to assign priority to pods +## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +## +priorityClassName: "" + +## Configure liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +## NB! readinessProbe and livenessProbe must be disabled before fully synced +## +livenessProbe: + initialDelaySeconds: 900 + timeoutSeconds: 3 + periodSeconds: 30 + failureThreshold: 3 + successThreshold: 1 + httpGet: + path: /eth1/liveness + port: sidecar + scheme: HTTP + +readinessProbe: + initialDelaySeconds: 30 + timeoutSeconds: 3 + periodSeconds: 30 + failureThreshold: 30 + successThreshold: 1 + httpGet: + path: /eth1/readiness + port: sidecar + scheme: HTTP