// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= Installing on Kubernetes

You can install Ignite 3 and run a Ignite cluster on Kubernetes cluster. This section describes all the necessary steps, as well as provides the configurations and manifests that you can copy and paste into your environment.

== Prerequisites

* Ignite 3.0.0 or more recent
* Access to a running Kubernetes cluster
* `kubectl` installed and configured to interact with your Kubernetes cluster
* A namespace exists for Ignite 3 to be deployed.

== Installation Steps

=== Create ConfigMaps

. Create the Ignite configuration file. The minimum node configuration is as follows:
+
.ignite-config.conf
[source,json]
----
{
  ignite: {
    network: {
      # Ignite 3 node port
      port: 3344,
      nodeFinder: {
        netClusterNodes: [
          # Kubernetes service to access the Ignite 3 cluster on the Kubernetes network
          "ignite-svc-headless:3344"
        ]
      }
    }
  }
}
----
+
. Create the ConfigMap object for Ignite configuration:
+
[source,shell]
----
kubectl create configmap ignite-config -n <namespace> --from-file=ignite-config.conf
----

=== Deploy the Service

. Prepare the `service.yaml` for service deployment:
+
.service.yaml
[source,yaml]
----
apiVersion: v1
kind: Service
metadata:
  # The name must be equal to netClusterNodes.
  name: ignite-svc-headless
  # Place your namespace name here.
  namespace: <namespace>
spec:
  clusterIP: None
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: management
    port: 10300
    protocol: TCP
    targetPort: 10300
  - name: rest
    port: 10800
    protocol: TCP
    targetPort: 10800
  - name: cluster
    port: 3344
    protocol: TCP
    targetPort: 3344
  selector:
    # Must be equal to the label set for pods.
    app: ignite
  # Include not-yet-ready nodes.
  publishNotReadyAddresses: True
  sessionAffinity: None
  type: ClusterIP
----
+
. Apply the `service.yaml` file to set up the service:
+
[source,shell]
----
kubectl apply -f service.yaml
----

=== Deploy the StatefulSet

. Prepare the `statefulset.yaml` file for StatefulSet deployment:
+
.statefulset.yaml
[source,yaml]
----
apiVersion: apps/v1 
kind: StatefulSet 
metadata:
  # The cluster name.
  name: ignite-cluster
  # Place your namespace name.
  namespace: <namespace>
spec:
  # The initial number of pods to be started by Kubernetes.
  replicas: 2
  # Kubernetes service to access the Ignite 3 cluster on the Kubernetes network.
  serviceName: ignite-svc-headless
  selector:
    matchLabels:
      app: ignite
  template:
    metadata:
      labels:
        app: ignite
    spec:
      terminationGracePeriodSeconds: 60000
      containers:
        # Custom pod name.
      - name: ignite-node
        # Limits and requests for the Ignite container.
        resources:
          limits:
            cpu: "4"
            memory: 4Gi
          requests:
            cpu: "4"
            memory: 4Gi
        env:
          # Must be specified to ensure that Ignite 3 cluster replicas are visible to each other.
          - name: IGNITE_NODE_NAME
            valueFrom:
              fieldRef: 
                fieldPath: metadata.name
          # Ignite 3 working directory.
          - name: IGNITE_WORK_DIR
            value: /ai3-work
        # Ignites Docker image and it's version.
        image: ignite/ignite3:9.0.5
        ports:
        - containerPort: 10300
        - containerPort: 10800
        - containerPort: 3344
        volumeMounts:
        # The config will be placed at this path in the container.
        - mountPath: /opt/ignite/etc/ignite-config.conf
          name: config-vol
          subPath: ignite-config.conf
        # Ignite 3 working directory.
        - mountPath: /gg9-work
          name: persistence
      volumes:
      - name: config-vol
        configMap:
          name: ignite-config
  volumeClaimTemplates:
  - apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: persistence
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi # Provide enough space for your application data.
      volumeMode: Filesystem
----
+
. Apply the `statefulset.yaml` file to deploy the main components of Ignite 3:
+
[source,shell]
----
kubectl apply -f statefulset.yaml
----

=== Wait for Pods to Start

. Monitor the status of the pods:
+
[source,shell]
----
kubectl get pods -n <namespace> -w
----
+
. Ensure that all pods' `STATUS` is `Running` before proceeding.

=== Deploy the Job

. Prepare the `job.yaml` file for deploying the job:
+
.job.yaml
[source,yaml]
----
apiVersion: batch/v1
kind: Job
metadata:
  name: cluster-init
  # Place your namespace name here.
  namespace: <namespace>
spec:
  template:
    spec:
      containers:
      # Command to init the cluster. URL and host must be the name of the service you created before. Port is 10300 as the management port.
      - args:
        - -ec
        - |
          /opt/ignite3cli/bin/ignite3 cluster init --name=ignite --url=http://ignite-svc-headless:10300
        command:
        - /bin/sh
        # Specify the Docker image with the Ignite 3 CLI and its version.
        image: ignite/ignite3:3.0.0
        imagePullPolicy: IfNotPresent
        name: cluster-init
        resources: {}
      restartPolicy: Never
      terminationGracePeriodSeconds: 120

----
+
. Apply the `job.yaml` file to complete installation.
+
[source,shell]
----
kubectl apply -f job.yaml
----

== Installation Verification

. Check the status of all resources in your namespace:
+
[source,shell]
----
kubectl get all -n <namespace>
----
+
. Ensure that all components are running as expected, without errors, and that the initialization job is in the `Completed` status.
. Verify that your cluster is initialized and running.
+
[source,shell]
----
kubectl exec -it ignite-cluster-0 bash -n <namespace>
/opt/ignite3cli/bin/ignite3 cluster status
----
+
The command output must include the name of your cluster and the number of nodes. The status must be `ACTIVE`.

== Installation Troubleshooting

If any issues occur during the installation:

* Check the logs of specific pods:
+
[source,shell]
----
kubectl logs <pod-name> -n <namespace>
----
+
* Review events in the namespace:
+
[source,shell]
----
kubectl get events -n <namespace>
----
