Javascript function not running on pod creation using a Kubernetes Job

Vincenzo

I have an AKS cluster with a Node.js server and a mongo db. I want to create MongoDb records from a repair catalog in a json file using the server endpoint.

To do so I created an Helm chart , with the sendRepiarData.js and the catalog.json files under a files folder and a Job which should create a Node pod and run the sendRepiarData.js file.

When I install the chart the Job does create the pod and set the status to completed but no data is sent to the server and I don't get any logs from the pod when I run the kubectl logs command on that pod.

So to debug it I commented out the function and just printed to console, but still no logs from the pod. I'm fairly new to Kubernetes and I guess I'm misconfiguring the Job's volumeMounts a volumes parameters. Can you spot what I'm doing wrong? Many thanks.

Events:

8s          Normal   Scheduled              pod/fixit-repair-catalog-job-pzcb5                Successfully assigned default/fixit-repair-catalog-job-pzcb5 to aks-default-80269438-vmss000000
8s          Normal   Pulled                 pod/fixit-repair-catalog-job-pzcb5                Container image "node:14" already present on machine
8s          Normal   Created                pod/fixit-repair-catalog-job-pzcb5                Created container fixit-repair-catalog-job
8s          Normal   Started                pod/fixit-repair-catalog-job-pzcb5                Started container fixit-repair-catalog-job
8s          Normal   SuccessfulCreate       job/fixit-repair-catalog-job                      Created pod: fixit-repair-catalog-job-pzcb5
4s          Normal   Completed              job/fixit-repair-catalog-job                      Job completed

.Values:

replicaCount: 1
global:
  namespace: default
image:
  repository: node
  tag: 14

# filePath: .
filePath: "/files"
service:
  name: fixit-repair-catalog
  type: ClusterIP
  port: 3000


fullnameOverride: ""

Job:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-job
  labels:
    app: {{ .Release.Name }}
spec:
  template:
    spec:
      restartPolicy: OnFailure
      containers:
        - name: {{ .Release.Name }}-job
          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
          command: ["node"]
          args: [ {{ .Files.Get "/files/sendRepairData.js" }} ]
          volumeMounts:
            - name: repair-catalog
              mountPath: /app/files
      volumes:
        - name: repair-catalog
          hostPath:
            path: {{ .Values.filePath }}

sendRepairData.js:

const fs = require('fs');
const http = require('http');

// Function to send repair data
var savedRepairs = [];
function sendRepairData() {
  // Read the catalog JSON file
  try {
    const catalogData = fs.readFileSync('catalog.json'); 
    const catalog = JSON.parse(catalogData);

    // Access the repairs array from the catalog
    const repairs = catalog.repairs;

    // Process the repairs data as needed
    for (const repair of repairs) {
      const options = {
        host: 'server-clusterip-service', 
        port: 3000,
        path: 'api/server/repairs',
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          AuthToken: '', 
          apikey: ''
        },
      };

      const req = http.request(options, (res) => {
        let data = '';

        res.on('data', (chunk) => {
          data += chunk;
        });

        res.on('end', () => {
          console.log('Response:', data);
          // save response data for resetting the db in case of error
          savedRepairs.push(JSON.parse(data));

        });
      });

      req.on('error', (error) => {
        console.error('Error:', error.message);
      });

      req.write(JSON.stringify(repair));
      req.end();
    }
  } catch (error) {
    console.error('Error reading catalog file:', error.message);
    throw error;
  }
}


// function to reset the db
function deleteRepairs() {
  savedRepairs.forEach((repair) => {
    const options = {
    host: 'server-clusterip-service', 
    port: 3000, 
    path: `api/server/repairs/${repair.id}`,
    method: 'Delete',
    headers: {
      'Content-Type': 'application/json',
      AuthToken: '',  by your server
      apikey: ''
    },
  };

  const req = http.request(options, (res) => {
    let data = '';

    res.on('data', (chunk) => {
      data += chunk;
    });

    res.on('end', () => {
      console.log('Response:', data);
    });
  });

  req.on('error', (error) => {
    console.error('Error:', error.message);
  });
  req.end();
  });
  
}

function uploadRepairCatalog() {
  try {
    sendRepairData();
  } catch (error){
    deleteRepairs();
    throw error;
  }
}
// uploadRepairCatalog();

