diff --git a/.gitignore b/.gitignore index 448aae9..25d881c 100644 --- a/.gitignore +++ b/.gitignore @@ -194,3 +194,4 @@ $RECYCLE.BIN/ # End of https://www.toptal.com/developers/gitignore/api/helm,linux,macos,windows,intellij +.idea diff --git a/charts/celestia-node/templates/NOTES.txt b/charts/celestia-node/templates/NOTES.txt index 153ac35..8c9c171 100644 --- a/charts/celestia-node/templates/NOTES.txt +++ b/charts/celestia-node/templates/NOTES.txt @@ -29,3 +29,4 @@ In order to replicate the container startup scripts execute this command: {{- end }} {{- include "common.warnings.rollingTag" .Values.node.image }} +{{- include "node.validateValues" . }} diff --git a/charts/celestia-node/templates/_helpers.tpl b/charts/celestia-node/templates/_helpers.tpl index 9cac366..7bb166b 100644 --- a/charts/celestia-node/templates/_helpers.tpl +++ b/charts/celestia-node/templates/_helpers.tpl @@ -30,7 +30,6 @@ Create the name of the service account to use {{- end -}} {{- end -}} - {{/* Return the proper image name for the otel agent */}} @@ -38,19 +37,33 @@ Return the proper image name for the otel agent {{- include "common.images.image" (dict "imageRoot" .Values.node.otelAgent.image "global" .Values.global) -}} {{- end -}} +{{/* +Validate the node.settings.nodeType value against the first argument in node.args. +*/}} +{{- define "node.validateValues.nodeType" -}} +{{- if not (hasKey .Values.node.settings "nodeType") -}} +Node type is not set. Must be one of 'bridge', 'full', or 'light'. +{{- else if and (ne .Values.node.settings.nodeType "bridge") (ne .Values.node.settings.nodeType "full") (ne .Values.node.settings.nodeType "light") -}} +Invalid node type: {{ .Values.node.settings.nodeType }}. Must be one of 'bridge', 'full', or 'light'. +{{- else if not (hasKey .Values.node "args") -}} +Node args are not set. +{{- else if not (eq .Values.node.settings.nodeType (first .Values.node.args)) -}} +The nodeType value ({{ .Values.node.settings.nodeType }}) does not match the first argument in args ({{ first .Values.node.args }}). +{{- end -}} +{{- end -}} + # TODO: add validations for values # Remember to add the validation message to NOTES.txt at the end ({{- include "node.validateValues" . }}) {{/* -Compile all warnings into a single message. +Compile all warnings into a single message and fail the deployment if there are any. */}} {{- define "node.validateValues" -}} {{- $messages := list -}} -{{- $messages := append $messages (include "node.validateValues.foo" .) -}} -{{- $messages := append $messages (include "node.validateValues.bar" .) -}} +{{- $messages := append $messages (include "node.validateValues.nodeType" .) -}} {{- $messages := without $messages "" -}} {{- $message := join "\n" $messages -}} {{- if $message -}} -{{- printf "\nVALUES VALIDATION:\n%s" $message -}} +{{- fail (printf "\nVALUES VALIDATION:\n%s" $message) -}} {{- end -}} {{- end -}} diff --git a/charts/celestia-node/templates/statefulset.yaml b/charts/celestia-node/templates/statefulset.yaml index edd65cf..e56b8d4 100644 --- a/charts/celestia-node/templates/statefulset.yaml +++ b/charts/celestia-node/templates/statefulset.yaml @@ -188,14 +188,18 @@ spec: ports: - name: p2p-tcp containerPort: {{ .Values.node.containerPorts.p2p }} + hostPort: {{ .Values.node.containerPorts.p2p }} protocol: TCP - name: p2p-udp containerPort: {{ .Values.node.containerPorts.p2p }} + hostPort: {{ .Values.node.containerPorts.p2p }} protocol: UDP - name: rest containerPort: {{ .Values.node.containerPorts.rest }} + hostPort: {{ .Values.node.containerPorts.rest }} - name: rpc containerPort: {{ .Values.node.containerPorts.rpc }} + hostPort: {{ .Values.node.containerPorts.rpc }} - name: profiling containerPort: {{ .Values.node.containerPorts.profiling }} - name: prometheus @@ -211,16 +215,22 @@ spec: {{- if .Values.node.customReadinessProbe }} readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.node.customReadinessProbe "context" $) | nindent 12 }} {{- else if .Values.node.readinessProbe.enabled }} - readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.node.readinessProbe "enabled") "context" $) | nindent 12 }} + {{- if or (eq .Values.node.settings.nodeType "bridge") (eq .Values.node.settings.nodeType "full") (eq .Values.node.settings.nodeType "light") }} + readinessProbe: exec: command: - sh - '-c' - > AUTH_TOKEN=$(celestia bridge auth read --node.store=/home/celestia 2>/dev/null); + {{- if eq .Values.node.settings.nodeType "bridge" }} + curl --max-time 0.5 -s -X POST -H "Content-type: application/json" -H "Accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -d '{"id":1,"jsonrpc":"2.0","method":"header.SyncWait","params":[]}' "http://localhost:26658"; + {{- else if or (eq .Values.node.settings.nodeType "full") (eq .Values.node.settings.nodeType "light") }} curl --max-time 0.5 -s -X POST -H "Content-type: application/json" -H "Accept: application/json" -H "Authorization: Bearer $AUTH_TOKEN" -d '{"id":1,"jsonrpc":"2.0","method":"das.WaitCatchUp","params":[]}' "http://localhost:26658"; + {{- end }} if [ "$?" -eq 0 ]; then exit 0; else echo "Catching up"; exit 1; fi {{- end }} + {{- end }} {{- if .Values.node.customStartupProbe }} startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.node.customStartupProbe "context" $) | nindent 12 }} {{- else if .Values.node.startupProbe.enabled }} diff --git a/charts/celestia-node/values.yaml b/charts/celestia-node/values.yaml index ae77b55..d01a04b 100644 --- a/charts/celestia-node/values.yaml +++ b/charts/celestia-node/values.yaml @@ -108,6 +108,12 @@ node: pullSecrets: [] ## @param node.settings Settings for the celestia-node settings: + ## Select from: bridge, full, light + ## Valid values: + ## - bridge + ## - full + ## - light: + nodeType: bridge ## @param node.settings.home Home directory for the celestia-node ## # -- home directory for the celestia-node, defaults to /home/celestia @@ -252,17 +258,16 @@ node: ## @param volumePermissions.resourcesPreset Set init container resources according to one common preset (allowed values: none, nano, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 ## - resourcesPreset: "micro" + #resourcesPreset: "micro" ## @param volumePermissions.resources Set init container resources for the otel agent (essential for production workloads) ## Example: - ## resources: - ## requests: - ## cpu: 100m - ## memory: 100Mi - ## limits: - ## cpu: 200m - ## memory: 200Mi - resources: {} + resources: + requests: + cpu: 100m + memory: 100Mi + #limits: + #cpu: 200m + #memory: 200Mi ## A secret must be available in the cluster with the following format: ## - name: ## - items: @@ -368,7 +373,7 @@ node: ## readinessProbe: # -- enable readiness probe on node containers, false by default - enabled: false + enabled: true # -- initial delay seconds for readinessProbe, 0 by default initialDelaySeconds: 0 # -- period seconds for readinessProbe, 10 by default @@ -436,7 +441,7 @@ node: # -- limits for the node limits: # -- cpu limits for the node, 2 by default - cpu: 6 + #cpu: 6 # -- memory limits for the node, 8Gi by default memory: 16Gi ## Configure Pods Security Context @@ -723,9 +728,9 @@ service: prometheus: 8890 ## @param service.internal.clusterIP node internal service Cluster IP ## e.g.: - ## clusterIP: None + ## clusterIP: None # We use headless mode by default for stateful workloads. ## - clusterIP: "" + clusterIP: "None" ## @param service.internal.annotations Additional custom annotations for node internal service ## annotations: {} @@ -749,8 +754,8 @@ service: enabled: true ## @param service.external.type node external service type ## - # -- external service type, LoadBalancer by default - type: LoadBalancer + # -- external service type, ClusterIP by default + type: ClusterIP ## @param service.external.ports.p2p Node external service P2P port ## @param service.external.ports.rest Node external service REST port ## @param service.external.ports.rpc Node external service RPC port @@ -787,6 +792,13 @@ service: ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer ## loadBalancerIP: "" + ## @param service.internal.clusterIP node internal service Cluster IP + ## e.g.: + ## clusterIP: None # We use headless mode by default for stateful workloads. + ## + clusterIP: "None" + ## @param service.internal.annotations Additional custom annotations for node internal service + ## ## @param service.external.loadBalancerSourceRanges node external service Load Balancer sources ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service ## e.g: diff --git a/examples/celestia-node/arabica-bridge.yaml b/examples/celestia-node/arabica-bridge.yaml new file mode 100644 index 0000000..020a35c --- /dev/null +++ b/examples/celestia-node/arabica-bridge.yaml @@ -0,0 +1,79 @@ +commonLabels: &commonLabels + chain_id: arabica-11 + environment: arabica + network: da + type: &nodeType bridge # check + secretName: &secretName keys-da-bridge-1 # check + pool: &pool pool-da-0 # check pool instance type to validate requests & limits +service: + external: + annotations: + external-dns.alpha.kubernetes.io/endpoints-type: "NodeExternalIP" + external-dns.alpha.kubernetes.io/hostname: "hc-bridge.celestia-arabica-11.com" + external-dns.alpha.kubernetes.io/ttl: "60" +persistence: + size: 750Gi + dataSource: + apiGroup: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: da-latest +node: + nodeSelector: + k8s.scaleway.com/pool-name: *pool + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Retain + otelAgent: + enabled: true + grafanaOtelSecret: + name: grafana-otel-token + resources: + requests: + cpu: 2 + memory: 4Gi + limits: + #cpu: 4 # not required since this pod should run on it's own dedicated node + memory: 10Gi + livenessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 30 + startupProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 60 + args: + - *nodeType + - start + - --p2p.network=arabica-11 + - --node.store=$(CELESTIA_HOME) + - --metrics + - --metrics.tls=false + - --p2p.metrics + settings: + nodeType: *nodeType + address: "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjcmVhdGVkIjoiMjAyNC0wMS0wMiAxMjo1NzoyMC4yNjk1Mjg2NTQgKzAwMDAgVVRDIG09KzAuMDQwNDkyNDk0IiwiZW5jIjoiQTI1NkdDTSIsInAyYyI6ODE5MiwicDJzIjoibHBUb0pLUkFvS3NPbmRhaCJ9.SFen5RaM_7JverpZQN6VxtJ06XePE5VKjyzMyIPgqURSge-XbiLHqA.vZ4fuVFbrLODe8RM.EGKwO3uGEifnPanziF-AD4i6q_92IetSVAEz-7Grg75AJyFLV3Flt4CmfLxrJ2JHWJEKUQBNyIU81u7pd01iNzEECDy9b0jO3DYZ_5PRET8zrVPv6SKKZ_U7MLWmAe_eUajipnbqZ6NzG8UcG4qAt278ttZB1KQsKqocKlE39fSvo3iaZEzOKxS0N3tU1Xw2C3w6HgHJFk0QiP36NIHuKoP_4QJkeAomhJX-cNOYwvTd8qTFTk2-1TzLJ5DasLXsVXTUSUzCzYQhEfL8F0qFoGvuY1dWRD5BESw2Gg2oLH1w957Xd2UhRbo5ORz9POR7goEv9AZ_rWrjSV8HozUmgFwDQyM89M7oiNedEfGQoDjypzcUBcVkZLEMIdrFRpshjcpNEzy6-PZ9rSxouKb7wemG_sueX3V3gIPCTfFr6hB8_b2mV-kKeIXQRS5pJz_wXxeFHFKOHDjt3L8n5eqh.fy-zygX7rjTUqgX02sZKKg" + node_id: "92a499fc2ce7cabd2de89416aa0d0d07838f625d" + secret: + name: *secretName + config: + configtoml: + Core: + IP: consensus-validator + RPC: + Enabled: true + Address: 0.0.0.0 + Gateway: + Enabled: true + Address: 0.0.0.0 + Node: + StartupTimeout: 2m +diagnosticMode: + enabled: false +networkPolicy: + enabled: false + \ No newline at end of file diff --git a/examples/celestia-node/arabica-full.yaml b/examples/celestia-node/arabica-full.yaml new file mode 100644 index 0000000..58f714a --- /dev/null +++ b/examples/celestia-node/arabica-full.yaml @@ -0,0 +1,75 @@ +commonLabels: + chain_id: arabica-11 + environment: arabica + network: da + type: &nodeType full # check + pool: &pool pool-da-0 # check +service: + external: + annotations: + external-dns.alpha.kubernetes.io/endpoints-type: "NodeExternalIP" + external-dns.alpha.kubernetes.io/hostname: "hc-da-full-1.celestia-arabica-11.com" + external-dns.alpha.kubernetes.io/ttl: "60" +persistence: + size: 1000Gi + dataSource: + apiGroup: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: da-latest +node: + nodeSelector: + k8s.scaleway.com/pool-name: *pool + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Retain + otelAgent: + enabled: true + grafanaOtelSecret: + name: grafana-otel-token + resources: + requests: + cpu: 3 + memory: 15Gi + limits: + cpu: 6 + memory: 24Gi + livenessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 30 + startupProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 60 + args: + - *nodeType # check + - start + - --p2p.network=arabica-11 + - --node.store=$(CELESTIA_HOME) + - --metrics + - --metrics.tls=false + - --p2p.metrics + settings: + nodeType: full # check + address: "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjcmVhdGVkIjoiMjAyNC0wMS0wMiAxMjo1NzoyMC4yNjk1Mjg2NTQgKzAwMDAgVVRDIG09KzAuMDQwNDkyNDk0IiwiZW5jIjoiQTI1NkdDTSIsInAyYyI6ODE5MiwicDJzIjoibHBUb0pLUkFvS3NPbmRhaCJ9.SFen5RaM_7JverpZQN6VxtJ06XePE5VKjyzMyIPgqURSge-XbiLHqA.vZ4fuVFbrLODe8RM.EGKwO3uGEifnPanziF-AD4i6q_92IetSVAEz-7Grg75AJyFLV3Flt4CmfLxrJ2JHWJEKUQBNyIU81u7pd01iNzEECDy9b0jO3DYZ_5PRET8zrVPv6SKKZ_U7MLWmAe_eUajipnbqZ6NzG8UcG4qAt278ttZB1KQsKqocKlE39fSvo3iaZEzOKxS0N3tU1Xw2C3w6HgHJFk0QiP36NIHuKoP_4QJkeAomhJX-cNOYwvTd8qTFTk2-1TzLJ5DasLXsVXTUSUzCzYQhEfL8F0qFoGvuY1dWRD5BESw2Gg2oLH1w957Xd2UhRbo5ORz9POR7goEv9AZ_rWrjSV8HozUmgFwDQyM89M7oiNedEfGQoDjypzcUBcVkZLEMIdrFRpshjcpNEzy6-PZ9rSxouKb7wemG_sueX3V3gIPCTfFr6hB8_b2mV-kKeIXQRS5pJz_wXxeFHFKOHDjt3L8n5eqh.fy-zygX7rjTUqgX02sZKKg" + node_id: "92a499fc2ce7cabd2de89416aa0d0d07838f625d" + secret: + name: keys-da-bridge-1 + config: + configtoml: + Core: + IP: consensus-validator + RPC: + Enabled: true + Address: 0.0.0.0 + Gateway: + Enabled: true + Address: 0.0.0.0 + Node: + StartupTimeout: 2m +diagnosticMode: + enabled: false \ No newline at end of file diff --git a/examples/celestia-node/arabica-light.yaml b/examples/celestia-node/arabica-light.yaml new file mode 100644 index 0000000..7de3584 --- /dev/null +++ b/examples/celestia-node/arabica-light.yaml @@ -0,0 +1,72 @@ +commonLabels: &commonLabels + chain_id: arabica-11 + environment: arabica + network: da + type: &nodeType light # check + secretName: &secretName keys-da-bridge-1 # check + pool: &pool pool-da-0 # check +service: + external: + annotations: + external-dns.alpha.kubernetes.io/endpoints-type: "NodeExternalIP" + external-dns.alpha.kubernetes.io/hostname: "hc-da-light-1.celestia-arabica-11.com" + external-dns.alpha.kubernetes.io/ttl: "60" +persistence: + size: 10Gi +node: + nodeSelector: + k8s.scaleway.com/pool-name: *pool + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Retain + otelAgent: + enabled: true + grafanaOtelSecret: + name: grafana-otel-token + resources: + requests: + cpu: 3 + memory: 15Gi + limits: + cpu: 6 + memory: 24Gi + livenessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 30 + startupProbe: + enabled: true + periodSeconds: 10 + failureThreshold: 60 + args: + - *nodeType + - start + - --p2p.network=arabica-11 + - --node.store=$(CELESTIA_HOME) + - --metrics + - --metrics.tls=false + - --p2p.metrics + settings: + nodeType: *nodeType + address: "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjcmVhdGVkIjoiMjAyNC0wMS0wMiAxMjo1NzoyMC4yNjk1Mjg2NTQgKzAwMDAgVVRDIG09KzAuMDQwNDkyNDk0IiwiZW5jIjoiQTI1NkdDTSIsInAyYyI6ODE5MiwicDJzIjoibHBUb0pLUkFvS3NPbmRhaCJ9.SFen5RaM_7JverpZQN6VxtJ06XePE5VKjyzMyIPgqURSge-XbiLHqA.vZ4fuVFbrLODe8RM.EGKwO3uGEifnPanziF-AD4i6q_92IetSVAEz-7Grg75AJyFLV3Flt4CmfLxrJ2JHWJEKUQBNyIU81u7pd01iNzEECDy9b0jO3DYZ_5PRET8zrVPv6SKKZ_U7MLWmAe_eUajipnbqZ6NzG8UcG4qAt278ttZB1KQsKqocKlE39fSvo3iaZEzOKxS0N3tU1Xw2C3w6HgHJFk0QiP36NIHuKoP_4QJkeAomhJX-cNOYwvTd8qTFTk2-1TzLJ5DasLXsVXTUSUzCzYQhEfL8F0qFoGvuY1dWRD5BESw2Gg2oLH1w957Xd2UhRbo5ORz9POR7goEv9AZ_rWrjSV8HozUmgFwDQyM89M7oiNedEfGQoDjypzcUBcVkZLEMIdrFRpshjcpNEzy6-PZ9rSxouKb7wemG_sueX3V3gIPCTfFr6hB8_b2mV-kKeIXQRS5pJz_wXxeFHFKOHDjt3L8n5eqh.fy-zygX7rjTUqgX02sZKKg" + node_id: "92a499fc2ce7cabd2de89416aa0d0d07838f625d" + secret: + name: *secretName + config: + configtoml: + Core: + IP: consensus-validator + RPC: + Enabled: true + Address: 0.0.0.0 + Gateway: + Enabled: true + Address: 0.0.0.0 + Node: + StartupTimeout: 2m +diagnosticMode: + enabled: false \ No newline at end of file