Skip to content

Commit 85641be

Browse files
feat(chart): add external node ha mode (#27)
* feat(chart): add external node ha mode * bump chart
1 parent 37dfaf6 commit 85641be

8 files changed

Lines changed: 458 additions & 45 deletions

File tree

‎charts/abstract-node/Chart.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: v2
22
name: abstract-node
33
description: External node for syncing and serving blockchain data for Abstract
4-
version: 0.1.39
4+
version: 0.1.40
55
type: application
66
icon: https://abstract-assets.abs.xyz/icons/light.png
77
keywords:

‎charts/abstract-node/templates/_helpers.tpl‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,84 @@ Create the name of the service account to use
6060
{{- default "default" .Values.serviceAccount.name }}
6161
{{- end }}
6262
{{- end }}
63+
64+
{{/*
65+
HA core StatefulSet / governing service name.
66+
*/}}
67+
{{- define "abstract-node.haCoreName" -}}
68+
{{- $name := include "common.names.fullname" . | trunc 58 | trimSuffix "-" -}}
69+
{{- printf "%s-core" $name -}}
70+
{{- end }}
71+
72+
{{/*
73+
HA API Deployment name.
74+
*/}}
75+
{{- define "abstract-node.haApiName" -}}
76+
{{- $name := include "common.names.fullname" . | trunc 59 | trimSuffix "-" -}}
77+
{{- printf "%s-api" $name -}}
78+
{{- end }}
79+
80+
{{/*
81+
Default HA core components. The tree API is included by default so API replicas can
82+
proxy proof requests to the singleton tree.
83+
*/}}
84+
{{- define "abstract-node.haCoreComponents" -}}
85+
{{- if .Values.ha.core.components -}}
86+
{{- .Values.ha.core.components -}}
87+
{{- else if .Values.ha.treeApi.enabled -}}
88+
core,tree,tree_fetcher,tree_api
89+
{{- else -}}
90+
core,tree,tree_fetcher
91+
{{- end -}}
92+
{{- end }}
93+
94+
{{/*
95+
Default HA API components.
96+
*/}}
97+
{{- define "abstract-node.haApiComponents" -}}
98+
{{- default "api" .Values.ha.api.components -}}
99+
{{- end }}
100+
101+
{{/*
102+
Render external node command / args, preserving the existing shutdown wrapper behavior.
103+
*/}}
104+
{{- define "abstract-node.nodeArgs" -}}
105+
{{- $root := .root -}}
106+
{{- $args := default (list) .args -}}
107+
{{- if $root.Values.shutdownWrapper.enabled }}
108+
command:
109+
- /bin/sh
110+
- -ec
111+
args:
112+
- |
113+
set -eu
114+
115+
child=0
116+
117+
forward_int() {
118+
if [ "$child" -ne 0 ]; then
119+
echo "Forwarding SIGINT to child process ${child}"
120+
kill -INT "$child" 2>/dev/null || true
121+
fi
122+
}
123+
124+
trap 'forward_int' TERM
125+
trap 'forward_int' INT
126+
127+
/usr/bin/entrypoint.sh "$@" &
128+
child=$!
129+
130+
status=0
131+
wait "$child" || status=$?
132+
exit "$status"
133+
- wrapper
134+
{{- range $args }}
135+
- {{ . | quote }}
136+
{{- end }}
137+
{{- else if $args }}
138+
args:
139+
{{- range $args }}
140+
- {{ . | quote }}
141+
{{- end }}
142+
{{- end }}
143+
{{- end }}
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
{{- if .Values.ha.enabled }}
2+
---
3+
apiVersion: apps/v1
4+
kind: Deployment
5+
metadata:
6+
name: {{ include "abstract-node.haApiName" . }}
7+
labels:
8+
{{- include "common.labels.standard" . | nindent 4 }}
9+
app.kubernetes.io/component: api
10+
spec:
11+
replicas: {{ .Values.ha.api.replicaCount }}
12+
selector:
13+
matchLabels:
14+
{{- include "common.labels.matchLabels" . | nindent 6 }}
15+
app.kubernetes.io/component: api
16+
template:
17+
metadata:
18+
labels:
19+
{{- include "common.labels.matchLabels" . | nindent 8 }}
20+
app.kubernetes.io/component: api
21+
{{- with .Values.podAnnotations }}
22+
annotations:
23+
{{- toYaml . | nindent 8 }}
24+
{{- end }}
25+
spec:
26+
{{- with (concat .Values.imagePullSecrets .Values.global.imagePullSecrets) }}
27+
imagePullSecrets:
28+
{{- toYaml . | nindent 8 }}
29+
{{- end }}
30+
{{- with .Values.affinity }}
31+
affinity:
32+
{{ toYaml . | nindent 8 | trim }}
33+
{{- end }}
34+
{{- with .Values.tolerations }}
35+
tolerations:
36+
{{ toYaml . | nindent 8 | trim }}
37+
{{- end }}
38+
{{- with .Values.nodeSelector }}
39+
nodeSelector:
40+
{{ toYaml . | nindent 8 | trim }}
41+
{{- end }}
42+
{{- with .Values.securityContext }}
43+
securityContext:
44+
{{ toYaml . | nindent 8 | trim }}
45+
{{- end }}
46+
{{- if .Values.terminationGracePeriodSeconds }}
47+
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
48+
{{- end }}
49+
serviceAccountName: {{ include "common.names.serviceAccountName" . }}
50+
priorityClassName: {{ .Values.priorityClassName | quote }}
51+
containers:
52+
- name: {{ .Chart.Name }}
53+
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
54+
imagePullPolicy: {{ .Values.image.pullPolicy }}
55+
{{- $apiArgs := concat (list (printf "--components=%s" (include "abstract-node.haApiComponents" .))) .Values.ha.api.extraArgs }}
56+
{{ include "abstract-node.nodeArgs" (dict "root" . "args" $apiArgs) | nindent 10 }}
57+
env:
58+
- name: POD_IP
59+
valueFrom:
60+
fieldRef:
61+
fieldPath: status.podIP
62+
- name: DATABASE_URL
63+
valueFrom:
64+
secretKeyRef:
65+
{{- if .Values.cnpg.enabled }}
66+
name: {{ include "cnpg.clusterName" . }}-app
67+
{{- else }}
68+
name: {{ .Values.database.secretName }}
69+
{{- end }}
70+
key: {{ .Values.database.secretKey }}
71+
optional: false
72+
- name: EN_GAS_PRICE_SCALE_FACTOR
73+
value: "1.5"
74+
- name: EN_ESTIMATE_GAS_SCALE_FACTOR
75+
value: "1.3"
76+
- name: EN_ESTIMATE_GAS_ACCEPTABLE_OVERESTIMATION
77+
value: "5000"
78+
- name: DATABASE_POOL_SIZE
79+
value: {{ .Values.database.poolSize | quote }}
80+
- name: EN_HTTP_PORT
81+
value: {{ .Values.rpc.http.port | quote }}
82+
- name: EN_WS_PORT
83+
value: {{ .Values.rpc.ws.port | quote }}
84+
- name: EN_HEALTHCHECK_PORT
85+
value: {{ .Values.healthcheck.port | quote }}
86+
- name: EN_PROMETHEUS_PORT
87+
value: {{ .Values.metrics.port | quote }}
88+
- name: EN_ETH_CLIENT_URL
89+
value: {{ .Values.node.ethClientUrl | quote }}
90+
- name: EN_MAIN_NODE_URL
91+
value: {{ .Values.node.mainnetUrl | quote }}
92+
- name: EN_L1_CHAIN_ID
93+
value: {{ .Values.node.l1ChainId | quote }}
94+
- name: EN_L2_CHAIN_ID
95+
value: {{ .Values.node.l2ChainId | quote }}
96+
- name: EN_STATE_CACHE_PATH
97+
value: "./db/ext-node/state_keeper"
98+
- name: EN_MERKLE_TREE_PATH
99+
value: "./db/ext-node/lightweight"
100+
- name: EN_PRUNING_ENABLED
101+
value: {{ .Values.node.pruningEnabled | quote }}
102+
- name: EN_SNAPSHOTS_RECOVERY_ENABLED
103+
value: {{ .Values.node.snapshotRecoveryEnabled | quote }}
104+
- name: EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL
105+
value: {{ .Values.node.snapshotBucket | quote }}
106+
- name: EN_SNAPSHOTS_OBJECT_STORE_MODE
107+
value: "GCSAnonymousReadOnly"
108+
- name: RUST_LOG
109+
value: "warn,zksync=info,zksync_web3_decl::client=error"
110+
- name: EN_API_NAMESPACES
111+
value: {{ .Values.rpc.api | quote }}
112+
{{- if or .Values.ha.treeApi.enabled .Values.ha.api.treeApiUrl }}
113+
{{- $treeApiUrl := default (printf "http://%s:%s" (include "abstract-node.haCoreName" .) (.Values.ha.treeApi.port | toString)) .Values.ha.api.treeApiUrl }}
114+
- name: EN_API_TREE_API_REMOTE_URL
115+
value: {{ $treeApiUrl | quote }}
116+
- name: EN_API_WEB3_JSON_RPC_TREE_API_REQUEST_TIMEOUT_SEC
117+
value: {{ .Values.ha.treeApi.requestTimeoutSec | quote }}
118+
{{- end }}
119+
{{- if .Values.rpc.maxResponseBodySizeMb }}
120+
- name: EN_MAX_RESPONSE_BODY_SIZE_MB
121+
value: {{ .Values.rpc.maxResponseBodySizeMb | quote }}
122+
{{- end }}
123+
{{- if .Values.database.poolSizeMaster }}
124+
- name: EN_DATABASE_MAX_CONNECTIONS_MASTER
125+
value: {{ .Values.database.poolSizeMaster | quote }}
126+
{{- end }}
127+
{{- if .Values.node.batchCommitDataGeneratorMode }}
128+
- name: EN_L1_BATCH_COMMIT_DATA_GENERATOR_MODE
129+
value: {{ .Values.node.batchCommitDataGeneratorMode | quote }}
130+
{{- end }}
131+
{{- if .Values.node.daClient }}
132+
- name: EN_DA_CLIENT
133+
value: {{ .Values.node.daClient | quote }}
134+
{{- end }}
135+
{{- if and .Values.node.daClient .Values.node.daClientType }}
136+
- name: "EN_DA_{{ .Values.node.daClient | upper }}_CLIENT_TYPE"
137+
value: {{ .Values.node.daClientType | quote }}
138+
{{- end }}
139+
{{- if .Values.node.daBridgeApiUrl }}
140+
- name: EN_DA_BRIDGE_API_URL
141+
value: {{ .Values.node.daBridgeApiUrl | quote }}
142+
{{- end }}
143+
{{- if .Values.node.daTimeoutMs }}
144+
- name: EN_DA_TIMEOUT_MS
145+
value: {{ .Values.node.daTimeoutMs | quote }}
146+
{{- end }}
147+
{{- if .Values.node.daApiNodeUrl }}
148+
- name: EN_DA_API_NODE_URL
149+
value: {{ .Values.node.daApiNodeUrl | quote }}
150+
{{- end }}
151+
{{- if .Values.node.daAppId }}
152+
- name: EN_DA_APP_ID
153+
value: {{ .Values.node.daAppId | quote }}
154+
{{- end }}
155+
{{- if .Values.node.daSecretsSeedPhrase }}
156+
- name: EN_DA_SECRETS_SEED_PHRASE
157+
value: {{ .Values.node.daSecretsSeedPhrase | quote }}
158+
{{- end }}
159+
{{- if .Values.node.experimentalSnapshotsRecoveryL1Batch }}
160+
- name: EN_EXPERIMENTAL_SNAPSHOTS_RECOVERY_L1_BATCH
161+
value: {{ .Values.node.experimentalSnapshotsRecoveryL1Batch | quote }}
162+
{{- end }}
163+
{{- if .Values.node.statekeeper.l2BlockCommitDeadline }}
164+
- name: EN_STATE_KEEPER_L2_BLOCK_COMMIT_DEADLINE
165+
value: {{ .Values.node.statekeeper.l2BlockCommitDeadline | quote }}
166+
{{- end }}
167+
{{- if .Values.rpc.sendRawTxSyncMaxTimeout }}
168+
- name: EN_API_SEND_RAW_TX_SYNC_MAX_TIMEOUT_MS
169+
value: {{ .Values.rpc.sendRawTxSyncMaxTimeout | quote }}
170+
{{- end }}
171+
{{- if .Values.rpc.sendRawTxSyncDefaultTimeout }}
172+
- name: EN_API_SEND_RAW_TX_SYNC_DEFAULT_TIMEOUT_MS
173+
value: {{ .Values.rpc.sendRawTxSyncDefaultTimeout | quote }}
174+
{{- end }}
175+
{{- range $name, $value := .Values.node.extraEnv }}
176+
- name: {{ $name | quote }}
177+
value: {{ $value | quote }}
178+
{{- end }}
179+
ports:
180+
{{- if .Values.rpc.http.enabled }}
181+
- name: http
182+
containerPort: {{ .Values.rpc.http.port }}
183+
{{- end }}
184+
{{- if .Values.rpc.ws.enabled }}
185+
- name: ws
186+
containerPort: {{ .Values.rpc.ws.port }}
187+
{{- end }}
188+
{{- if or .Values.global.metrics.enabled .Values.metrics.enabled }}
189+
- name: metrics
190+
containerPort: {{ .Values.metrics.port }}
191+
{{- end }}
192+
{{- if .Values.healthcheck.enabled }}
193+
- name: healthcheck
194+
containerPort: {{ .Values.healthcheck.port }}
195+
{{- end }}
196+
{{- with .Values.resources }}
197+
resources:
198+
{{ toYaml . | nindent 12 | trim }}
199+
{{- end }}
200+
{{- if .Values.rpc.http.enabled }}
201+
- name: sidecar
202+
image: "{{ .Values.sidecar.registry }}/{{ .Values.sidecar.repository }}:{{ .Values.sidecar.tag }}"
203+
imagePullPolicy: {{ .Values.sidecar.pullPolicy }}
204+
env:
205+
- name: SERVER_BINDADDR
206+
value: "{{ .Values.sidecar.bindAddr }}:{{ .Values.sidecar.bindPort }}"
207+
- name: CLIENT_RPCPORT
208+
value: {{ .Values.rpc.http.port | quote }}
209+
- name: CLIENT_HEALTHPORT
210+
value: {{ .Values.healthcheck.port | quote }}
211+
- name: CLIENT_SCHEME
212+
value: "http"
213+
- name: CLIENT_HOST
214+
value: "127.0.0.1"
215+
ports:
216+
- containerPort: {{ .Values.sidecar.bindPort }}
217+
name: sidecar
218+
protocol: TCP
219+
{{- if or .Values.global.livenessProbe.enabled .Values.livenessProbe.enabled }}
220+
livenessProbe:
221+
initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
222+
timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
223+
periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
224+
failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
225+
successThreshold: {{ .Values.livenessProbe.successThreshold }}
226+
httpGet:
227+
path: {{ .Values.livenessProbe.httpGet.path }}
228+
port: {{ .Values.livenessProbe.httpGet.port }}
229+
scheme: {{ .Values.livenessProbe.httpGet.scheme }}
230+
{{- end }}
231+
{{- if or .Values.global.readinessProbe.enabled .Values.readinessProbe.enabled }}
232+
readinessProbe:
233+
initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
234+
timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
235+
periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
236+
failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
237+
successThreshold: {{ .Values.readinessProbe.successThreshold }}
238+
httpGet:
239+
path: {{ .Values.readinessProbe.httpGet.path }}
240+
port: {{ .Values.readinessProbe.httpGet.port }}
241+
scheme: {{ .Values.readinessProbe.httpGet.scheme }}
242+
{{- end }}
243+
{{- end }}
244+
{{- end }}

‎charts/abstract-node/templates/pdb.yaml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ spec:
1515
selector:
1616
matchLabels:
1717
{{- include "common.labels.matchLabels" . | nindent 6 }}
18-
{{- end }}
18+
{{- if .Values.ha.enabled }}
19+
app.kubernetes.io/component: api
20+
{{- end }}
21+
{{- end }}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- if .Values.ha.enabled }}
2+
---
3+
apiVersion: v1
4+
kind: Service
5+
metadata:
6+
name: {{ include "abstract-node.haCoreName" . }}
7+
labels:
8+
{{- include "common.labels.standard" . | nindent 4 }}
9+
app.kubernetes.io/component: core
10+
spec:
11+
clusterIP: None
12+
type: ClusterIP
13+
ports:
14+
{{- if .Values.global.metrics.enabled }}
15+
- name: metrics
16+
port: {{ .Values.metrics.port }}
17+
targetPort: metrics
18+
{{- end }}
19+
{{- if .Values.healthcheck.enabled }}
20+
- name: healthcheck
21+
port: {{ .Values.healthcheck.port }}
22+
targetPort: healthcheck
23+
{{- end }}
24+
{{- if .Values.ha.treeApi.enabled }}
25+
- name: tree-api
26+
port: {{ .Values.ha.treeApi.port }}
27+
targetPort: tree-api
28+
{{- end }}
29+
{{- if .Values.consensus.enabled }}
30+
- name: consensus
31+
port: {{ .Values.consensus.port }}
32+
targetPort: consensus
33+
- name: debug-page
34+
port: {{ .Values.consensus.debugPagePort }}
35+
targetPort: debug-page
36+
{{- end }}
37+
selector:
38+
{{- include "common.labels.matchLabels" . | nindent 4 }}
39+
app.kubernetes.io/component: core
40+
{{- end }}

0 commit comments

Comments
 (0)