diff --git a/docker/chart/Chart.yaml b/docker/chart/Chart.yaml new file mode 100644 index 0000000..55731e3 --- /dev/null +++ b/docker/chart/Chart.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: v1 +name: quilibrium-node +version: 0.0.1 +appVersion: '' diff --git a/docker/chart/app-readme.md b/docker/chart/app-readme.md new file mode 100644 index 0000000..37a9554 --- /dev/null +++ b/docker/chart/app-readme.md @@ -0,0 +1,53 @@ +# Quilibrium-node chart + +## How to use + +Run in docker dir + +``` bash +helm install -n default -f chart/values.yaml quilibrium-node chart +``` + +## Storage Configuration Guide + +### 1. `emptyDir` (Temporary Storage) + +- An `emptyDir` volume is created when a Pod is assigned to a node +- Data persists only for the Pod's lifetime (deleted when the Pod is removed) +- Storage is backed by: + - Node's default medium (disk/SSD) by default + - RAM if `emptyDir.medium: Memory` is set + +--- + +### 2. `hostPath` (Node-Local Storage) + +- Binds a directory from the host node's filesystem into the Pod +- Data persists even if the Pod is deleted +- Tied to the node's lifecycle + +#### ⚠️ Warnings +- `replicaCount` must be set to `1` +- Not suitable for multi-node clusters +- Potential security risks (host system access) + +--- + +### 3. `PVC` (PersistentVolumeClaim - Production Storage) + +- Dynamically provisions a PersistentVolume (PV) per Pod via `volumeClaimTemplates` +- Each Pod gets independent volume (e.g., `pvc-quilibrium-node-0`, `pvc-quilibrium-node-1`) +- Data survives: + - Pod restarts + - Rescheduling (if storage backend supports it) + + +### Comparison Table + +| Feature | emptyDir | hostPath | PVC | +|------------------|---------------------|----------------------|----------------------| +| Persistence | ❌ Ephemeral | ✅ Node-persistent | ✅ Cluster-persistent| +| Multi-Node | ✅ Supported | ❌ Single-node only | ✅ Supported | +| Production Ready | ❌ No | ❌ No | ✅ Yes | +| Performance | High | Highest | Storage-dependent | +| Data Safety | Low | Medium | High | \ No newline at end of file diff --git a/docker/chart/templates/_helpers.tpl b/docker/chart/templates/_helpers.tpl new file mode 100644 index 0000000..881e1dd --- /dev/null +++ b/docker/chart/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{- define "extractGrpcPortFromMultiaddr" -}} +{{- $parts := splitList "/" .Values.node.grpc_multiaddr -}} +{{- $port := last $parts -}} +{{- if and ($port) (regexMatch "^\\d+$" $port) -}} +{{- $port -}} +{{- else -}} +{{- fail "Invalid grpc_multiaddr format. Expected /ip4/
//" -}} +{{- end -}} +{{- end -}} + +{{- define "extractRestPortFromMultiaddr" -}} +{{- $parts := splitList "/" .Values.node.rest_multiaddr -}} +{{- $port := last $parts -}} +{{- if and ($port) (regexMatch "^\\d+$" $port) -}} +{{- $port -}} +{{- else -}} +{{- fail "Invalid rest_multiaddr format. Expected /ip4/
//" -}} +{{- end -}} +{{- end -}} diff --git a/docker/chart/templates/node/statefulset.yaml b/docker/chart/templates/node/statefulset.yaml new file mode 100644 index 0000000..5bfa8ca --- /dev/null +++ b/docker/chart/templates/node/statefulset.yaml @@ -0,0 +1,92 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: quilibrium-node +spec: + replicas: {{ .Values.node.replica_count }} + podManagementPolicy: Parallel + selector: + matchLabels: + app: quilibrium-node + template: + metadata: + labels: + app: quilibrium-node + spec: + containers: + - name: quilibrium-node + image: {{ .Values.node.image }} + ports: + - name: grpc + containerPort: {{ include "extractGrpcPortFromMultiaddr" . | int }} + - name: rest + containerPort: {{ include "extractRestPortFromMultiaddr" . | int }} + - name: p2p + containerPort: {{ .Values.node.p2p_port }} + imagePullPolicy: IfNotPresent + env: + - name: DEFAULT_LISTEN_GRPC_MULTIADDR + value: {{ .Values.node.grpc_multiaddr }} + - name: DEFAULT_LISTEN_REST_MULTIADDR + value: {{ .Values.node.rest_multiaddr }} + - name: DEFAULT_STATS_MULTIADDR + value: {{ .Values.node.stats_multiaddr }} + resources: + requests: + cpu: {{ .Values.node.cpu_resource }} + memory: {{ .Values.node.memory_resource }} + limits: + cpu: {{ .Values.node.cpu_resource }} + memory: {{ .Values.node.memory_resource }} + volumeMounts: + - name: config-volume + mountPath: {{ .Values.node.persistence.mount_path }} + livenessProbe: + exec: + command: + - grpcurl + - -plaintext + - localhost:{{ include "extractGrpcPortFromMultiaddr" . | int }} + - list + - quilibrium.node.node.pb.NodeService + initialDelaySeconds: 900 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + exec: + command: + - grpcurl + - -plaintext + - localhost:{{ include "extractGrpcPortFromMultiaddr" . | int }} + - list + - quilibrium.node.node.pb.NodeService + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + {{- if (eq .Values.node.persistence.volume.type "host_path") }} + volumes: + - name: config-volume + hostPath: + path: {{ .Values.node.persistence.volume.host_path.path }} + {{- end }} + {{- if (eq .Values.node.persistence.volume.type "empty_dir") }} + volumes: + - name: config-volume + emptyDir: {} + {{- end }} + {{- if (eq .Values.node.persistence.volume.type "pvc") }} + volumeClaimTemplates: + - metadata: + name: config-volume + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.node.persistence.volume.pvc.size }} + {{- if .Values.node.persistence.volume.pvc.storage_class }} + storageClassName: {{ .Values.node.persistence.volume.pvc.storage_class }} + {{- end }} + {{- end }} diff --git a/docker/chart/values.yaml b/docker/chart/values.yaml new file mode 100644 index 0000000..6f1cc4d --- /dev/null +++ b/docker/chart/values.yaml @@ -0,0 +1,20 @@ +--- +node: + image: trancelife/quilibrium:latest + replica_count: 3 + p2p_port: 8336 + grpc_multiaddr: /ip4/0.0.0.0/tcp/8337 + rest_multiaddr: /ip4/0.0.0.0/tcp/8338 + stats_multiaddr: /dns/stats.quilibrium.com/tcp/443 + cpu_resource: 4000m + memory_resource: 8Gi + persistence: + mount_path: /root/.config + volume: + type: empty_dir + empty_dir: {} + host_path: + path: /mnt/data/quilibrium-store + pvc: + size: 1Gi + storage_class: standard