console.log('cron job done');
David Maze

In Kubernetes, you can't really run an unmodified base image and inject your application through mounts. I see this as an occasional Docker "pattern" to avoid the one-line installation of Node locally, but in Kubernetes you can't reliably access the host system. To use Kubernetes effectively, you all but must create a custom image and push it to some registry.

In particular, this block of YAML

      volumes:
        - name: repair-catalog
          hostPath:
            path: {{ .Values.filePath }}

mounts an arbitrary directory from whichever Node the Pod is running on. It cannot copy content from your local machine; indeed, Kubernetes doesn't track from where a Job might have been submitted, and can't connect back out of the cluster. In most uses you should avoid hostPath: mounts.

Instead you need to create a custom image. If you're just trying to run this script and it doesn't have any dependencies, the Dockerfile is pretty straightfoward

FROM node:14
WORKDIR /app
COPY sendRepairData.js ./
CMD ["node", "./sendRepairData.js"]

You then need to either publish the image or get the image into the cluster somehow. The generic answer, assuming some external image repository exists, looks like

docker build -t registry.example.com/send-repair-data:20230526 .
docker push registry.example.com/send-repair-data:20230526

In local environments you may be able to get away without the "push" command. Minikube for example has a way to directly use an embedded Docker daemon so long as you eval $(minikube docker-env) before building; Kind has a documented path to run a local registry.

You need to change your values.yaml to point at the image you just built

image:
  repository: registry.example.com/send-repair-data
  tag: "20230526"

Then in the Job YAML, you don't need to provide the file content or override the command at all, all of these details are already embedded in the image.

spec:
  template:
    spec:
      restartPolicy: OnFailure
      containers:
        - name: send-repair-data  # this name does not need to be configurable
          image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
      # the end

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Running nextflow as a job vs. a pod in kubernetes

Timeout a pod/job in kubernetes

Kubernetes a job is moved to another pod

Commands passed to a Kubernetes Job and Pod

Unable to expose SCTP server running in a kubernetes pod using NodePort

Creating Kubernetes Pod per Kubernetes Job and Cleanup

Changing configuration in running Kubernetes Pod

Running bash script in a kubernetes pod

On-demand creation of a container in an existing kubernetes pod

Kubernetes helm - Running helm install in a running pod

Kubernetes difference between activeDeadlineSeconds in Job and Pod

GKE kubernetes delayed_job pod logs

Kubernetes events for pod termination or job completion

Kubernetes job to delete a single pod every minute

How to create a kubernetes job from a pod

Kubernetes job creation method showing as deprecated in IntelliJ. I am using Fabric8 Kubernetes Client api

Using Kubernetes javascript client inside a deployment to create a job

Running a pod/container in Kubernetes that applies maintenance to a DB

How to keep redis database pod running in kubernetes

Running an example pod on Kubernetes with Nvidia GPU nodes

Basic authentication for elasticsearch pod running in kubernetes cluster

Connect pod to Kafka running locally outside Kubernetes

Kubernetes: How to access a label value of the current running pod from code using K8's API?

Using docker socket in Kubernetes pod

kubernetes node fail after pod migration running pod

Is it possible to specify a Docker image build argument at pod creation time in Kubernetes?

How to resolve this issue ErrImageNeverPull pod creation status kubernetes

kubernetes: how to install a package in a pod's container during container creation

Spark job in Kubernetes stuck in RUNNING state

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  3. 3

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  4. 4

    pump.io port in URL

  5. 5

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

  9. 9

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  10. 10

    How to remove the extra space from right in a webview?

  11. 11

    java.lang.NullPointerException: Cannot read the array length because "<local3>" is null

  12. 12

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  13. 13

    flutter: dropdown item programmatically unselect problem

  14. 14

    How to use merge windows unallocated space into Ubuntu using GParted?

  15. 15

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  16. 16

    Nuget add packages gives access denied errors

  17. 17

    Svchost high CPU from Microsoft.BingWeather app errors

  18. 18

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  19. 19

    12.04.3--- Dconf Editor won't show com>canonical>unity option

  20. 20

    Any way to remove trailing whitespace *FOR EDITED* lines in Eclipse [for Java]?

  21. 21

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

HotTag

Archive