Kubernetes node installation

Scope

The goal of this documentation is to install a standalone instance of the application in a Kubernetes environment. It requires that you have a minimal Kubernetes/Docker knowledge in order to adapt and tune the proposed parameters and resources.

This documentation is based on Kubernetes v1.16.0 with Docker 18.09.9.

Installation prerequisites

Manage volume used for persistence

For its installation and execution ADI will need disk space. As it is not done dynamically you must allocate storage for the application yourself (for configuration, data and working files). This is done using a "persistant volume claim". Below is an example of a volume claim for 500 Gigabytes. You must provision enough space for your application to run correctly. The volume claim is named adi-sta-pvc which is the name that will be used by the deployment to refer to this storage.

Persistant volume claim / volume-for-adi.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: adi-sta-pvc
  labels:
    app: adi-std
spec:
  storageClassName: standard
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  resources:
    requests:
      storage: 500Gi

(warning) If you are using storageClassName to manage the volumes, you have to change it to a high performance class as the application's performance strongly relies on storage responsiveness.

It is possible to load the code above in Kubernetes using the following command assuming you had put it in a file named volume-for-adi.yml.

Load volume-for-adi.yml with kubectl command
kubectl apply -f volume-for-adi.yml

Configuration used for installation

The initialization process of the application's POD works like a fully automated docker installation (See Docker fully automated installation) so it relies on a configuration file that has to contain every necessary information to run the application. More information about the configuration file is available in About Configuration Files. This file has to be loaded as a Config Map.

The example script used for deploying ADI expects a config file named config.txt. To create the Config Map from a file named my-local-config.txt, use the following command which will also rename the file to config.txt.

Config Map Creation
kubectl create configmap di-conf --from-file=config.txt=my-local-config.txt

Load ADI docker image

Kubernetes uses docker's registry to load the images referenced in deployment scripts. One way to achieve this is by loading ADI docker image like this:

Load ADI image in Docker
qatest@qda06:~$ docker load -i DecisionInsight_2.0.0_DockerImage_linux-x86-64_BNXXXXXXXXXX.tar.gz
        ...
Loaded image: axway/decisioninsight:XXXXXXXX-XX
qatest@qa06:~$

The name of the  Loaded image will be used to reference ADI in Kubernetes.

Deploying ADI

The following deployment YAML script describes the deployment of a POD. Because it is a standalone installation, the number of replicas is set to 1. The POD starting process is composed of two steps. The first one is the initialization step (see initContainers), its purpose is to initialize the volume when it is empty. This step is executed systematically even if the volume is not empty but in this case it does nothing. The second step (see containers)  starts the application. Note that you have to adapt the following script to match the image name and update the ressource section to match your usage use case.

ADI Standalone POD deployment / adi-standalone.yml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: adi-std-deployment
  labels:
    app: adi-std
spec:
  replicas: 0
  selector:
    matchLabels:
      app: adi-std
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: adi-std
    spec:
      volumes:
      - name: node-volume
        persistentVolumeClaim:
          claimName: adi-sta-pvc
      - name: conf-volume
        configMap:
          name: di-conf
      securityContext:
        fsGroup: 11000
      initContainers:
      - name: init-node-volume
        image: axway/decisioninsight:XXXXXXXX-XX
        securityContext:
          runAsNonRoot: true
          runAsUser: 11001
        command: ["sh", "-c", "if [ `ls /opt/adi/node | wc -l` -ne 0 ]; then echo Volume is not empty so is supposed already initialized; else /docker-node-deploy.sh --noPrompt --apply /opt/adi/init/config.txt ; fi"]
        volumeMounts:
        - name: node-volume
          mountPath: "/opt/adi/node"
        - name: conf-volume
          mountPath: "/opt/adi/init"
      containers:
      - name: adi-container
        image: axway/decisioninsight:XXXXXXXX-XX
        securityContext:
          runAsNonRoot: true
          runAsUser: 11001
          allowPrivilegeEscalation: false
        resources:
          limits:
            memory: 16Gi
            cpu: "8"
          requests:
            cpu: "8"
        ports:
        - name: "adi-std-server"
          containerPort: 8080
        volumeMounts:
        - name: node-volume
          mountPath: "/opt/adi/node"

(warning) The replicas count is set to 0 in the proposed YAML script to avoid an autostart once applied. 

In order to load the above code, you can save it in a file (i.e. adi-standalone.yml) and execute the following command:

Load volume-for-adi.yml with kubectl command
kubectl apply -f adi-standalone.yml

Expose ADI as a service

ADI's container was configured to listen for http requests on port 8080 so this is the one that has to be exposed in order to be able to access ADI's UI.

Expose deployment as a service
> kubectl expose deployment adi-std-deployment --type=NodePort --port=8080
service/adi-std-deployment exposed
> kubectl get services
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
adi-std-deployment   NodePort    10.101.218.246   <none>        8080:31604/TCP   6m38s
kubernetes           ClusterIP   10.96.0.1        <none>        443/TCP          14d

Node management

Start the node

Start node
kubectl scale --replicas=1 deployment/adi-std-deployment

Stop the node (gracefully)

Stop node
kubectl scale --replicas=0 deployment/adi-std-deployment

View node logs

Node log tail
kubectl logs deployment/adi-std-deployment
Node log tail sticky
kubectl logs deployment/adi-std-deployment -f

Update configuration files

When the application is running in a POD, you can attach a TTY to the POD and update the configuration files located in /opt/adi/node/conf.

First you will need to get the POD's name. It is the one starting by adi-std-deployment:

Get pods name
kubectl get pods
NAME READY STATUS RESTARTS AGE
adi-std-deployment-5858f54666-ngfrb 1/1 Running 0 9m41s

Second, execute an attached raw TTY shell into the pod:

Run sh
kubectl exec -it adi-std-deployment-5858f54666-ngfrb /bin/sh
/ $ cd /opt/adi/node/conf/
/opt/adi/node/conf $ ls -l
total 24
-rw-r--r--    1 adi-user adi-user        16 Nov  8 15:19 encryption.key
-rw-r--r--    1 adi-user adi-user       132 Nov  8 15:19 jvm.conf
-rw-r--r--    1 adi-user adi-user      7227 Nov  8 15:19 log4j.properties
-rw-r--r--    1 adi-user adi-user       107 Nov  8 15:19 path.conf
-rw-r--r--    1 adi-user adi-user      1722 Nov  8 15:19 platform.properties
/opt/adi/node/conf $

Once you are done, hit ctrl+d (^d) to close and end the terminal session.

Upgrade

Upgrading a Kubernetes deployments is done by updating the deployment container's image from a given version (axway/decisioninsight:XXXXXXXX-XX) to a newer one (axway/decisioninsight:YYYYYYYY-YY).

To do so, you should have a look at Upgrade a node on Docker and fulfill the following three steps :

  1. Configure a backup checkpoint

  2. Prepare the node configuration

  3. Load the new image in the docker registry of your Kubernetes server

To finish the update, execute the following command:

Update container's image
kubectl set image deployment/adi-std-deployment adi-container=axway/decisioninsight:YYYYYYYY-YY --record

This command will stop the POD and restart it using the image you affected to it.

Once the node has been updated, as with any deployments some checks should be done to see it was indeed successful. Following Upgrade verification on Docker is a good start.

Related Links