3

I have a Kubernetes Job, job.yaml :

---
apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace
---
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
  namespace: my-namespace
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: gcr.io/project-id/my-image:latest
        command: ["sh", "run-vpn-script.sh", "/to/download/this"] # need to run this multiple times
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never

I need to run command for different parameters. I have like 30 parameters to run. I'm not sure what is the best solution here. I'm thinking to create container in a loop to run all parameters. How can I do this? I want to run the commands or containers all simultaneously.

3 Answers 3

2

Some of the ways that you could do it outside of the solutions proposed in other answers are following:


Helm example:

Helm in short is a templating tool that will allow you to template your manifests (YAML files). By that you could have multiple instances of Jobs with different name and a different command.

Assuming that you've installed Helm by following guide:

You can create an example Chart that you will modify to run your Jobs:

  • helm create chart-name

You will need to delete everything that is in the chart-name/templates/ and clear the chart-name/values.yaml file.

After that you can create your values.yaml file which you will iterate upon:

jobs:
  - name: job1
    command: ['"perl",  "-Mbignum=bpi", "-wle", "print bpi(3)"']
    image: perl
  - name: job2
    command: ['"perl",  "-Mbignum=bpi", "-wle", "print bpi(20)"']
    image: perl
  • templates/job.yaml
{{- range $jobs := .Values.jobs }}
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ $jobs.name }}
  namespace: default # <-- FOR EXAMPLE PURPOSES ONLY!
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: {{ $jobs.image }}
        command: {{ $jobs.command }}
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never
---
{{- end }}

If you have above files created you can run following command on what will be applied to the cluster beforehand:

  • $ helm template . (inside the chart-name folder)
---
# Source: chart-name/templates/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: job1
  namespace: default
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(3)"]
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never
---
# Source: chart-name/templates/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: job2
  namespace: default
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(20)"]
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never

A side note #1!

This example will create X amount of Jobs where each one will be separate from the other. Please refer to the documentation on data persistency if the files that are downloaded are needed to be stored persistently (example: GKE).

A side note #2!

You can also add your namespace definition in the templates (templates/namespace.yaml) so it will be created before running your Jobs.

You can also run above Chart by:

  • $ helm install chart-name . (inside the chart-name folder)

After that you should be seeing 2 Jobs that are completed:

  • $ kubectl get pods
NAME         READY   STATUS      RESTARTS   AGE
job1-2dcw5   0/1     Completed   0          82s
job2-9cv9k   0/1     Completed   0          82s

And the output that they've created:

  • $ echo "one:"; kubectl logs job1-2dcw5; echo "two:"; kubectl logs job2-9cv9k
one:
3.14
two:
3.1415926535897932385

Additional resources:

Sign up to request clarification or add additional context in comments.

Comments

2

In simpler terms , you want to run multiple commands , following is a sample format to execute multiple commands in a pod :

command: ["/bin/bash","-c","touch /foo && echo 'here' && ls /"]

When we apply this logic to your requirement for two different operations

 command: ["sh", "-c", "run-vpn-script.sh /to/download/this && run-vpn-script.sh /to/download/another"] 

2 Comments

So means it will run one after another? What if I want to run sh all at the same time?
Infact && makes it run only when previous command is sucessful.if you want to run them oneafter another we need replace && with ;. if you need them to run "parallely"(kind of) then you might need put all those commands in a file with & at the end of each command and pass that file as an argument to "sh"
1

If you want to run the same command multiple times you can deploy the same YAML multiple times by just changing the name.

You can go with the sed command for replacing the values in YAML and apply those YAML to the cluster for creating the container.

Example job.yaml

---
apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace
---
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
  namespace: my-namespace
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: gcr.io/project-id/my-image:latest
        command: COMMAND # need to run this multiple times
        securityContext:
          privileged: true
          allowPrivilegeEscalation: true
      restartPolicy: Never

command :

'job.yaml | sed -i "s,COMMAND,["sh", "run-vpn-script.sh", "/to/download/this"],"

so the above command will replace all the values in YAML and you can apply the YAML to the cluster for creating the container. Same you can apply for other variables.

You can pass the different parameters as per the need in the command that got set in the YAML.

You can also deploy the multiple jobs using the command also

kubectl create job test-job --from=cronjob/a-cronjob

https://www.mankier.com/1/kubectl-create-job

pass other param as per need into the command.

If you don't just want to run the POD you can also try

kubectl run nginx --image=nginx --command -- <cmd> <arg1> ... <argN>

https://jamesdefabia.github.io/docs/user-guide/kubectl/kubectl_run/

3 Comments

should I apply the sed command before or after applying the job.yaml? Sorry, I'm not clear how use this
what sed command will is find the COMMAND in YAML and file and replace it with your command config you want to pass. You can write the sed command which will use the one YAML as base template and give you new updated YAML with value.
Please you can also check this answer : stackoverflow.com/a/48297258/5525824

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.