GridGain Developers Hub

Installing GridGain 9 on Kubernetes using Helm Chart

This guide walks you through deploying a GridGain 9 cluster on Kubernetes using Kubernetes Helm Chart.

Prerequisites

  • Kubernetes cluster version 1.26 or more recent

  • Helm version 3 or more recent

  • PersistentVolume provisioner support in the persistence configuration

Installing Helm Chart

Step 1: Add the Helm Repository

First, add the Helm chart repository with the following commands:

helm repo add gridgain https://gridgain.github.io/helm-charts/
helm repo update

Step 2: Install the Helm Chart

Install the chart with the default configuration:

helm install my-release gridgain/gridgain9

This installs GridGain 9 on your Kubernetes cluster.

Configuring Installation

Customize Installation

To customize your installation, use --set flag to override individual settings or provide your own values.yaml file:

helm install my-release gridgain/gridgain -f values.yaml

Custom Configuration for GridGain

You can provide custom configuration for GridGain by passing configuration parameters in the values.yaml file.

values.yaml
# Make default config from file null to provide custom config as a plaintext
configMapsFromFile:
  gridgain-config: null

configMaps:
  gridgain-config:
    name: gridgain-config.conf
    path: /opt/gridgain/etc/gridgain-config.conf
    subpath: gridgain-config.conf
# Provide any custom gg config below
    content: |
      ignite {
        clientConnector {
            connectTimeout=5000
            idleTimeout=0
            listenAddress=""
            metricsEnabled=true
            port="{{ .Values.services.headless.ports.rest }}"
            sendServerExceptionStackTraceToClient=false
            ssl {
                ciphers=""
                clientAuth=none
                enabled=false
                keyStore {
                    password=""
                    path=""
                    type=PKCS12
                }
                trustStore {
                    password=""
                    path=""
                    type=PKCS12
                }
            }
        }
        compute {
            queueMaxSize=2147483647
            statesLifetimeMillis=60000
            threadPoolSize=10
            threadPoolStopTimeoutMillis=10000
        }
        criticalWorkers {
            livenessCheckInterval=200
            maxAllowedLag=500
            nettyThreadsHeartbeatInterval=100
        }
        deployment {
            deploymentLocation=deployment
        }
        eviction {
            checkInterval=60000
        }
        expiration {
            batchSize=1000
            checkInterval=600000
            parallelismLevel=1
        }
        failureHandler {
            handler {
                ignoredFailureTypes=[
                    systemWorkerBlocked,
                    systemCriticalOperationTimeout
                ]
                type=noop
            }
        }
        network {
            fileTransfer {
                chunkSize=1048576
                maxConcurrentRequests=4
                responseTimeout=10000
                threadPoolSize=8
            }
            inbound {
                soBacklog=128
                soKeepAlive=true
                soLinger=0
                soReuseAddr=true
                tcpNoDelay=true
            }
            listenAddress=""
            membership {
                failurePingInterval=1000
                membershipSyncInterval=30000
                scaleCube {
                    failurePingRequestMembers=3
                    gossipInterval=200
                    gossipRepeatMult=3
                    membershipSuspicionMultiplier=5
                    metadataTimeout=3000
                }
            }
            nodeFinder: {
              netClusterNodes: [
                # Kubernetes service to access the GridGain 9 cluster on the Kubernetes network
                "{{ include "gridgain9.fullname" . }}-headless:{{ .Values.services.headless.ports.cluster }}"
              ]
            }
            outbound {
                soKeepAlive=true
                soLinger=0
                tcpNoDelay=true
            }
            port="{{ .Values.services.headless.ports.cluster }}"
            shutdownQuietPeriod=0
            shutdownTimeout=15000
            ssl {
                ciphers=""
                clientAuth=none
                enabled=false
                keyStore {
                    password=""
                    path=""
                    type=PKCS12
                }
                trustStore {
                    password=""
                    path=""
                    type=PKCS12
                }
            }
        }
        raft {
            fsync=false
            installSnapshotTimeout=300000
            logStripesCount=4
            logYieldStrategy=false
            responseTimeout=3000
            retryDelay=200
            retryTimeout=10000
            stripes=10
            volatileRaft {
                logStorageBudget {
                    name=unlimited
                }
            }
        }
        sql {
            execution {
                threadCount=4
            }
            nodeMemoryQuota="60%"
            offloadingDataDir="sql_offloading"
            offloadingDataLimit="0g"
            planner {
                threadCount=4
            }
        }
        storage {
            engines {
                aimem {
                    pageSize=16384
                }
                aipersist {
                    checkpoint {
                        checkpointDelayMillis=200
                        checkpointThreads=4
                        compactionThreads=4
                        interval=180000
                        intervalDeviation=40
                        logReadLockThresholdTimeout=0
                        readLockTimeout=10000
                        useAsyncFileIoFactory=true
                    }
                    pageSize=16384
                }
                rocksdb {
                    flushDelayMillis=100
                }
            }
            profiles=[
                {
                    engine=aipersist
                    name=default
                    replacementMode=CLOCK
                    size=2147483648
                }
            ]
        }
        system {
            cmgPath=""
            metastoragePath=""
            partitionsBasePath=""
            partitionsLogPath=""
        }
      }

