diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 747970f..37268f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,12 +4,6 @@ on: push: branches: [ main, develop ] tags: [ 'v*' ] - paths: - - 'src/**' - - 'Dockerfile' - - 'requirements.txt' - - '.github/workflows/build.yml' - - '.github/workflows/build-simple.yml' paths-ignore: - 'charts/**' - 'docs/**' diff --git a/charts/cardano-node/README.md b/charts/cardano-node/README.md index f6c73e6..14ce32a 100644 --- a/charts/cardano-node/README.md +++ b/charts/cardano-node/README.md @@ -190,9 +190,10 @@ forgeManager: ```yaml persistence: - enabled: true - size: 400Gi # Mainnet requires ~350GB+ - storageClass: "fast-ssd" # Use fast storage for best performance + ledger: + enabled: true + size: 400Gi # Mainnet requires ~350GB+ + storageClass: "fast-ssd" # Use fast storage for best performance ``` #### Resource Configuration diff --git a/charts/cardano-node/examples/mainnet-block-prod.yaml b/charts/cardano-node/examples/mainnet-block-prod.yaml index 9e3dd85..2bdf71c 100644 --- a/charts/cardano-node/examples/mainnet-block-prod.yaml +++ b/charts/cardano-node/examples/mainnet-block-prod.yaml @@ -105,12 +105,15 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 400Gi # Mainnet requires substantial storage - # storageClass: "fast-ssd" # Use high-performance storage class for production - annotations: - # Example for AWS EBS volume encryption - # ebs.csi.aws.com/encrypted: "true" + ledger: + enabled: true + size: 400Gi # Mainnet requires substantial storage + # storageClass: "fast-ssd" # Use high-performance storage class for production + annotations: + # Example for AWS EBS volume encryption + # ebs.csi.aws.com/encrypted: "true" + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION (Production) @@ -438,4 +441,4 @@ networkPolicy: # Immediately rotate all secrets # Review access logs and audit trails # Check for unauthorized changes -# Isolate affected systems \ No newline at end of file +# Isolate affected systems diff --git a/charts/cardano-node/examples/mainnet-relay-shared-socket.yaml b/charts/cardano-node/examples/mainnet-relay-shared-socket.yaml new file mode 100644 index 0000000..e5a6bd1 --- /dev/null +++ b/charts/cardano-node/examples/mainnet-relay-shared-socket.yaml @@ -0,0 +1,320 @@ +# Mainnet Relay Node - Production Ready Example +# This is a complete, production-ready relay configuration for Cardano Mainnet +# Optimized for high availability and performance +# Socket can be shared by created PVC + +# =========================================== +# BASIC CONFIGURATION +# =========================================== +replicaCount: 2 # Multiple replicas for HA + +# =========================================== +# CARDANO NODE CONFIGURATION +# =========================================== +cardanoNode: + network: "mainnet" + magic: "764824073" + + # Relay node configuration + blockProducer: false + + # Enable Mithril for fast sync + mithril: + enabled: true + restoreSnapshot: true + aggregatorEndpoint: "https://aggregator.release-mainnet.api.mithril.network/aggregator" + genesisVerificationKey: "5b3133312c36362c3134302c3138352c3133382c31312c3233372c3230372c3235302c3134342c32372c322c3138382c33302c31322c38312c3135352c3230342c31302c3137392c37352c32332c3133382c3139362c3231372c352c31342c32302c35372c37392c33392c3137365d" + ancillaryVerificationKey: "5b32332c37312c39362c3133332c34372c3235332c3232362c3133362c3233352c35372c3136342c3130362c3138362c322c32312c32392c3132302c3136332c38392c3132312c3137372c3133382c3230382c3133382c3231342c39392c35382c32322c302c35382c332c36395d" + + # Override requirements for mainnet + config: + requiresNetworkMagic: "RequiresNoMagic" + + # Mainnet network topology + topology: + bootstrapPeers: + - address: "backbone.cardano.iog.io" + port: 3001 + - address: "backbone.mainnet.emurgornd.com" + port: 3001 + - address: "backbone.mainnet.cardanofoundation.org" + port: 3001 + localRoots: + - accessPoints: + - address: "cardano-bp-cardano-node-p2p.cardano-mainnet.svc.cluster.local" # Block Producer Internal DNS Name + port: 3001 + description: "block-producer-1" + advertise: false + trustable: true + hotValency: 2 + publicRoots: + - accessPoints: [] + advertise: false + useLedgerAfterSlot: 128908821 + +# =========================================== +# FORGE MANAGER V2.0 +# =========================================== +forgeManager: + enabled: false + +# =========================================== +# STORAGE CONFIGURATION +# =========================================== +persistence: + ledger: + enabled: true + size: 400Gi # Mainnet requires substantial storage + # storageClass: "fast-ssd" # Use high-performance storage class + socket: + enabled: true + +# =========================================== +# RESOURCE CONFIGURATION (Production) +# =========================================== +resources: + cardanoNode: + limits: + cpu: 4000m + memory: 16Gi + requests: + cpu: 2000m + memory: 8Gi + + forgeManager: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + +# =========================================== +# NETWORKING +# =========================================== +service: + p2p: + type: LoadBalancer # External access for relay + port: 3001 + annotations: + # Example for AWS NLB + service.beta.kubernetes.io/aws-load-balancer-type: "nlb" + service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" + +# =========================================== +# MONITORING +# =========================================== +monitoring: + enabled: true + serviceMonitor: + enabled: true # Enable for production monitoring + interval: 30s + scrapeTimeout: 10s + +# =========================================== +# POD CONFIGURATION +# =========================================== +podLabels: + network: "mainnet" + environment: "production" + node-type: "relay" + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "12798" + prometheus.io/path: "/metrics" + +# =========================================== +# HIGH AVAILABILITY +# =========================================== +affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cardano-node + - key: network + operator: In + values: + - mainnet + - key: node-type + operator: In + values: + - relay + topologyKey: kubernetes.io/hostname + +# =========================================== +# POD DISRUPTION BUDGET +# =========================================== +podDisruptionBudget: + enabled: true + minAvailable: 1 # Always keep at least 1 replica running + +# =========================================== +# SECURITY CONTEXT +# =========================================== +securityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + +podSecurityContext: + fsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + fsGroupChangePolicy: Always + +# =========================================== +# NETWORK POLICY (Production Security) +# =========================================== +networkPolicy: + enabled: true + ingress: + # Allow P2P from anywhere + p2pFromCIDR: "0.0.0.0/0" + # Allow metrics from monitoring namespace + metricsFromNamespaces: + - monitoring + egress: + # Allow P2P to anywhere + p2pToCIDR: "0.0.0.0/0" + # Allow HTTPS for genesis files and Mithril + httpsToCIDR: "0.0.0.0/0" + +# =========================================== +# DEPLOYMENT INSTRUCTIONS +# =========================================== +# +# This example provides a complete mainnet relay deployment. +# Follow these steps to deploy: +# +# 1. Create namespace: +# kubectl create namespace cardano-mainnet +# +# 2. Review and customize resource allocation: +# - Ensure your cluster has sufficient CPU/memory +# - Consider using dedicated nodes with high-performance storage +# +# 3. Deploy the relay: +# helm install cardano-relay ./charts/cardano-node \ +# --namespace cardano-mainnet \ +# --values ./charts/cardano-node/examples/mainnet-relay.yaml +# +# 4. Monitor the deployment: +# kubectl logs -f cardano-relay-0 -c cardano-node -n cardano-mainnet +# # You should see Mithril snapshot restoration messages +# +# 5. Get external IP for connecting block producers: +# kubectl get svc cardano-relay-cardano-node-p2p -n cardano-mainnet +# +# =========================================== +# VERIFICATION STEPS +# =========================================== +# +# After deployment, verify everything is working: +# +# 1. Check node sync status: +# kubectl exec -it cardano-relay-0 -c cardano-node -n cardano-mainnet -- \ +# cardano-cli query tip --mainnet --socket-path /ipc/node.socket +# +# 2. Check that the node socket exists: +# kubectl exec -it cardano-relay-0 -c cardano-node -n cardano-mainnet -- \ +# ls -la /ipc/node.socket +# +# 3. Test network connectivity: +# kubectl exec -it cardano-relay-0 -c cardano-node -n cardano-mainnet -- \ +# nc -zv backbone.cardano.iog.io 3001 +# +# 4. Monitor resource usage: +# kubectl top pods -n cardano-mainnet +# +# 5. Check high availability: +# kubectl get pods -n cardano-mainnet -o wide +# # Verify pods are running on different nodes +# +# =========================================== +# CUSTOMIZATION +# =========================================== +# +# Common customizations for production: +# +# 1. Resource allocation: +# - Scale CPU/memory based on your infrastructure +# - Use node selectors for dedicated hardware +# +# 2. Storage optimization: +# - Use high-performance storage classes (SSD, NVMe) +# - Consider larger storage sizes for future growth +# +# 3. Networking: +# - Configure LoadBalancer annotations for your cloud provider +# - Set up DNS names for your relay endpoints +# +# 4. Monitoring: +# - Enable ServiceMonitor for Prometheus +# - Set up alerting for node health and sync status +# +# 5. Security: +# - Enable NetworkPolicy for production security +# - Consider using Pod Security Standards +# +# =========================================== +# EXPECTED BEHAVIOR +# =========================================== +# +# 1. Two relay pods will start with anti-affinity (different nodes) +# 2. Node will restore from Mithril snapshot (faster than full sync) +# 3. External LoadBalancer service will provide P2P access +# 4. Pods will maintain high availability with PDB +# 5. Metrics will be available for monitoring +# +# =========================================== +# PRODUCTION CONSIDERATIONS +# =========================================== +# +# 1. Node placement: +# - Use dedicated nodes with high-performance storage +# - Consider different availability zones +# +# 2. Monitoring: +# - Set up comprehensive monitoring and alerting +# - Monitor sync status, peer connections, and resource usage +# +# 3. Backup strategy: +# - Regular snapshots of persistent volumes +# - Consider database backups for quick recovery +# +# 4. Security: +# - Regular security updates for node images +# - Network segmentation and firewall rules +# +# 5. Performance tuning: +# - Adjust resources based on actual usage patterns +# - Consider SSD storage for optimal performance +# +# =========================================== +# TROUBLESHOOTING +# =========================================== +# +# Common production issues: +# +# 1. Pod stuck in pending: +# - Check resource availability and node capacity +# - Verify storage class exists and has capacity +# +# 2. Slow sync performance: +# - Check storage performance (IOPS, throughput) +# - Monitor network connectivity to bootstrap peers +# +# 3. High resource usage: +# - Monitor and adjust resource limits +# - Consider scaling to dedicated nodes +# +# 4. LoadBalancer issues: +# - Verify cloud provider LoadBalancer configuration +# - Check security groups and firewall rules diff --git a/charts/cardano-node/examples/mainnet-relay.yaml b/charts/cardano-node/examples/mainnet-relay.yaml index 66a408c..5aeeebe 100644 --- a/charts/cardano-node/examples/mainnet-relay.yaml +++ b/charts/cardano-node/examples/mainnet-relay.yaml @@ -61,9 +61,12 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 400Gi # Mainnet requires substantial storage - # storageClass: "fast-ssd" # Use high-performance storage class + ledger: + enabled: true + size: 400Gi # Mainnet requires substantial storage + # storageClass: "fast-ssd" # Use high-performance storage class + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION (Production) @@ -313,4 +316,4 @@ networkPolicy: # # 4. LoadBalancer issues: # - Verify cloud provider LoadBalancer configuration -# - Check security groups and firewall rules \ No newline at end of file +# - Check security groups and firewall rules diff --git a/charts/cardano-node/examples/testnet-preprod-block-prod.yaml b/charts/cardano-node/examples/testnet-preprod-block-prod.yaml index 842be6d..8ec48be 100644 --- a/charts/cardano-node/examples/testnet-preprod-block-prod.yaml +++ b/charts/cardano-node/examples/testnet-preprod-block-prod.yaml @@ -91,9 +91,12 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 35Gi # Preprod network requires more storage than preview - # storageClass: "" # Use default storage class + ledger: + enabled: true + size: 35Gi # Preprod network requires more storage than preview + storageClass: "" # Use default storage class + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION @@ -276,4 +279,4 @@ podSecurityContext: # Verify RBAC permissions for leases and CRDs # # 6. "requiresNetworkMagic" errors: -# Ensure config.requiresNetworkMagic is set to "RequiresMagic" for testnets \ No newline at end of file +# Ensure config.requiresNetworkMagic is set to "RequiresMagic" for testnets diff --git a/charts/cardano-node/examples/testnet-preprod-relay.yaml b/charts/cardano-node/examples/testnet-preprod-relay.yaml index c24a0b7..5192f9a 100644 --- a/charts/cardano-node/examples/testnet-preprod-relay.yaml +++ b/charts/cardano-node/examples/testnet-preprod-relay.yaml @@ -56,9 +56,12 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 35Gi # Preprod network requires more storage than preview - # storageClass: "" # Use default storage class + ledger: + enabled: true + size: 35Gi # Preprod network requires more storage than preview + storageClass: "" # Use default storage class + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION @@ -204,4 +207,4 @@ podSecurityContext: # Verify your cluster supports LoadBalancer services (cloud provider required) # # 4. "requiresNetworkMagic" errors: -# Ensure config.requiresNetworkMagic is set to "RequiresMagic" for testnets \ No newline at end of file +# Ensure config.requiresNetworkMagic is set to "RequiresMagic" for testnets diff --git a/charts/cardano-node/examples/testnet-preview-block-prod.yaml b/charts/cardano-node/examples/testnet-preview-block-prod.yaml index a1f5765..aa9082b 100644 --- a/charts/cardano-node/examples/testnet-preview-block-prod.yaml +++ b/charts/cardano-node/examples/testnet-preview-block-prod.yaml @@ -91,9 +91,12 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 25Gi # Preview network requires less storage - # storageClass: "" # Use default storage class + ledger: + enabled: true + size: 25Gi # Preview network requires less storage + # storageClass: "" # Use default storage class + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION diff --git a/charts/cardano-node/examples/testnet-preview-relay.yaml b/charts/cardano-node/examples/testnet-preview-relay.yaml index 8668214..abf3325 100644 --- a/charts/cardano-node/examples/testnet-preview-relay.yaml +++ b/charts/cardano-node/examples/testnet-preview-relay.yaml @@ -57,9 +57,12 @@ forgeManager: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - size: 25Gi # Preview network requires less storage - # storageClass: "" # Use default storage class + ledger: + enabled: true + size: 25Gi # Preview network requires less storage + # storageClass: "" # Use default storage class + socket: + enabled: false # =========================================== # RESOURCE CONFIGURATION diff --git a/charts/cardano-node/templates/_helpers.tpl b/charts/cardano-node/templates/_helpers.tpl index 407a13d..358ad1b 100644 --- a/charts/cardano-node/templates/_helpers.tpl +++ b/charts/cardano-node/templates/_helpers.tpl @@ -243,13 +243,16 @@ Common annotations {{- end }} {{/* -PVC name - either existing claim or generated name +PVC name - either existing claim or generated name. +Takes a parameter: "ledger" or "socket" */}} {{- define "cardano-node.pvcName" -}} -{{- if .Values.persistence.existingClaim -}} -{{- .Values.persistence.existingClaim -}} +{{- $which := . -}} {{/* parameter: "ledger" or "socket" */}} +{{- $p := index .Values.persistence $which -}} +{{- if $p.existingClaim -}} +{{- $p.existingClaim -}} {{- else -}} -{{- printf "%s-data" (include "cardano-node.fullname" .) -}} +{{- printf "%s-%s" (include "cardano-node.fullname" $) $which -}} {{- end -}} {{- end }} @@ -303,3 +306,77 @@ name: {{ .Values.forgeManager.multiTenant.pool.name | quote }} ticker: {{ .Values.forgeManager.multiTenant.pool.ticker | quote }} {{- end }} {{- end }} +{{/* +Return "true" if either ledger or socket PVC template should be created. +Used to decide whether to emit the volumeClaimTemplates: root key. +*/}} +{{- define "cardano-node.requiresPVCs" -}} +{{- $ledger := .Values.persistence.ledger -}} +{{- $socket := .Values.persistence.socket -}} + +{{- $needLedger := and $ledger.enabled (not $ledger.existingClaim) -}} +{{- $needSocket := and $socket.enabled (not $socket.existingClaim) -}} + +{{- if or $needLedger $needSocket }}true{{ else }}false{{ end }} +{{- end }} + +{{/* +Generate the list items for volumeClaimTemplates. +This helper does NOT emit the volumeClaimTemplates: key itself. +Indentation is controlled by callers via nindent. +*/}} +{{- define "cardano-node.volumeClaimTemplates" -}} +{{- $ledger := .Values.persistence.ledger -}} +{{- $socket := .Values.persistence.socket -}} + +{{- $needLedger := and $ledger.enabled (not $ledger.existingClaim) -}} +{{- $needSocket := and $socket.enabled (not $socket.existingClaim) -}} + +{{- if $needLedger }} +- metadata: + name: cardano-data + labels: + {{- include "cardano-node.labels" . | nindent 6 }} + {{- with $ledger.annotations }} + annotations: + {{- toYaml . | nindent 6 }} + {{- end }} + spec: + accessModes: + - {{ $ledger.accessMode | quote }} + {{- if $ledger.storageClass }} + {{- if (eq "-" $ledger.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: {{ $ledger.storageClass | quote }} + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $ledger.size | quote }} +{{- end }} + +{{- if $needSocket }} +- metadata: + name: socket-dir + labels: + {{- include "cardano-node.labels" . | nindent 6 }} + {{- with $socket.annotations }} + annotations: + {{- toYaml . | nindent 6 }} + {{- end }} + spec: + accessModes: + - {{ $socket.accessMode | quote }} + {{- if $socket.storageClass }} + {{- if (eq "-" $socket.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: {{ $socket.storageClass | quote }} + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $socket.size | quote }} +{{- end }} +{{- end }} diff --git a/charts/cardano-node/templates/statefulset.yaml b/charts/cardano-node/templates/statefulset.yaml index 0276b02..50fe173 100644 --- a/charts/cardano-node/templates/statefulset.yaml +++ b/charts/cardano-node/templates/statefulset.yaml @@ -430,6 +430,25 @@ spec: # VOLUMES # =========================================== volumes: + # cardano-data: use an existing volume claim if provided, otherwise will create a volumeclaimtemplate + {{- if and .Values.persistence.ledger.enabled .Values.persistence.ledger.existingClaim }} + - name: cardano-data + persistentVolumeClaim: + claimName: {{ .Values.persistence.ledger.existingClaim }} + {{- end }} + + # socket-dir: use existing volume claim if provided, else create an emptydir + # or create volumeclaimtemplate + {{- if and .Values.persistence.socket.enabled .Values.persistence.socket.existingClaim }} + - name: socket-dir + persistentVolumeClaim: + claimName: {{ .Values.persistence.socket.existingClaim }} + {{- else if not .Values.persistence.socket.enabled }} + # EmptyDir for node socket + - name: socket-dir + emptyDir: {} + {{- end }} + # ConfigMap for cardano-node config - name: cardano-config-src configMap: @@ -439,10 +458,6 @@ spec: - name: cardano-config emptyDir: {} - # EmptyDir for node socket - - name: socket-dir - emptyDir: {} - {{- if eq (include "cardano-node.forgeManagerEnabled" .) "true" }} # Secret for forging keys - name: cardano-secrets @@ -475,30 +490,7 @@ spec: # =========================================== # VOLUME CLAIM TEMPLATES # =========================================== - {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} + {{- if eq (include "cardano-node.requiresPVCs" .) "true" }} volumeClaimTemplates: - - metadata: - name: cardano-data - labels: - {{- include "cardano-node.labels" . | nindent 10 }} - {{- with .Values.persistence.annotations }} - annotations: - {{- toYaml . | nindent 10 }} - {{- end }} - spec: - accessModes: - - {{ .Values.persistence.accessMode | quote }} - {{- if .Values.persistence.storageClass }} - {{- if (eq "-" .Values.persistence.storageClass) }} - storageClassName: "" - {{- else }} - storageClassName: {{ .Values.persistence.storageClass | quote }} - {{- end }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{- else if .Values.persistence.existingClaim }} - # Using existing PVC - # Note: This requires manual PVC creation before chart installation + {{ include "cardano-node.volumeClaimTemplates" . | nindent 2 }} {{- end }} diff --git a/charts/cardano-node/values.yaml b/charts/cardano-node/values.yaml index 4af1587..966358a 100644 --- a/charts/cardano-node/values.yaml +++ b/charts/cardano-node/values.yaml @@ -399,14 +399,27 @@ submitApi: # STORAGE CONFIGURATION # =========================================== persistence: - enabled: true - storageClass: "" # Use default storage class if empty - accessMode: ReadWriteOnce - size: 200Gi # Increase for mainnet (400Gi+ recommended) - annotations: {} - - # Existing PVC (if you want to use an existing volume) - existingClaim: "" + # Cardano ledger storage + ledger: + enabled: true + storageClass: "" # Use default storage class if empty + accessMode: ReadWriteOnce + size: 200Gi # Increase for mainnet (400Gi+ recommended) + annotations: {} + + # Existing PVC (if you want to use an existing volume) + existingClaim: "" + # Optional: create a PVC for the IPC socket if needed by + # external applications not part of this release + socket: + enabled: false # default: disabled; use emptyDir instead + storageClass: "" # Use default storage class if empty + accessMode: ReadWriteOnce + size: 10Mi + annotations: {} + + # Existing PVC (if you want to use an existing volume) + existingClaim: "" # =========================================== # RESOURCE CONFIGURATION