Skip to content

Commit b6b59d4

Browse files
authored
Add block explorer to net up --kubernetes (#4582)
## Motivation We're working on adding the Indexer/Explorer/Exporter into our deployments. ## Proposal This adds them to `linera net up --kubernetes` as a starting point. Next, adding to the actual GCP deployment. ## Test Plan Started a local k8s network, sent some transactions to it, and managed to see the information in the block explorer: ![Screenshot 2025-09-16 at 12.18.34.png](https://app.graphite.dev/user-attachments/assets/80cd3746-4f75-4d0b-aa5d-1daa900be025.png) ![Screenshot 2025-09-16 at 12.18.55.png](https://app.graphite.dev/user-attachments/assets/b765f25d-271e-47ad-987a-7691c5b5c755.png) ## Release Plan - Nothing to do / These changes follow the usual release cycle.
1 parent 6ca49e5 commit b6b59d4

File tree

16 files changed

+686
-118
lines changed

16 files changed

+686
-118
lines changed

CLI.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,9 @@ Start a Local Linera Network
12231223
* `--with-block-exporter` — Whether to start a block exporter for each validator
12241224

12251225
Default value: `false`
1226+
* `--num-block-exporters <NUM_BLOCK_EXPORTERS>` — The number of block exporters to start
1227+
1228+
Default value: `1`
12261229
* `--exporter-address <EXPORTER_ADDRESS>` — The address of the block exporter
12271230

12281231
Default value: `localhost`

docker/Dockerfile.indexer-test renamed to docker/Dockerfile.indexer

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ARG binaries=
2525
ARG copy=${binaries:+_copy}
2626
# ARG build_flag=--release
2727
ARG build_folder=debug
28-
ARG build_features=metrics
28+
ARG build_features=scylladb,metrics
2929
ARG rustflags="-C force-frame-pointers=yes"
3030

3131
FROM rust:1.74-slim-bookworm AS builder
@@ -63,7 +63,7 @@ COPY linera-persistent linera-persistent
6363
COPY linera-version linera-version
6464
COPY linera-views linera-views
6565
COPY linera-views-derive linera-views-derive
66-
COPY linera-web linera-web
66+
COPY web web
6767
COPY linera-witty linera-witty
6868
COPY linera-witty-macros linera-witty-macros
6969
COPY scripts scripts
@@ -73,22 +73,11 @@ ENV GIT_COMMIT=${git_commit}
7373
ENV RUSTFLAGS=${rustflags}
7474

7575

76-
# Build linera core binaries (no database features needed)
77-
RUN cargo build ${build_flag:+"$build_flag"} \
78-
--bin linera \
79-
--bin linera-proxy \
80-
--bin linera-server \
81-
--features $build_features
82-
83-
# Build storage service (memory storage, no database features)
84-
RUN cargo build ${build_flag:+"$build_flag"} \
85-
-p linera-storage-service
86-
87-
# Build block exporter with metrics feature only
76+
# Build block exporter with scylladb and metrics features
8877
RUN cargo build ${build_flag:+"$build_flag"} \
8978
-p linera-service \
9079
--bin linera-exporter \
91-
--features metrics
80+
--features $build_features
9281

9382
# Build indexer binaries (no scylladb needed for testing)
9483
RUN cargo build ${build_flag:+"$build_flag"} \
@@ -97,10 +86,6 @@ RUN cargo build ${build_flag:+"$build_flag"} \
9786

9887
# Move binaries to avoid directory conflicts and clean up to save space
9988
RUN mv \
100-
target/"$build_folder"/linera \
101-
target/"$build_folder"/linera-proxy \
102-
target/"$build_folder"/linera-server \
103-
target/"$build_folder"/linera-storage-server \
10489
target/"$build_folder"/linera-exporter \
10590
target/"$build_folder"/linera-indexer-grpc \
10691
./
@@ -109,10 +94,6 @@ RUN mv \
10994
FROM scratch AS builder_copy
11095
ARG binaries
11196
COPY \
112-
"$binaries"/linera \
113-
"$binaries"/linera-server \
114-
"$binaries"/linera-proxy \
115-
"$binaries"/linera-storage-server \
11697
"$binaries"/linera-exporter \
11798
"$binaries"/linera-indexer-grpc \
11899
./
@@ -140,12 +121,8 @@ RUN update-ca-certificates
140121

141122
ARG target
142123

143-
# Copy pre-built binaries for non-indexer services
124+
# Copy only indexer and exporter binaries
144125
COPY --from=binaries \
145-
linera \
146-
linera-proxy \
147-
linera-server \
148-
linera-storage-server \
149126
linera-indexer-grpc \
150127
linera-exporter \
151128
./
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
id = {{ .exporterId }}
2+
3+
metrics_port = {{ .Values.blockExporter.metricsPort }}
4+
5+
[service_config]
6+
host = "0.0.0.0"
7+
port = {{ .Values.blockExporter.port }}
8+
9+
[destination_config]
10+
committee_destination = true
11+
12+
[[destination_config.destinations]]
13+
file_name = "/data/linera-exporter.log"
14+
kind = "Logging"
15+
16+
[[destination_config.destinations]]
17+
kind = "Indexer"
18+
tls = "ClearText"
19+
port = {{ .Values.indexer.port }}
20+
endpoint = "linera-indexer"
21+
22+
[limits]
23+
persistence_period_ms = 299000
24+
work_queue_size = 256
25+
blob_cache_weight_mb = 1024
26+
blob_cache_items_capacity = 8192
27+
block_cache_weight_mb = 1024
28+
block_cache_items_capacity = 8192
29+
auxiliary_cache_size_mb = 1024
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{{- if .Values.blockExporter.enabled }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: block-exporter-config
6+
data:
7+
{{- range $i := until (int .Values.blockExporter.replicas) }}
8+
exporter-config-{{ $i }}.toml: |
9+
{{ tpl ($.Files.Get "exporter-config.toml.tpl") (dict "exporterId" $i "Values" $.Values) | indent 4 }}
10+
{{- end }}
11+
---
12+
apiVersion: v1
13+
kind: Service
14+
metadata:
15+
name: linera-block-exporter
16+
labels:
17+
app: linera-block-exporter
18+
spec:
19+
clusterIP: None
20+
ports:
21+
- port: {{ .Values.blockExporter.port }}
22+
name: http
23+
- port: {{ .Values.blockExporter.metricsPort }}
24+
name: metrics
25+
selector:
26+
app: linera-block-exporter
27+
---
28+
apiVersion: apps/v1
29+
kind: StatefulSet
30+
metadata:
31+
name: linera-block-exporter
32+
spec:
33+
serviceName: linera-block-exporter
34+
replicas: {{ .Values.blockExporter.replicas }}
35+
selector:
36+
matchLabels:
37+
app: linera-block-exporter
38+
template:
39+
metadata:
40+
labels:
41+
app: linera-block-exporter
42+
spec:
43+
{{- if eq .Values.environment "GCP" }}
44+
nodeSelector:
45+
workload: system
46+
tolerations:
47+
- key: system
48+
value: "true"
49+
effect: NoSchedule
50+
{{- end }}
51+
initContainers:
52+
- name: config-selector
53+
image: busybox
54+
command:
55+
- sh
56+
- -c
57+
- |
58+
ORDINAL=$(echo $HOSTNAME | sed 's/.*-//')
59+
cp /configmap/exporter-config-${ORDINAL}.toml /config/exporter-config.toml
60+
volumeMounts:
61+
- name: configmap
62+
mountPath: /configmap
63+
- name: config
64+
mountPath: /config
65+
containers:
66+
- name: linera-block-exporter
67+
image: {{ .Values.indexer.image }}
68+
imagePullPolicy: {{ .Values.indexer.imagePullPolicy }}
69+
command:
70+
- "./linera-exporter"
71+
- "--storage"
72+
- "{{ .Values.storage }}"
73+
- "--config-path"
74+
- "/config/exporter-config.toml"
75+
- "--metrics-port"
76+
- "{{ .Values.blockExporter.metricsPort }}"
77+
ports:
78+
- containerPort: {{ .Values.blockExporter.port }}
79+
name: http
80+
- containerPort: {{ .Values.blockExporter.metricsPort }}
81+
name: metrics
82+
env:
83+
- name: RUST_LOG
84+
value: {{ .Values.blockExporter.logLevel }}
85+
- name: RUST_BACKTRACE
86+
value: "1"
87+
volumeMounts:
88+
- name: config
89+
mountPath: /config
90+
readOnly: true
91+
- name: exporter-data
92+
mountPath: /data
93+
livenessProbe:
94+
tcpSocket:
95+
port: {{ .Values.blockExporter.port }}
96+
initialDelaySeconds: 30
97+
periodSeconds: 10
98+
readinessProbe:
99+
tcpSocket:
100+
port: {{ .Values.blockExporter.port }}
101+
initialDelaySeconds: 5
102+
periodSeconds: 5
103+
volumes:
104+
- name: configmap
105+
configMap:
106+
name: block-exporter-config
107+
- name: config
108+
emptyDir: {}
109+
- name: exporter-data
110+
persistentVolumeClaim:
111+
claimName: exporter-data
112+
---
113+
apiVersion: v1
114+
kind: PersistentVolumeClaim
115+
metadata:
116+
name: exporter-data
117+
spec:
118+
accessModes:
119+
- ReadWriteOnce
120+
resources:
121+
requests:
122+
storage: {{ .Values.blockExporter.storageSize }}
123+
{{- if .Values.blockExporter.serviceMonitor.enabled }}
124+
---
125+
apiVersion: monitoring.coreos.com/v1
126+
kind: ServiceMonitor
127+
metadata:
128+
name: linera-block-exporter
129+
labels:
130+
app: linera-block-exporter
131+
spec:
132+
selector:
133+
matchLabels:
134+
app: linera-block-exporter
135+
endpoints:
136+
- port: metrics
137+
path: /metrics
138+
{{- end }}
139+
{{- end }}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{{- if .Values.explorer.enabled }}
2+
apiVersion: v1
3+
kind: Service
4+
metadata:
5+
name: linera-explorer
6+
labels:
7+
app: linera-explorer
8+
spec:
9+
ports:
10+
- port: {{ .Values.explorer.frontendPort }}
11+
name: frontend
12+
- port: {{ .Values.explorer.apiPort }}
13+
name: api
14+
selector:
15+
app: linera-explorer
16+
---
17+
apiVersion: apps/v1
18+
kind: Deployment
19+
metadata:
20+
name: linera-explorer
21+
spec:
22+
replicas: 1
23+
selector:
24+
matchLabels:
25+
app: linera-explorer
26+
template:
27+
metadata:
28+
labels:
29+
app: linera-explorer
30+
spec:
31+
{{- if eq .Values.environment "GCP" }}
32+
nodeSelector:
33+
workload: system
34+
tolerations:
35+
- key: system
36+
value: "true"
37+
effect: NoSchedule
38+
{{- end }}
39+
containers:
40+
- name: linera-explorer
41+
image: {{ .Values.explorer.image }}
42+
imagePullPolicy: {{ .Values.explorer.imagePullPolicy }}
43+
ports:
44+
- containerPort: {{ .Values.explorer.frontendPort }}
45+
name: frontend
46+
- containerPort: {{ .Values.explorer.apiPort }}
47+
name: api
48+
env:
49+
- name: NODE_ENV
50+
value: "production"
51+
- name: DB_PATH
52+
value: "/data/indexer.db"
53+
- name: EXPLORER_FRONTEND_PORT
54+
value: "{{ .Values.explorer.frontendPort }}"
55+
- name: EXPLORER_API_PORT
56+
value: "{{ .Values.explorer.apiPort }}"
57+
- name: LOG_LEVEL
58+
value: {{ .Values.explorer.logLevel }}
59+
volumeMounts:
60+
- name: indexer-data
61+
mountPath: /data
62+
readOnly: true
63+
livenessProbe:
64+
httpGet:
65+
path: /api/health
66+
port: {{ .Values.explorer.apiPort }}
67+
initialDelaySeconds: 30
68+
periodSeconds: 30
69+
readinessProbe:
70+
httpGet:
71+
path: /api/health
72+
port: {{ .Values.explorer.apiPort }}
73+
initialDelaySeconds: 10
74+
periodSeconds: 10
75+
volumes:
76+
- name: indexer-data
77+
persistentVolumeClaim:
78+
claimName: indexer-data
79+
{{- if .Values.explorer.ingress.enabled }}
80+
---
81+
apiVersion: networking.k8s.io/v1
82+
kind: Ingress
83+
metadata:
84+
name: linera-explorer
85+
labels:
86+
app: linera-explorer
87+
{{- with .Values.explorer.ingress.annotations }}
88+
annotations:
89+
{{- toYaml . | nindent 4 }}
90+
{{- end }}
91+
spec:
92+
{{- if .Values.explorer.ingress.tls }}
93+
tls:
94+
{{- range .Values.explorer.ingress.tls }}
95+
- hosts:
96+
{{- range .hosts }}
97+
- {{ . | quote }}
98+
{{- end }}
99+
secretName: {{ .secretName }}
100+
{{- end }}
101+
{{- end }}
102+
rules:
103+
{{- range .Values.explorer.ingress.hosts }}
104+
- host: {{ .host | quote }}
105+
http:
106+
paths:
107+
{{- range .paths }}
108+
- path: {{ .path }}
109+
pathType: {{ .pathType }}
110+
backend:
111+
service:
112+
name: linera-explorer
113+
port:
114+
number: {{ $.Values.explorer.frontendPort }}
115+
{{- end }}
116+
{{- end }}
117+
{{- end }}
118+
{{- end }}

0 commit comments

Comments
 (0)