Custom License

To install GridGain with a custom license, you can use the license key.

values.yaml
license:
# -- path inside GridGain container to mount the file with license
  mountPath: /opt/gridgain/etc/license.conf
# -- Create secret from raw content passed
  createSecret:
    mountPath: /opt/gridgain/etc
# -- License raw content
    content: |
      ignite {
        license {
          content:"<Put your license here>"
        }
      }

Authentication Configuration

To configure authentication in GridGain 9, add the following block to your values.yaml file.

For detailed setup instructions, see the Authentication chapter in the GridGain documentation.

values.yaml
license:
# -- path inside GridGain container to mount the file with license
  mountPath: /opt/gridgain/etc/license.conf
# -- Create secret from raw content passed
  createSecret:
    mountPath: /opt/gridgain/etc
# -- License raw content
    content: |
      ignite {
        security {
          enabled:true,
          authentication.providers:[{
            name:default,
            type:basic,
            users:[
              {
                username:ignite,
                displayName:administrator,
                password:ignite,
                roles:["system"]
              }
            ]
          }]
        }
        license {
          content:"<Put your license here>"
        }
      }

Volume Configuration

To configure persistent storage or attach custom volumes to GridGain, define the volume mounts and persistence settings in values.yaml.

values.yaml
persistence:
  volumes:
    persistence:
      enabled: true
      mountPath: /persistence
      size: 8Gi
      accessModes:
        - ReadWriteOnce

# Make default config from file null to provide custom config as a plaintext
configMapsFromFile:
  gridgain-config: null

configMaps:
  gridgain-config:
    name: gridgain-config.conf
    path: /opt/gridgain/etc/gridgain-config.conf
    subpath: gridgain-config.conf
# Provide any custom gg config below
    content: |
      ignite {
        clientConnector {
            connectTimeout=5000
            idleTimeout=0
            listenAddress=""
            metricsEnabled=true
            port="{{ .Values.services.headless.ports.rest }}"
            sendServerExceptionStackTraceToClient=false
            ssl {
                ciphers=""
                clientAuth=none
                enabled=false
                keyStore {
                    password=""
                    path=""
                    type=PKCS12
                }
                trustStore {
                    password=""
                    path=""
                    type=PKCS12
                }
            }
        }
        compute {
            queueMaxSize=2147483647
            statesLifetimeMillis=60000
            threadPoolSize=10
            threadPoolStopTimeoutMillis=10000
        }
        criticalWorkers {
            livenessCheckInterval=200
            maxAllowedLag=500
            nettyThreadsHeartbeatInterval=100
        }
        deployment {
            deploymentLocation=deployment
        }
        failureHandler {
            handler {
                ignoredFailureTypes=[
                    systemWorkerBlocked,
                    systemCriticalOperationTimeout
                ]
                type=noop
            }
        }
        network {
            fileTransfer {
                chunkSize=1048576
                maxConcurrentRequests=4
                responseTimeout=10000
                threadPoolSize=8
            }
            inbound {
                soBacklog=128
                soKeepAlive=true
                soLinger=0
                soReuseAddr=true
                tcpNoDelay=true
            }
            listenAddress=""
            membership {
                failurePingInterval=1000
                membershipSyncInterval=30000
                scaleCube {
                    failurePingRequestMembers=3
                    gossipInterval=200
                    gossipRepeatMult=3
                    membershipSuspicionMultiplier=5
                    metadataTimeout=3000
                }
            }
            nodeFinder: {
              netClusterNodes: [
                # Kubernetes service to access the GridGain 9 cluster on the Kubernetes network
                "{{ include "gridgain9.fullname" . }}-headless:{{ .Values.services.headless.ports.cluster }}"
              ]
            }
            outbound {
                soKeepAlive=true
                soLinger=0
                tcpNoDelay=true
            }
            port="{{ .Values.services.headless.ports.cluster }}"
            shutdownQuietPeriod=0
            shutdownTimeout=15000
            ssl {
                ciphers=""
                clientAuth=none
                enabled=false
                keyStore {
                    password=""
                    path=""
                    type=PKCS12
                }
                trustStore {
                    password=""
                    path=""
                    type=PKCS12
                }
            }
        }
        raft {
            fsync=false
            installSnapshotTimeout=300000
            logStripesCount=4
            logYieldStrategy=false
            responseTimeout=3000
            retryDelay=200
            retryTimeout=10000
            stripes=10
            volatileRaft {
                logStorageBudget {
                    name=unlimited
                }
            }
        }
        sql {
            execution {
                threadCount=4
            }
            nodeMemoryQuota="60%"
            offloadingDataDir="sql_offloading"
            offloadingDataLimit="0g"
            planner {
                threadCount=4
            }
        }
        storage {
            engines {
                aimem {
                    pageSize=16384
                }
                aipersist {
                    checkpoint {
                        checkpointDelayMillis=200
                        checkpointThreads=4
                        compactionThreads=4
                        interval=180000
                        intervalDeviation=40
                        logReadLockThresholdTimeout=0
                        readLockTimeout=10000
                        useAsyncFileIoFactory=true
                    }
                    pageSize=16384
                }
                rocksdb {
                    flushDelayMillis=100
                }
            }
            profiles=[
                {
                    engine=aipersist
                    name=default
                    replacementMode=CLOCK
                    size=2147483648
                }
            ]
        }
        system {
            cmgPath=""
            metastoragePath=""
            partitionsBasePath=""
            partitionsLogPath=""
        }
      }

KEDA Configuration

You can configure KEDA scaling for your clusters in the following way:

  • Add Helm repositories:

    helm repo add kedacore https://kedacore.github.io/charts
    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    helm repo update
  • Install KEDA:

    helm install keda kedacore/keda --namespace keda --create-namespace
  • Install Prometheus (if not already installed):

    helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --create-namespace
  • Deploy GridGain9 with KEDA autoscaling:

    helm install gridgain9 ./charts/gridgain9 -f examples/keda-autoscaling/values.yaml --namespace gridgain --create-namespace

    The example below shows how to set the values.yaml file:

values.yaml
# Example values for GridGain9 with KEDA autoscaling and JMX metrics
# This example shows how to configure GridGain9 with KEDA-based autoscaling
# and Prometheus metrics scraping using ServiceMonitor

# Enable JMX metrics exposure
jmx:
  enabled: true
  port: 9404
  agent:
    image: "busybox:1.36"
    pullPolicy: IfNotPresent
    resources:
      limits:
        cpu: "100m"
        memory: "128Mi"
      requests:
        cpu: "50m"
        memory: "64Mi"
  config: |
    lowercaseOutputName: true
    lowercaseOutputLabelNames: true

resources:
  limits:
    cpu: "1"
    memory: 4Gi
  requests:
    cpu: "1"
    memory: 4Gi

extraEnvVars:
  - name: GRIDGAIN9_EXTRA_JVM_ARGS
    value: "-javaagent:/agent/jmx.jar=9404:/opt/jmx/jmx.yaml -Xms1g -Xmx3g -XX:MaxMetaspaceSize=256m"

# ServiceMonitor configuration for Prometheus
serviceMonitor:
  enabled: true
  interval: 30s
  scrapeTimeout: 10s
  path: /metrics
  port: metrics
  labels:
    release: prometheus

# KEDA ScaledObject configuration
keda:
  enabled: true
  pollingInterval: 30
  cooldownPeriod: 300
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
    - type: prometheus
      name: heap-memory-usage
      metadata:
        serverAddress: http://prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local:9090
        query: |
          avg(jvm_memory_committed_bytes{area="heap", job="gridgain-gridgain9-headless"} / jvm_memory_max_bytes{area="heap", job="gridgain-gridgain9-headless"})
        threshold: "0.5"
    - type: prometheus
      name: nonheap-memory-usage
      metadata:
        serverAddress: http://prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local:9090
        query: |
          avg(jvm_memory_committed_bytes{area="nonheap", job="gridgain-gridgain9-headless"} / jvm_memory_max_bytes{area="nonheap", job="gridgain-gridgain9-headless"})
        threshold: "0.7"

# License configuration (example)
license:
  mountPath: /opt/gridgain/etc/license.conf
  createSecret:
    mountPath: /opt/gridgain/etc
    content: |
      {"edition":"ULTIMATE"...}

Updating Installation

To update your GridGain installation with new configuration or values:

  1. Modify the desired settings in your values.yaml file;

  2. Apply the changes using the Helm upgrade command:

    helm upgrade my-release gridgain/gridgain9 -f values.yaml

Uninstalling GridGain

To remove the installation from your Kubernetes cluster, use the following command:

helm uninstall my-release

Limitations and Considerations

When running GridGain 9 in a Kubernetes environment, the node configuration becomes read-only and cannot be modified by using the gridgain9 node config update CLI command. This is by design, as node configuration is managed via Kubernetes resources.

Getting Help

For more information about available options and values, refer to the Helm chart documentation on Artifact Hub.

If you have questions or concerns, open an issue in our GitHub repository.